All files
authorPanagiotis Kanavos <pkanavos@gmail.com>
Wed, 1 Jun 2011 06:45:00 +0000 (09:45 +0300)
committerPanagiotis Kanavos <pkanavos@gmail.com>
Wed, 1 Jun 2011 06:45:00 +0000 (09:45 +0300)
680 files changed:
trunk/.gitignore [new file with mode: 0644]
trunk/Libraries/Json40r2/Documentation.chm [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Doc/ContractResolver.html [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Doc/ConvertingJSONandXML.html [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Doc/CustomCreationConverter.html [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Doc/DatesInJSON.html [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Doc/Introduction.html [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Doc/LINQtoJSON.html [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Doc/PreserveObjectReferences.html [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Doc/ReadingWritingJSON.html [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Doc/ReducingSerializedJSONSize.html [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Doc/SelectToken.html [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Doc/SerializationAttributes.html [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Doc/SerializationCallbacks.html [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Doc/SerializationErrorHandling.html [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Doc/SerializingCollections.html [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Doc/SerializingJSON.html [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Doc/SerializingJSONFragments.html [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Doc/custom.css [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Doc/doc.shfbproj [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Doc/doc.sitemap [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Doc/donate.gif [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Doc/readme.txt [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Doc/styles.css [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Doc/versions.txt [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Lib/LinqBridge.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Lib/NUnit/Compact/NUnitLite.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Lib/NUnit/DotNet/nunit.framework.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Lib/NUnit/DotNet/nunit.framework.xml [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Lib/NUnit/Silverlight/nunit.framework.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Net20.sln [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Net35.sln [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Silverlight.sln [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Bson/BsonReaderTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Bson/BsonWriterTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/BinaryConverterTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/CustomCreationConverterTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/DataSetConverterTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/DataTableConverterTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/ExpandoObjectConverterTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/IsoDateTimeConverterTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/JavaScriptDateTimeConverterTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/ObjectIdConverterTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/RegexConverterTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/StringEnumConverterTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/ExceptionTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/FileSystemEntityModel.Designer.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/FileSystemEntityModel.edmx [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/JsonArrayAttributeTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/JsonConvertTest.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/JsonValidatingReaderTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/ComponentModel/BindingTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/ComponentModel/JPropertyDescriptorTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/DynamicTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JArrayTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JConstructorTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JPathTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JPropertyTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JRawTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JTokenEqualityComparerTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JTokenReaderTest.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JTokenWriterTest.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/LinqToJsonTest.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/LinqToSql/Department.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/LinqToSql/DepartmentConverter.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/LinqToSql/GuidByteArrayConverter.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClasses.dbml [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClasses.dbml.layout [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClasses.designer.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClassesSerializationTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/LinqToSql/Person.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/LinqToSql/Role.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net35.csproj [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.WindowsPhone.csproj [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/PerformanceTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Schema/ExtensionsTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaBuilderTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaGeneratorTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaModelBuilderTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaNodeTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/CamelCasePropertyNamesContractResolverTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/ConstructorHandlingTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/ContractResolverTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/DefaultValueHandlingTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/DynamicTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/EntitiesSerializationTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/MissingMemberHandlingTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/NullValueHandlingTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/PopulateTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/PreserveReferencesHandlingTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/SerializationErrorHandlingTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/SerializationEventAttributeTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/SilverlightTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestFixtureBase.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/AbstractGenericBase.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ArgumentConverterPrecedenceClassConverter.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Article.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ArticleCollection.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/BadJsonPropertyClass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Bar.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Car.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/CircularReferenceClass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/CircularReferenceWithIdClass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ClassAndMemberConverterClass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ClassConverterPrecedenceClassConverter.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ClassWithArray.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ClassWithGuid.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Computer.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ConstructorCaseSensitivityClass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ConstructorReadonlyFields.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Container.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Content.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ContentBaseClass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ContentSubClass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ConverableMembers.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ConverterPrecedenceClass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ConverterPrecedenceClassConverter.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/DateTimeErrorObjectCollection.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/DateTimeTestClass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/DefaultValueAttributeTestClass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/DictionaryInterfaceClass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/DoubleClass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/EmployeeReference.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Event.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Foo.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/GenericImpl.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/GenericListAndDictionaryInterfaceProperties.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/GetOnlyPropertyClass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/GoogleMapGeocoderStructure.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/HolderClass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/IncompatibleJsonAttributeClass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/InterfacePropertyTestClass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Invoice.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/JaggedArray.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/JsonIgnoreAttributeOnClassTestClass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/JsonIgnoreAttributeTestClass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/JsonPropertyClass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/JsonPropertyWithHandlingValues.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ListErrorObject.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ListErrorObjectCollection.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ListOfIds.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ListTestClass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/LogEntry.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/MemberConverterClass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/MemberConverterPrecedenceClassConverter.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/MethodExecutorObject.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Movie.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/MyClass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Name.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/NonRequest.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/NullableDateTimeTestClass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ObjectArrayPropertyTest.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Person.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/PersonError.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/PersonPropertyClass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/PersonRaw.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/PhoneNumber.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/PrivateConstructorTestClass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/PrivateConstructorWithPublicParametizedConstructorTestClass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/PrivateMembersClass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Product.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ProductCollection.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ProductShort.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/PropertyCase.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/RequestOnly.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/RequiredMembersClass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/RoleTransfer.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/SearchResult.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/SerializationEventTestDictionary.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/SerializationEventTestList.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/SerializationEventTestObject.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/SerializationEventTestObjectWithConstructor.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/SetOnlyPropertyClass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/SetOnlyPropertyClass2.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Shortie.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Store.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/StoreColor.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/StructTest.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/SubKlass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/SuperKlass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/TypeClass.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/TypedSubHashtable.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/UserNullable.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/VersionKeyedCollection.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/WagePerson.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Utilities/DynamicReflectionDelegateFactoryTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Utilities/ReflectionUtilsTests.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/bunny_pancake.jpg [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.WindowsPhone.sln [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.sln [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Bson/BsonBinaryType.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Bson/BsonBinaryWriter.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Bson/BsonObjectId.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Bson/BsonReader.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Bson/BsonToken.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Bson/BsonType.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Bson/BsonWriter.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/ConstructorHandling.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/BinaryConverter.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/BsonObjectIdConverter.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/CustomCreationConverter.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/DataSetConverter.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/DataTableConverter.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/DateTimeConverterBase.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/EntityKeyMemberConverter.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/ExpandoObjectConverter.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/IsoDateTimeConverter.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/JavaScriptDateTimeConverter.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/JsonDateTimeSerializationMode.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/KeyValuePairConverter.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/RegexConverter.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/StringEnumConverter.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/DefaultValueHandling.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Dynamic.snk [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/FormatterAssemblyStyle.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/IJsonLineInfo.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonArrayAttribute.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonConstructorAttribute.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonContainerAttribute.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonConvert.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonConverter.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonConverterAttribute.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonConverterCollection.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonIgnoreAttribute.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonObjectAttribute.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonPropertyAttribute.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonReader.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonReaderException.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonSerializationException.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonSerializer.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonSerializerSettings.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonTextReader.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonTextWriter.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonToken.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonValidatingReader.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonWriter.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonWriterException.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/ComponentModel/JPropertyDescriptor.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/Extensions.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/IJEnumerable.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JArray.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JConstructor.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JContainer.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JEnumerable.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JObject.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JPath.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JProperty.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JRaw.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JToken.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JTokenEqualityComparer.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JTokenReader.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JTokenType.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JTokenWriter.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JValue.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/MemberSerialization.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/MissingMemberHandling.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Newtonsoft.Json.Net35.csproj [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Newtonsoft.Json.WindowsPhone.csproj [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Newtonsoft.Json.csproj [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Newtonsoft.Json.ruleset [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/NullValueHandling.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/ObjectCreationHandling.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/PreserveReferencesHandling.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/ReferenceLoopHandling.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Required.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/Extensions.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchema.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaBuilder.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaConstants.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaException.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaGenerator.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaModel.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaModelBuilder.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaNode.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaNodeCollection.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaResolver.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaType.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaWriter.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/UndefinedSchemaIdHandling.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/ValidationEventArgs.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/ValidationEventHandler.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/CachedAttributeGetter.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/CamelCasePropertyNamesContractResolver.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/DefaultReferenceResolver.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/DefaultSerializationBinder.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/DynamicValueProvider.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/ErrorContext.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/ErrorEventArgs.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/IContractResolver.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/IReferenceResolver.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/IValueProvider.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonContract.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonDynamicContract.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonFormatterConverter.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonISerializableContract.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonLinqContract.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonPrimitiveContract.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonProperty.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonPropertyCollection.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalBase.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonSerializerProxy.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonStringContract.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/LateBoundMetadataTypeAttribute.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/ObjectConstructor.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/OnErrorAttribute.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/ReflectionValueProvider.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/SerializationBinder.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/StreamingContext.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/TypeNameHandling.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/Base64Encoder.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/BidirectionalDictionary.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/CollectionUtils.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/CollectionWrapper.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/DateTimeUtils.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/DictionaryWrapper.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/DynamicProxy.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/DynamicProxyMetaObject.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/DynamicReflectionDelegateFactory.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/DynamicUtils.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/DynamicWrapper.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/EnumUtils.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/EnumValue.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/EnumValues.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/ILGeneratorExtensions.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/JavaScriptUtils.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/LateBoundReflectionDelegateFactory.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/ListWrapper.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/MathUtils.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/MethodCall.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/MiscellaneousUtils.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/ReflectionDelegateFactory.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/StringBuffer.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/StringUtils.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/ThreadSafeStore.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/ValidationUtils.cs [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/7-zip/7-zip.chm [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/7-zip/copying.txt [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/7-zip/license.txt [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/7-zip/readme.txt [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/ILMerge/ILMerge License.rtf [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/ILMerge/ILMerge.doc [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/NUnitFitTests.html [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/NUnitTests.config [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/NUnitTests.nunit [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/agent.conf [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/agent.log.conf [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/framework/nunit.framework.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/framework/nunit.framework.xml [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/framework/nunit.mocks.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/framework/pnunit.framework.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/launcher.log.conf [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/Failure.png [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/Ignored.png [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/Inconclusive.png [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/Skipped.png [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/Success.png [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/fit.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/log4net.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit-console-runner.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit-gui-runner.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit.core.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit.core.interfaces.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit.fixtures.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit.uiexception.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit.uikit.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit.util.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/nunit-agent-x86.exe.config [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/nunit-agent.exe.config [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/nunit-console-x86.exe.config [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/nunit-console.exe.config [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/nunit-x86.exe.config [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/nunit.exe.config [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/nunit.framework.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/pnunit-agent.exe.config [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/pnunit-launcher.exe.config [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/pnunit.framework.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/pnunit.tests.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/runFile.exe.config [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/runpnunit.bat [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/test.conf [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/loadtest-assembly.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/mock-assembly.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nonamespace-assembly.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit-console.tests.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit-gui.tests.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.core.tests.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.fixtures.tests.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.framework.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.framework.tests.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.mocks.tests.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.uiexception.tests.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.uikit.tests.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.util.tests.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/test-assembly.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/test-utilities.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/timing-tests.dll [new file with mode: 0644]
trunk/Libraries/Json40r2/Source/Tools/PSake/psake.psm1 [new file with mode: 0644]
trunk/Libraries/Json40r2/readme.txt [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/AbstractStreamBase.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/ActionCountdownEvent.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/AsyncCoordination/AsyncBarrier.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/AsyncCoordination/AsyncCache.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/AsyncCoordination/AsyncCall.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/AsyncCoordination/AsyncProducerConsumerCollection.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/AsyncCoordination/AsyncReaderWriter.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/AsyncCoordination/AsyncSemaphore.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/ConcurrentPriorityQueue.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/ObjectPool.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/ObservableConcurrentCollection.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/ObservableConcurrentDictionary.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/Pipeline.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/ProducerConsumerCollectionBase.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/ReductionVariable.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/SerialTaskQueue.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/SpinLockClass.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/ThreadSafeRandom.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/TransferStream.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Drawing/FastBitmap.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Extensions/APM/FileAsync.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Extensions/APM/StreamExtensions.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Extensions/APM/WebRequestExtensions.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Extensions/AggregateExceptionExtensions.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Extensions/BlockingCollectionExtensions.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Extensions/CancellationTokenExtensions.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Extensions/CompletedTask.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Extensions/DelegateBasedObserver.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Extensions/DelegateExtensions.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Extensions/EAP/EAPCommon.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Extensions/EAP/PingExtensions.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Extensions/EAP/SmtpClientExtensions.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Extensions/EAP/WebClientExtensions.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Extensions/IProducerConsumerCollectionExtensions.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Extensions/LazyExtensions.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Extensions/LinqToTasks.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Extensions/ParallelLinqOptions.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Extensions/ParallelOptionsExtensions.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Extensions/PlinqExtensions.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskCompletionSourceExtensions.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskExtrasExtensions.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskFactoryExtensions/TaskFactoryExtensions_Common.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskFactoryExtensions/TaskFactoryExtensions_ContinueWhenAllAny.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskFactoryExtensions/TaskFactoryExtensions_Create.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskFactoryExtensions/TaskFactoryExtensions_Delayed.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskFactoryExtensions/TaskFactoryExtensions_From.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskFactoryExtensions/TaskFactoryExtensions_FromAsync.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskFactoryExtensions/TaskFactoryExtensions_Iterate.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskFactoryExtensions/TaskFactoryExtensions_TrackedSequence.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskSchedulerExtensions.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_Common.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_Filter.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_For.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_ForRange.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_Map.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_Reduce.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_Scan.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_Sort.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_SpeculativeFor.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_SpeculativeForEach.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_SpeculativeInvoke.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_Wavefront.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_While.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_WhileNotEmpty.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/ParallelExtensionsExtras.csproj [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/ParallelExtensionsExtras.sln [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Partitioners/ChunkPartitioner.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Partitioners/SingleItemPartitioner.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Properties/AssemblyInfo.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/ConcurrentExclusiveInterleave.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/CurrentThreadTaskScheduler.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/IOCompletionPortTaskScheduler.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/IOTaskScheduler.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/LimitedConcurrencyLevelTaskScheduler.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/OrderedTaskScheduler.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/QueuedTaskScheduler.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/ReprioritizableTaskScheduler.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/RoundRobinTaskScheduler.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/StaTaskScheduler.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/SynchronizationContextTaskScheduler.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/ThreadPerTaskkScheduler.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/WorkStealingTaskScheduler.cs [new file with mode: 0644]
trunk/Libraries/ParallelExtensionsExtras/Utils/SortedTopN.cs [new file with mode: 0644]
trunk/Pithos.Client.Test/Pithos.Client.Test.csproj [new file with mode: 0644]
trunk/Pithos.Client.Test/Properties/AssemblyInfo.cs [new file with mode: 0644]
trunk/Pithos.Client/AccountSettings.cs [new file with mode: 0644]
trunk/Pithos.Client/App_Code/LICENSE.txt [new file with mode: 0644]
trunk/Pithos.Client/App_Code/Massive.cs [new file with mode: 0644]
trunk/Pithos.Client/IoC.cs [new file with mode: 0644]
trunk/Pithos.Client/Pithos.Client.csproj [new file with mode: 0644]
trunk/Pithos.Client/PithosFiles.db [new file with mode: 0644]
trunk/Pithos.Client/PithosSettings.cs [new file with mode: 0644]
trunk/Pithos.Client/Preferences.Designer.cs [new file with mode: 0644]
trunk/Pithos.Client/Preferences.cs [new file with mode: 0644]
trunk/Pithos.Client/Preferences.resx [new file with mode: 0644]
trunk/Pithos.Client/Program.cs [new file with mode: 0644]
trunk/Pithos.Client/Properties/AssemblyInfo.cs [new file with mode: 0644]
trunk/Pithos.Client/Properties/Resources.Designer.cs [new file with mode: 0644]
trunk/Pithos.Client/Properties/Resources.resx [new file with mode: 0644]
trunk/Pithos.Client/Properties/Settings.Designer.cs [new file with mode: 0644]
trunk/Pithos.Client/Properties/Settings.settings [new file with mode: 0644]
trunk/Pithos.Client/Resources/Tray.ico [new file with mode: 0644]
trunk/Pithos.Client/Resources/TrayInSynch.ico [new file with mode: 0644]
trunk/Pithos.Client/Resources/TraySynching.ico [new file with mode: 0644]
trunk/Pithos.Client/app.config [new file with mode: 0644]
trunk/Pithos.Client/header.jpg [new file with mode: 0644]
trunk/Pithos.Client/packages.config [new file with mode: 0644]
trunk/Pithos.Core.Test/MockSettings.cs [new file with mode: 0644]
trunk/Pithos.Core.Test/MockStatusKeeper.cs [new file with mode: 0644]
trunk/Pithos.Core.Test/Pithos.Core.Test.csproj [new file with mode: 0644]
trunk/Pithos.Core.Test/PithosWorkflowTest.cs [new file with mode: 0644]
trunk/Pithos.Core.Test/Properties/AssemblyInfo.cs [new file with mode: 0644]
trunk/Pithos.Core.Test/StatusCheckerTest.cs [new file with mode: 0644]
trunk/Pithos.Core.Test/WorkflowFileStatusTest.cs [new file with mode: 0644]
trunk/Pithos.Core/IPithosWorkflow.cs [new file with mode: 0644]
trunk/Pithos.Core/IStatusKeeper.cs [new file with mode: 0644]
trunk/Pithos.Core/NativeMethods.cs [new file with mode: 0644]
trunk/Pithos.Core/Pithos.Core.csproj [new file with mode: 0644]
trunk/Pithos.Core/PithosMonitor.cs [new file with mode: 0644]
trunk/Pithos.Core/PithosWorkflow.cs [new file with mode: 0644]
trunk/Pithos.Core/Properties/AssemblyInfo.cs [new file with mode: 0644]
trunk/Pithos.Core/StatusChecker.cs [new file with mode: 0644]
trunk/Pithos.Core/StatusInfo.cs [new file with mode: 0644]
trunk/Pithos.Core/WorkflowState.cs [new file with mode: 0644]
trunk/Pithos.Interfaces/ICloudClient.cs [new file with mode: 0644]
trunk/Pithos.Interfaces/IPithosSettings.cs [new file with mode: 0644]
trunk/Pithos.Interfaces/IStatusChecker.cs [new file with mode: 0644]
trunk/Pithos.Interfaces/Pithos.Interfaces.csproj [new file with mode: 0644]
trunk/Pithos.Interfaces/Properties/AssemblyInfo.cs [new file with mode: 0644]
trunk/Pithos.Interfaces/pithos.snk [new file with mode: 0644]
trunk/Pithos.Network.Test/ChecksumTest.cs [new file with mode: 0644]
trunk/Pithos.Network.Test/NetworkOpsTest.cs [new file with mode: 0644]
trunk/Pithos.Network.Test/Pithos.Network.Test.csproj [new file with mode: 0644]
trunk/Pithos.Network.Test/Properties/AssemblyInfo.cs [new file with mode: 0644]
trunk/Pithos.Network/CloudFilesClient.cs [new file with mode: 0644]
trunk/Pithos.Network/Pithos.Network.csproj [new file with mode: 0644]
trunk/Pithos.Network/Properties/AssemblyInfo.cs [new file with mode: 0644]
trunk/Pithos.Network/TimeoutRetryCondition.cs [new file with mode: 0644]
trunk/Pithos.Network/packages.config [new file with mode: 0644]
trunk/Pithos.ShellExtensions.Test/FileContextMenuTest.cs [new file with mode: 0644]
trunk/Pithos.ShellExtensions.Test/FileContextTest.cs [new file with mode: 0644]
trunk/Pithos.ShellExtensions.Test/IconOverlayTest.cs [new file with mode: 0644]
trunk/Pithos.ShellExtensions.Test/IoCTest.cs [new file with mode: 0644]
trunk/Pithos.ShellExtensions.Test/Pithos.ShellExtensions.Test.csproj [new file with mode: 0644]
trunk/Pithos.ShellExtensions.Test/Properties/AssemblyInfo.cs [new file with mode: 0644]
trunk/Pithos.ShellExtensions.Test/TestPithosSettings.cs [new file with mode: 0644]
trunk/Pithos.ShellExtensions.Test/TestStatusChecker.cs [new file with mode: 0644]
trunk/Pithos.ShellExtensions/FileContext.cs [new file with mode: 0644]
trunk/Pithos.ShellExtensions/IoC.cs [new file with mode: 0644]
trunk/Pithos.ShellExtensions/MarshalHelpers.cs [new file with mode: 0644]
trunk/Pithos.ShellExtensions/Menus/DisplayFlags.cs [new file with mode: 0644]
trunk/Pithos.ShellExtensions/Menus/FileContextMenu.cs [new file with mode: 0644]
trunk/Pithos.ShellExtensions/Menus/MenuItem.cs [new file with mode: 0644]
trunk/Pithos.ShellExtensions/Overlays/ConflictIconOverlay.cs [new file with mode: 0644]
trunk/Pithos.ShellExtensions/Overlays/IconOverlayBase.cs [new file with mode: 0644]
trunk/Pithos.ShellExtensions/Overlays/ModifiedIconOverlay.cs [new file with mode: 0644]
trunk/Pithos.ShellExtensions/Overlays/NormalIconOverlay.cs [new file with mode: 0644]
trunk/Pithos.ShellExtensions/Overlays/SynchIconOverlay.cs [new file with mode: 0644]
trunk/Pithos.ShellExtensions/Pithos.ShellExtensions.csproj [new file with mode: 0644]
trunk/Pithos.ShellExtensions/ProjectInstaller.cs [new file with mode: 0644]
trunk/Pithos.ShellExtensions/ProjectInstaller.designer.cs [new file with mode: 0644]
trunk/Pithos.ShellExtensions/Properties/AssemblyInfo.cs [new file with mode: 0644]
trunk/Pithos.ShellExtensions/ShellExtLib.cs [new file with mode: 0644]
trunk/Pithos.ShellExtensions/TestPithosSettings.cs [new file with mode: 0644]
trunk/Pithos.ShellExtensions/TestStatusChecker.cs [new file with mode: 0644]
trunk/Pithos.ShellExtensions/app.config [new file with mode: 0644]
trunk/Pithos.ShellExtensions/pithos.snk [new file with mode: 0644]
trunk/Pithos.sln [new file with mode: 0644]
trunk/Pithos.sln.docstates [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/Hammock-Binaries.zip [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/Hammock.1.2.3.nupkg [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/LICENSE [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/net20/Hammock.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/net20/LinqBridge.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/net35-client/Hammock.ClientProfile.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/net35/Hammock.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/net40-client/Hammock.ClientProfile.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/net40/Hammock.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/net40/Hammock.dll.CodeAnalysisLog.xml [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/net40/Hammock.dll.lastcodeanalysissucceeded [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl3/Hammock.Silverlight.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl3/ICSharpCode.SharpZipLib.Silverlight.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl3/System.Runtime.Serialization.Json.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl3/System.Runtime.Serialization.Json.xml [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl3/System.Xml.Linq.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl3/System.Xml.Linq.xml [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl3/de/System.Runtime.Serialization.Json.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl3/de/System.Xml.Linq.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl3/es/System.Runtime.Serialization.Json.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl3/es/System.Xml.Linq.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl3/fr/System.Runtime.Serialization.Json.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl3/fr/System.Xml.Linq.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl3/it/System.Runtime.Serialization.Json.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl3/it/System.Xml.Linq.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl3/ja/System.Runtime.Serialization.Json.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl3/ja/System.Xml.Linq.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl3/ko/System.Runtime.Serialization.Json.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl3/ko/System.Xml.Linq.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl3/zh-Hans/System.Runtime.Serialization.Json.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl3/zh-Hans/System.Xml.Linq.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl3/zh-Hant/System.Runtime.Serialization.Json.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl3/zh-Hant/System.Xml.Linq.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4-wp/Hammock.WindowsPhone.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4-wp/ICSharpCode.SharpZipLib.WindowsPhone.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/Hammock.Silverlight.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/ICSharpCode.SharpZipLib.Silverlight.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/Microsoft.CSharp.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/Microsoft.CSharp.xml [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/System.Json.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/System.Json.xml [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/System.Runtime.Serialization.Json.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/System.Runtime.Serialization.Json.xml [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/System.Xml.Linq.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/System.Xml.Linq.xml [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/de/Microsoft.CSharp.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/de/System.Json.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/de/System.Runtime.Serialization.Json.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/de/System.Xml.Linq.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/es/Microsoft.CSharp.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/es/System.Json.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/es/System.Runtime.Serialization.Json.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/es/System.Xml.Linq.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/fr/Microsoft.CSharp.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/fr/System.Json.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/fr/System.Runtime.Serialization.Json.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/fr/System.Xml.Linq.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/it/Microsoft.CSharp.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/it/System.Json.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/it/System.Runtime.Serialization.Json.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/it/System.Xml.Linq.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/ja/Microsoft.CSharp.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/ja/System.Json.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/ja/System.Runtime.Serialization.Json.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/ja/System.Xml.Linq.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/ko/Microsoft.CSharp.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/ko/System.Json.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/ko/System.Runtime.Serialization.Json.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/ko/System.Xml.Linq.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/ru/Microsoft.CSharp.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/ru/System.Json.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/ru/System.Runtime.Serialization.Json.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/ru/System.Xml.Linq.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hans/Microsoft.CSharp.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hans/System.Json.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hans/System.Runtime.Serialization.Json.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hans/System.Xml.Linq.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hant/Microsoft.CSharp.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hant/System.Json.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hant/System.Runtime.Serialization.Json.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hant/System.Xml.Linq.resources.dll [new file with mode: 0644]
trunk/packages/Hammock.1.2.3/mono/Hammock.Mono.dll [new file with mode: 0644]
trunk/packages/Massive.1.0/Massive.1.0.nupkg [new file with mode: 0644]
trunk/packages/Massive.1.0/content/App_Code/LICENSE.txt [new file with mode: 0644]
trunk/packages/Massive.1.0/content/App_Code/Massive.cs [new file with mode: 0644]
trunk/packages/repositories.config [new file with mode: 0644]
trunk/pithos.snk [new file with mode: 0644]

diff --git a/trunk/.gitignore b/trunk/.gitignore
new file mode 100644 (file)
index 0000000..2b67b7b
--- /dev/null
@@ -0,0 +1,107 @@
+#OS junk files
+[Tt]humbs.db
+*.DS_Store
+
+#Visual Studio files
+*.[Oo]bj
+*.exe
+*.pdb
+*.user
+*.aps
+*.pch
+*.vspscc
+*.vssscc
+*_i.c
+*_p.c
+*.ncb
+*.suo
+*.tlb
+*.tlh
+*.bak
+*.[Cc]ache
+*.ilk
+*.log
+*.lib
+*.sbr
+*.sdf
+ipch/
+obj/
+[Bb]in
+[Dd]ebug*/
+[Rr]elease*/
+Ankh.NoLoad
+
+#Tooling
+_ReSharper*/
+*.resharper
+[Tt]est[Rr]esult*
+
+#Project files
+[Bb]uild/
+
+#Subversion files
+.svn
+
+# Office Temp Files
+~$*
+
+
+
+
+
+
+*.*scc
+*.FileListAbsolute.txt
+*.aps
+*.bak
+*.[Cc]ache
+*.clw
+*.eto
+*.exe
+*.fb6lck
+*.fbl6
+*.fbpInf
+*.ilk
+*.lib
+*.log
+*.ncb
+*.nlb
+*.obj
+*.patch
+*.pch
+*.pdb
+*.plg
+*.[Pp]ublish.xml
+*.rdl.data
+*.sbr
+*.scc
+*.sig
+*.sqlsuo
+*.suo
+*.svclog
+*.tlb
+*.tlh
+*.tli
+*.tmp
+*.user
+*.vshost.*
+*DXCore.Solution
+*_i.c
+*_p.c
+Ankh.Load
+Backup*
+CVS/
+PrecompiledWeb/
+UpgradeLog*.*
+[Bb]in/
+[Dd]ebug/
+[Oo]bj/
+[Rr]elease/
+[Tt]humbs.db
+_UpgradeReport_Files
+_[Rr]e[Ss]harper.*/
+hgignore[.-]*
+ignore[.-]*
+svnignore[.-]*
+lint.db
+*.vs10x
diff --git a/trunk/Libraries/Json40r2/Documentation.chm b/trunk/Libraries/Json40r2/Documentation.chm
new file mode 100644 (file)
index 0000000..289803b
Binary files /dev/null and b/trunk/Libraries/Json40r2/Documentation.chm differ
diff --git a/trunk/Libraries/Json40r2/Source/Doc/ContractResolver.html b/trunk/Libraries/Json40r2/Source/Doc/ContractResolver.html
new file mode 100644 (file)
index 0000000..99ef6de
--- /dev/null
@@ -0,0 +1,92 @@
+<html>
+  
+  <head>
+    <title>Contract Resolver</title>
+    <link href="styles.css" rel="stylesheet" type="text/css" />
+    <link href="custom.css" rel="stylesheet" type="text/css" />
+  </head>
+  
+  <body>
+    
+    <div id="control">
+      <span class="productTitle">Json.NET - Quick Starts & API Documentation</span><br />
+        <span class="topicTitle">Contract Resolvers</span></div>
+
+    <div id="content">
+      <span style="color: DarkGray"> </span>
+    
+
+       <p>The <a href="./html/T_Newtonsoft_Json_Serialization_IContractResolver.htm">IContractResolver</a> interface provides a way to customize how the JsonSerializer serializes and deserializes .NET objects to JSON.</p>
+       <p>Implementing the IContractResolver interface and then assigning an instance to a JsonSerializer lets you control 
+        whether the object is serialized as a JSON object or JSON array, what object members should be serialized, how they are serialized and what they are called.</p>
+       
+       <h4>DefaultContractResolver</h4>
+       <p>The <a href="./html/T_Newtonsoft_Json_Serialization_DefaultContractResolver.htm">DefaultContractResolver</a> is the default resolver used by the serializer. It provides many avenues of extensibility in the form of virtual methods that can be overriden.</p>
+       
+       <h4>CamelCasePropertyNamesContractResolver</h4>
+       <p><a href="./html/T_Newtonsoft_Json_Serialization_CamelCasePropertyNamesContractResolver.htm">CamelCasePropertyNamesContractResolver</a> inherits from DefaultContractResolver and simply overrides the JSON property name to be written in <a href="http://en.wikipedia.org/wiki/CamelCase" target="_blank">camelcase</a>.</p>
+
+ <div class="overflowpanel">   <div class="code">     <div style="font-family: courier new; color: black; font-size: 10pt;">       <pre style="margin: 0px;"><span style="color: rgb(43, 145, 175);">Product</span> product = <span style="color: blue;">new</span> <span style="color: rgb(43, 145, 175);">Product</span></pre>
+
+      <pre style="margin: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</pre>
+
+      <pre style="margin: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ExpiryDate = <span style="color: blue;">new</span> <span style="color: rgb(43, 145, 175);">DateTime</span>(2010, 12, 20, 18, 1, 0, <span style="color: rgb(43, 145, 175);">DateTimeKind</span>.Utc),</pre>
+
+      <pre style="margin: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Name = <span style="color: rgb(163, 21, 21);">"Widget"</span>,</pre>
+
+      <pre style="margin: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Price = 9.99m,</pre>
+
+      <pre style="margin: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sizes = <span style="color: blue;">new</span>[] {<span style="color: rgb(163, 21, 21);">"Small"</span>, <span style="color: rgb(163, 21, 21);">"Medium"</span>, <span style="color: rgb(163, 21, 21);">"Large"</span>}</pre>
+
+      <pre style="margin: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };</pre>
+
+      <pre style="margin: 0px;">&nbsp;</pre>
+
+      <pre style="margin: 0px;"><span style="color: blue;">string</span> json = </pre>
+
+      <pre style="margin: 0px;">&nbsp; <span style="color: rgb(43, 145, 175);">JsonConvert</span>.SerializeObject(</pre>
+
+      <pre style="margin: 0px;">&nbsp;&nbsp;&nbsp; product,</pre>
+
+      <pre style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: rgb(43, 145, 175);">Formatting</span>.Indented,</pre>
+
+      <pre style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">new</span> <span style="color: rgb(43, 145, 175);">JsonSerializerSettings</span> { ContractResolver = <span style="color: blue;">new</span> <span style="color: rgb(43, 145, 175);">CamelCasePropertyNamesContractResolver</span>() }</pre>
+
+      <pre style="margin: 0px;">&nbsp; );</pre>
+
+      <pre style="margin: 0px;">&nbsp;</pre>
+
+      <pre style="margin: 0px;"><span style="color: green;">//{</span></pre>
+
+      <pre style="margin: 0px;"><span style="color: green;">//&nbsp; "name": "Widget",</span></pre>
+
+      <pre style="margin: 0px;"><span style="color: green;">//&nbsp; "expiryDate": "\/Date(1292868060000)\/",</span></pre>
+
+      <pre style="margin: 0px;"><span style="color: green;">//&nbsp; "price": 9.99,</span></pre>
+
+      <pre style="margin: 0px;"><span style="color: green;">//&nbsp; "sizes": [</span></pre>
+
+      <pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp;&nbsp; "Small",</span></pre>
+
+      <pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp;&nbsp; "Medium",</span></pre>
+
+      <pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp;&nbsp; "Large"</span></pre>
+
+      <pre style="margin: 0px;"><span style="color: green;">//&nbsp; ]</span></pre>
+
+      <pre style="margin: 0px;"><span style="color: green;">//}</span></pre>
+    </div>
+  </div>
+</div>
+
+
+      <div id="footer">
+
+
+    
+        </div>      
+    </div>
+
+  </body>
+
+</html>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Doc/ConvertingJSONandXML.html b/trunk/Libraries/Json40r2/Source/Doc/ConvertingJSONandXML.html
new file mode 100644 (file)
index 0000000..38cedfa
--- /dev/null
@@ -0,0 +1,146 @@
+<html>
+  
+  <head>
+    <title>Converting between JSON and XML</title>
+    <link href="styles.css" rel="stylesheet" type="text/css" />
+    <link href="custom.css" rel="stylesheet" type="text/css" />
+  </head>
+  
+  <body>
+    
+    <div id="control">
+      <span class="productTitle">Json.NET - Quick Starts & API Documentation</span><br />
+        <span class="topicTitle">Converting between JSON and XML</span></div>
+
+    <div id="content">
+      <span style="color: DarkGray"> </span>
+        <p>Json.NET supports converting JSON to XML and vice versa using the 
+            <a href="./html/T_Newtonsoft_Json_Converters_XmlNodeConverter.htm">XmlNodeConverter</a>.</p>
+
+        <p>
+            Elements, attributes, text, comments, character data, processing instructions, 
+            namespaces and the XML declaration are all preserved when converting between the 
+            two. The only caveat is that it is possible to lose the order of differently 
+            named nodes at the same level when they are grouped together into an array.</p>
+        <h3>Conversion Rules</h3>
+        <ul>
+            <li>Elements remain unchanged. </li>
+            <li>Attributes are prefixed with an @. </li>
+            <li>Single child text nodes are a value directly against an element, otherwise they 
+                are accessed via #text. </li>
+            <li>The XML declaration and processing instructions are prefixed with ?. </li>
+            <li>Charater data, comments, whitespace and significate whitespace nodes are 
+                accessed via #cdata-section,&nbsp;#comment, #whitespace and #significate-whitespace 
+                respectively. </li>
+            <li>Multiple nodes with the same name at the same level are grouped together into an 
+                array. </li>
+            <li>Empty elements are null.</li>
+        </ul>
+
+<h3>SerializeXmlNode</h3>
+<p>The JsonConvert has two helper methods for converting between JSON and XML. The first is <a href="./html/M_Newtonsoft_Json_JsonConvert_SerializeXmlNode.htm">SerializeXmlNode</a>. This method takes an
+XmlNode and serializes it to JSON text.</p>
+<div class="overflowpanel">
+  <div class="code">
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: blue;">string</span> xml = <span style="color: #a31515;">@&quot;&lt;?xml version=&quot;&quot;1.0&quot;&quot; standalone=&quot;&quot;no&quot;&quot;?&gt;</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&lt;root&gt;</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &lt;person id=&quot;&quot;1&quot;&quot;&gt;</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &lt;name&gt;Alan&lt;/name&gt;</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &lt;url&gt;http://www.google.com&lt;/url&gt;</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &lt;/person&gt;</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &lt;person id=&quot;&quot;2&quot;&quot;&gt;</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &lt;name&gt;Louis&lt;/name&gt;</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &lt;url&gt;http://www.yahoo.com&lt;/url&gt;</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &lt;/person&gt;</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&lt;/root&gt;&quot;</span>;</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">XmlDocument</span> doc = <span style="color: blue;">new</span> <span style="color: #2b91af;">XmlDocument</span>();</pre>
+<pre style="margin: 0px;">doc.LoadXml(xml);</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: blue;">string</span> jsonText = <span style="color: #2b91af;">JsonConvert</span>.SerializeXmlNode(doc);</pre>
+<pre style="margin: 0px;"><span style="color: green;">//{</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &quot;?xml&quot;: {</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; &quot;@version&quot;: &quot;1.0&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; &quot;@standalone&quot;: &quot;no&quot;</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; },</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &quot;root&quot;: {</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; &quot;person&quot;: [</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; &nbsp; {</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; &nbsp; &nbsp; &quot;@id&quot;: &quot;1&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; &nbsp; &nbsp; &quot;name&quot;: &quot;Alan&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; &nbsp; &nbsp; &quot;url&quot;: &quot;http://www.google.com&quot;</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; &nbsp; },</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; &nbsp; {</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; &nbsp; &nbsp; &quot;@id&quot;: &quot;2&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; &nbsp; &nbsp; &quot;name&quot;: &quot;Louis&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; &nbsp; &nbsp; &quot;url&quot;: &quot;http://www.yahoo.com&quot;</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; &nbsp; }</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; ]</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; }</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//}</span></pre>
+</div>
+
+</div>
+  </div>
+
+<h3>DeserializeXmlNode</h3>
+
+<p>The second helper method on JsonConvert is <a href="./html/M_Newtonsoft_Json_JsonConvert_DeserializeXmlNode.htm">DeserializeXmlNode</a>. This method takes 
+    JSON text and deserializes it into a XmlNode.</p>
+        <p>Because valid XML must have one root element the JSON passed to 
+            DeserializeXmlNode should have one property in the root JSON object. If the root 
+            JSON object has multiple properties then the overload that also takes an element 
+            name should be used. A root element with that name will be inserted into the 
+            deserialized XmlNode.</p>
+
+<div class="overflowpanel">
+
+  <div class="code">
+
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: blue;">string</span> json = <span style="color: #a31515;">@&quot;{</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &quot;&quot;?xml&quot;&quot;: {</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &quot;&quot;@version&quot;&quot;: &quot;&quot;1.0&quot;&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &quot;&quot;@standalone&quot;&quot;: &quot;&quot;no&quot;&quot;</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; },</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &quot;&quot;root&quot;&quot;: {</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &quot;&quot;person&quot;&quot;: [</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; {</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;@id&quot;&quot;: &quot;&quot;1&quot;&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;name&quot;&quot;: &quot;&quot;Alan&quot;&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;url&quot;&quot;: &quot;&quot;http://www.google.com&quot;&quot;</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; },</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; {</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;@id&quot;&quot;: &quot;&quot;2&quot;&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;name&quot;&quot;: &quot;&quot;Louis&quot;&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;url&quot;&quot;: &quot;&quot;http://www.yahoo.com&quot;&quot;</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; }</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; ]</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; }</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">}&quot;</span>;</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">XmlDocument</span> doc = (<span style="color: #2b91af;">XmlDocument</span>)<span style="color: #2b91af;">JsonConvert</span>.DeserializeXmlNode(json);</pre>
+<pre style="margin: 0px;"><span style="color: green;">// &lt;?xml version=&quot;1.0&quot; standalone=&quot;no&quot;?&gt;</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">// &lt;root&gt;</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp; &lt;person id=&quot;1&quot;&gt;</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp; &lt;name&gt;Alan&lt;/name&gt;</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp; &lt;url&gt;http://www.google.com&lt;/url&gt;</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp; &lt;/person&gt;</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp; &lt;person id=&quot;2&quot;&gt;</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp; &lt;name&gt;Louis&lt;/name&gt;</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp; &lt;url&gt;http://www.yahoo.com&lt;/url&gt;</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp; &lt;/person&gt;</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">// &lt;/root&gt;</span></pre>
+</div>
+
+
+  </div>
+</div>
+
+      <div id="footer"></div>      
+    </div>
+
+  </body>
+
+</html>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Doc/CustomCreationConverter.html b/trunk/Libraries/Json40r2/Source/Doc/CustomCreationConverter.html
new file mode 100644 (file)
index 0000000..edc403b
--- /dev/null
@@ -0,0 +1,99 @@
+<html>
+  
+  <head>
+    <title>CustomCreationConverter</title>
+    <link href="styles.css" rel="stylesheet" type="text/css" />
+    <link href="custom.css" rel="stylesheet" type="text/css" />
+  </head>
+  
+  <body>
+    
+    <div id="control">
+      <span class="productTitle">Json.NET - Quick Starts & API Documentation</span><br />
+        <span class="topicTitle">CustomCreationConverter</span></div>
+
+    <div id="content">
+      <span style="color: DarkGray"> </span>
+    
+       <p>
+       The CustomCreationConverter is a JsonConverter that provides a way to customize how an object is created 
+        during JSON deserialization.
+       Once the object has been created it will then have values populated onto it by the serializer.
+       </p>
+
+<div class="overflowpanel"> <div class="code">
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: blue;">public</span> <span style="color: blue;">interface</span> <span style="color: #2b91af;">IPerson</span></pre>
+<pre style="margin: 0px;">{</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">string</span> FirstName { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">string</span> LastName { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: #2b91af;">DateTime</span> BirthDate { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">}</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">Employee</span> : <span style="color: #2b91af;">IPerson</span></pre>
+<pre style="margin: 0px;">{</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> FirstName { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> LastName { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: #2b91af;">DateTime</span> BirthDate { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> Department { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> JobTitle { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">}</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">PersonConverter</span> : <span style="color: #2b91af;">CustomCreationConverter</span>&lt;<span style="color: #2b91af;">IPerson</span>&gt;</pre>
+<pre style="margin: 0px;">{</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">override</span> <span style="color: #2b91af;">IPerson</span> Create(<span style="color: #2b91af;">Type</span> objectType)</pre>
+<pre style="margin: 0px;">&nbsp; {</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; <span style="color: blue;">return</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">Employee</span>();</pre>
+<pre style="margin: 0px;">&nbsp; }</pre>
+<pre style="margin: 0px;">}</pre>
+</div>
+</div></div>
+
+<p>
+This is an extremely simple example. A more complicated scenario could involve an object factory or service locator 
+    which resolves the object at runtime.
+</p>
+
+<div class="overflowpanel"> <div class="code">
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: green;">//[</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; {</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "FirstName": "Maurice",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "LastName": "Moss",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "BirthDate": "\/Date(252291661000)\/",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "Department": "IT",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "JobTitle": "Support"</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; },</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; {</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "FirstName": "Jen",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "LastName": "Barber",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "BirthDate": "\/Date(258771661000)\/",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "Department": "IT",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "JobTitle": "Manager"</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; }</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//]</span></pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">List</span>&lt;<span style="color: #2b91af;">IPerson</span>&gt; people = <span style="color: #2b91af;">JsonConvert</span>.DeserializeObject&lt;<span style="color: #2b91af;">List</span>&lt;<span style="color: #2b91af;">IPerson</span>&gt;&gt;(json, <span style="color: blue;">new</span> <span style="color: #2b91af;">PersonConverter</span>());</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">IPerson</span> person = people[0];</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(person.GetType());</pre>
+<pre style="margin: 0px;"><span style="color: green;">// Newtonsoft.Json.Tests.Employee</span></pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(person.FirstName);</pre>
+<pre style="margin: 0px;"><span style="color: green;">// Maurice</span></pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Employee</span> employee = (<span style="color: #2b91af;">Employee</span>)person;</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(employee.JobTitle);</pre>
+<pre style="margin: 0px;"><span style="color: green;">// Support</span></pre>
+</div>
+</div></div>
+
+      <div id="footer"></div>      
+    </div>
+
+  </body>
+
+</html>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Doc/DatesInJSON.html b/trunk/Libraries/Json40r2/Source/Doc/DatesInJSON.html
new file mode 100644 (file)
index 0000000..e59af91
--- /dev/null
@@ -0,0 +1,94 @@
+<html>
+  
+  <head>
+    <title>Serializing Dates in JSON</title>
+    <link href="styles.css" rel="stylesheet" type="text/css" />
+    <link href="custom.css" rel="stylesheet" type="text/css" />
+  </head>
+  
+  <body>
+    
+    <div id="control">
+      <span class="productTitle">Json.NET - Quick Starts & API Documentation</span><br />
+        <span class="topicTitle">Serializing Dates in JSON</span></div>
+
+    <div id="content">
+      <span style="color: DarkGray"> </span>
+        <p>DateTimes in JSON are hard.</p>
+        <p>
+            The problem comes from the <a href="http://www.ietf.org/rfc/rfc4627.txt" target="_blank">JSON spec</a> itself, there is no literal syntax for dates in JSON. The spec has objects, arrays, strings, integers and floats, but it defines no standard for what a date looks like.</p>
+<p>The default format used by <a href="http://james.newtonking.com/projects/json-net.aspx" target="_blank">Json.NET</a> for dates is the same one used by Microsoft: "\/Date(1198908717056)\/". You can read more about it <a href="http://weblogs.asp.net/bleroy/archive/2008/01/18/dates-and-json.aspx" target="_blank">here</a>.</p>
+
+<h3>DateTime JsonConverters</h3>
+<p>With no standard for dates in JSON, the number of possible different formats when interoping with other systems is endless. Fortunately Json.NET has a solution to deal with reading and writing custom dates: JsonConverters. A JsonConverter is used to override how a type is serialized.</p>
+
+<div class="overflowpanel">
+<div class="code">
+<div style="font-size: 10pt; color: black; font-family: courier new;">
+<pre style="margin: 0px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: rgb(43, 145, 175);">LogEntry</span></pre>
+<pre style="margin: 0px;">{</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> Details { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: rgb(43, 145, 175);">DateTime</span> LogDate { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">}</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;">[<span style="color: rgb(43, 145, 175);">Test</span>]</pre>
+
+<pre style="margin: 0px;"><span style="color: blue;">public</span> <span style="color: blue;">void</span> WriteJsonDates()</pre>
+<pre style="margin: 0px;">{</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: rgb(43, 145, 175);">LogEntry</span> entry = <span style="color: blue;">new</span> <span style="color: rgb(43, 145, 175);">LogEntry</span></pre>
+<pre style="margin: 0px;">&nbsp; {</pre>
+
+<pre style="margin: 0px;">&nbsp;&nbsp;&nbsp; LogDate = <span style="color: blue;">new</span> <span style="color: rgb(43, 145, 175);">DateTime</span>(2009, 2, 15, 0, 0, 0, <span style="color: rgb(43, 145, 175);">DateTimeKind</span>.Utc),</pre>
+<pre style="margin: 0px;">&nbsp;&nbsp;&nbsp; Details = <span style="color: rgb(163, 21, 21);">"Application started."</span></pre>
+<pre style="margin: 0px;">&nbsp; };</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">string</span> defaultJson = <span style="color: rgb(43, 145, 175);">JsonConvert</span>.SerializeObject(entry);</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: green;">// {"Details":"Application started.","LogDate":"\/Date(1234656000000)\/"}</span></pre>
+<pre style="margin: 0px;"></pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">string</span> javascriptJson = <span style="color: rgb(43, 145, 175);">JsonConvert</span>.SerializeObject(entry, <span style="color: blue;">new</span> <span style="color: rgb(43, 145, 175);">JavaScriptDateTimeConverter</span>());</pre>
+
+<pre style="margin: 0px;">&nbsp; <span style="color: green;">// {"Details":"Application started.","LogDate":new Date(1234656000000)}</span></pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">string</span> isoJson = <span style="color: rgb(43, 145, 175);">JsonConvert</span>.SerializeObject(entry, <span style="color: blue;">new</span> <span style="color: rgb(43, 145, 175);">IsoDateTimeConverter</span>());</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: green;">// {"Details":"Application started.","LogDate":"2009-02-15T00:00:00Z"}</span></pre>
+
+<pre style="margin: 0px;">}</pre>
+</div>
+</div>
+</div>
+<p>Simply pass the JsonConverter you wish to use to the Json.NET serializer.</p>
+<h4>JavaScriptDateTimeConverter</h4>
+<p>The JavaScriptDateTimeConverter class is one of the two DateTime JsonConverters that come with Json.NET. This converter serializes a DateTime as a <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Date" target="_blank">JavaScript Date object</a>.</p>
+<div class="overflowpanel">
+<div class="code">
+<div style="font-size: 10pt; color: black; font-family: courier new;">
+<pre style="margin: 0px;">new Date(1234656000000)</pre>
+
+</div>
+</div>
+</div>
+<p>Technically this is invalid JSON according to the spec but all browsers, and some JSON frameworks including Json.NET, support it. </p>
+<h4>IsoDateTimeConverter</h4>
+<p>IsoDateTimeConverter seralizes a DateTime to an <a href="http://en.wikipedia.org/wiki/ISO_8601" target="_blank">ISO 8601</a> formatted string.</p>
+<div class="overflowpanel">
+<div class="code">
+<div style="font-size: 10pt; color: black; font-family: courier new;">
+<pre style="margin: 0px;"><span style="color: rgb(163, 21, 21);">"2009-02-15T00:00:00Z"</span></pre>
+
+</div>
+</div>
+</div>
+<p>The IsoDateTimeConverter class has a property, DateTimeFormat, to further customize the formatted string.</p>
+<p>&nbsp;</p>
+<p>One final thing to note is all date values returned by Json.NET are in <a href="http://en.wikipedia.org/wiki/Utc" target="_blank">UTC time</a>.</p>
+
+
+      <div id="footer"></div>      
+    </div>
+
+  </body>
+
+</html>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Doc/Introduction.html b/trunk/Libraries/Json40r2/Source/Doc/Introduction.html
new file mode 100644 (file)
index 0000000..0282159
--- /dev/null
@@ -0,0 +1,68 @@
+<html>
+<head>
+    <title>Introduction</title>
+    <link href="styles.css" rel="stylesheet" type="text/css" />
+    <link href="custom.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+    <div id="control">
+        <span class="productTitle">Json.NET - Quick Starts & API Documentation</span><br />
+        <span class="topicTitle">Introduction</span></div>
+    <div id="content">
+        <span style="color: DarkGray"></span>
+        <p>
+            Json.NET makes working with JSON formatted data in .NET
+            simple. Quickly read and write JSON using LINQ to JSON or serialize
+            your .NET objects with a single method call using the JsonSerializer.</p>
+        <h3>
+            Features</h3>
+        <ul>
+            <li>Flexible JSON serializer to convert .NET objects to JSON and back again</li>
+            <li>LINQ to JSON for reading and writing JSON</li>
+            <li>Writes indented, easy to read JSON</li>
+            <li>Convert JSON to and from XML</li>
+            <li>Supports Silverlight and the Compact Framework</li>
+        </ul>
+        <p>The JSON serializer is a good choice when the JSON you are reading or writing maps closely
+        to a .NET class. The serializer automatically reads and writes JSON for the class.</p>
+        <p class="MsoNormal">
+            For situations where you are only interested in getting values from JSON, don&#39;t 
+            have a class to serialize or deserialize to, or the JSON is radically different 
+            from your class and you need to manually read and write from your objects then 
+            LINQ to JSON is what you should use. LINQ to JSON allows you to easily read, 
+            create and modify JSON in .NET.</p>
+        <h3>
+            History</h3>
+        <p>
+            Json.NET grew out of projects I was working on in late 2005 involving JavaScript,
+            AJAX and .NET. At the time there were no libraries for working with JavaScript in
+            .NET so I began to grow my own.</p>
+        <p>
+            Starting out as a couple of static methods for escaping JavaScript strings, Json.NET
+            evolved as features were added. To add support for reading JSON a major refactor
+            was required and Json.NET will split into the three major classes it still uses
+            today, JsonReader, JsonWriter and JsonSerializer.
+        </p>
+        <p>
+            Json.NET was first released in June 2006. Since then Json.NET has been downloaded
+            thousands of times by developers and is used in a number of major projects open
+            source projects including <a href="http://www.castleproject.org/monorail/index.html" target="_blank">MonoRail</a>,
+            Castle Project's MVC web framework, and <a href="http://www.mono-project.com/" target="_blank">Mono</a>,
+            an open source implementation
+            of the .NET framework.</p>
+        <p>
+            <i>~ James Newton-King</i></p>
+        <h3>
+            Donate</h3>
+        <p>
+            Json.NET is a free open source project that I have developed in my personal time.</p>
+            <p>
+            I really appreciate your feedback and support for Json.NET and its future development.</p>
+        <p><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=james%40newtonking%2ecom&item_name=Supporting%20Json%2eNET&no_shipping=0&no_note=1&tax=0&currency_code=USD&lc=US&bn=PP%2dDonationsBF&charset=UTF%2d8" target="_blank">
+            <img src="donate.gif" alt="Donate" style="border-width:0;" />
+            </a></p>
+        <div id="footer">
+        </div>
+    </div>
+</body>
+</html>
diff --git a/trunk/Libraries/Json40r2/Source/Doc/LINQtoJSON.html b/trunk/Libraries/Json40r2/Source/Doc/LINQtoJSON.html
new file mode 100644 (file)
index 0000000..c80d3b7
--- /dev/null
@@ -0,0 +1,254 @@
+<html>
+  
+  <head>
+    <title>LINQ to JSON</title>
+    <link href="styles.css" rel="stylesheet" type="text/css" />
+    <link href="custom.css" rel="stylesheet" type="text/css" />
+  </head>
+  
+  <body>
+    
+    <div id="control">
+      <span class="productTitle">Json.NET - Quick Starts & API Documentation</span><br />
+        <span class="topicTitle">LINQ to JSON</span></div>
+
+    <div id="content">
+      <span style="color: DarkGray"> </span>
+    
+       <p>LINQ to JSON is a programming API for working with JSON objects. The API has been designed with LINQ in mind to enable to quick querying and creation of JSON objects. LINQ to JSON sits under the <a href="./html/N_Newtonsoft_Json_Linq.htm">Newtonsoft.Json.Linq</a> namespace.</p>
+
+<h3>Creating JSON</h3>
+<p>There are a number of different options when it comes to creating JSON using LINQ to JSON. The first to create objects imperatively. You have total control but it is more verbose than other options.</p>
+
+<div class="overflowpanel"> <div class="code">
+
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: #2b91af;">JArray</span> array = <span style="color: blue;">new</span> <span style="color: #2b91af;">JArray</span>();</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">JValue</span> text = <span style="color: blue;">new</span> <span style="color: #2b91af;">JValue</span>(<span style="color: #a31515;">"Manual text"</span>);</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">JValue</span> date = <span style="color: blue;">new</span> <span style="color: #2b91af;">JValue</span>(<span style="color: blue;">new</span> <span style="color: #2b91af;">DateTime</span>(2000, 5, 23));</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;">array.Add(text);</pre>
+<pre style="margin: 0px;">array.Add(date);</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: blue;">string</span> json = array.ToString();</pre>
+<pre style="margin: 0px;"><span style="color: green;">// [</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp;  "Manual text",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp;  "\/Date(958996800000+1200)\/"</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">// ]</span></pre>
+</div>
+
+</div></div>
+
+<p>Another option is to create JSON objects declaratively.</p>
+
+
+<div class="overflowpanel"> <div class="code">
+
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: #2b91af;">List</span>&lt;<span style="color: #2b91af;">Post</span>&gt; posts = GetPosts();</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">JObject</span> rss =</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">new</span> <span style="color: #2b91af;">JObject</span>(</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; <span style="color: blue;">new</span> <span style="color: #2b91af;">JProperty</span>(<span style="color: #a31515;">"channel"</span>,</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; <span style="color: blue;">new</span> <span style="color: #2b91af;">JObject</span>(</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: blue;">new</span> <span style="color: #2b91af;">JProperty</span>(<span style="color: #a31515;">"title"</span>, <span style="color: #a31515;">"James Newton-King"</span>),</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: blue;">new</span> <span style="color: #2b91af;">JProperty</span>(<span style="color: #a31515;">"link"</span>, <span style="color: #a31515;">"http://james.newtonking.com"</span>),</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: blue;">new</span> <span style="color: #2b91af;">JProperty</span>(<span style="color: #a31515;">"description"</span>, <span style="color: #a31515;">"James Newton-King's blog."</span>),</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: blue;">new</span> <span style="color: #2b91af;">JProperty</span>(<span style="color: #a31515;">"item"</span>,</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: blue;">new</span> <span style="color: #2b91af;">JArray</span>(</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: blue;">from</span> p <span style="color: blue;">in</span> posts</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: blue;">orderby</span> p.Title</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: blue;">select</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">JObject</span>(</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: blue;">new</span> <span style="color: #2b91af;">JProperty</span>(<span style="color: #a31515;">"title"</span>, p.Title),</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: blue;">new</span> <span style="color: #2b91af;">JProperty</span>(<span style="color: #a31515;">"description"</span>, p.Description),</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: blue;">new</span> <span style="color: #2b91af;">JProperty</span>(<span style="color: #a31515;">"link"</span>, p.Link),</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: blue;">new</span> <span style="color: #2b91af;">JProperty</span>(<span style="color: #a31515;">"category"</span>,</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: blue;">new</span> <span style="color: #2b91af;">JArray</span>(</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: blue;">from</span> c <span style="color: blue;">in</span> p.Categories</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: blue;">select</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">JValue</span>(c)))))))));</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(rss.ToString());</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: green;">//{</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; "channel": {</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "title": "James Newton-King",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "link": "http://james.newtonking.com",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "description": "James Newton-King's blog.",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "item": [</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; &nbsp; {</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; &nbsp; &nbsp; "title": "Json.NET 1.3 + New license + Now on CodePlex",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; &nbsp; &nbsp; "description": "Annoucing the release of Json.NET 1.3, the MIT license and the source being available on CodePlex",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; &nbsp; &nbsp; "link": "http://james.newtonking.com/projects/json-net.aspx",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; &nbsp; &nbsp; "category": [</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "Json.NET",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "CodePlex"</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; &nbsp; &nbsp; ]</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; &nbsp; },</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; &nbsp; {</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; &nbsp; &nbsp; "title": "LINQ to JSON beta",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; &nbsp; &nbsp; "description": "Annoucing LINQ to JSON",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; &nbsp; &nbsp; "link": "http://james.newtonking.com/projects/json-net.aspx",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; &nbsp; &nbsp; "category": [</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "Json.NET",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "LINQ"</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; &nbsp; &nbsp; ]</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; &nbsp; }</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; ]</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; }</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//}</span></pre>
+</div>
+
+</div></div>
+
+<p>You can create a JSON object from a non-JSON type using the <a href="./html/M_Newtonsoft_Json_Linq_JObject_FromObject.htm">FromObject</a> method.</p>
+
+<div class="overflowpanel"> <div class="code">
+
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: #2b91af;">JObject</span> o = <span style="color: #2b91af;">JObject</span>.FromObject(<span style="color: blue;">new</span></pre>
+<pre style="margin: 0px;">{</pre>
+<pre style="margin: 0px;">&nbsp; channel = <span style="color: blue;">new</span></pre>
+<pre style="margin: 0px;">&nbsp; {</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; title = <span style="color: #a31515;">"James Newton-King"</span>,</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; link = <span style="color: #a31515;">"http://james.newtonking.com"</span>,</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; description = <span style="color: #a31515;">"James Newton-King's blog."</span>,</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; item =</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: blue;">from</span> p <span style="color: blue;">in</span> posts</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: blue;">orderby</span> p.Title</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: blue;">select</span> <span style="color: blue;">new</span></pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; {</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; title = p.Title,</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; description = p.Description,</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; link = p.Link,</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; category = p.Categories</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; }</pre>
+<pre style="margin: 0px;">&nbsp; }</pre>
+<pre style="margin: 0px;">});</pre>
+</div>
+
+</div></div>
+
+<p>Finally JSON objects can be created from a string use the <a href="./html/M_Newtonsoft_Json_Linq_JObject_Parse.htm">Parse</a> method.</p>
+
+<div class="overflowpanel"> <div class="code">
+
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: blue;">string</span> json = <span style="color: #a31515;">@"{</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; CPU: 'Intel',</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; Drives: [</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; 'DVD read/writer',</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; ""500 gigabyte hard drive""</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; ]</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">}"</span>;</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">JObject</span> o = <span style="color: #2b91af;">JObject</span>.Parse(json);</pre>
+</div>
+
+</div></div>
+
+       <h3>Querying JSON</h3>
+
+
+       <p>The properties methods that are the most useful when querying JSON objects are 
+        the <a href="./html/Overload_Newtonsoft_Json_Linq_JToken_Children.htm">Children</a> 
+        method and the <a href="./html/P_Newtonsoft_Json_Linq_JToken_Item.htm">property index</a>.</p>
+       <p>Children returns all the children of that object. If it is a JObject it will 
+        return a collection of properties to work with and if it is a JArray you will 
+        get a collection of the array&#39;s values.</p>
+        <p>The property index is used to get a specific child, either by index position for JSON arrays or property name for JSON objects.</p>
+
+<div class="overflowpanel"> <div class="code">
+
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: blue;">var</span> postTitles =</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">from</span> p <span style="color: blue;">in</span> rss[<span style="color: #a31515;">"channel"</span>][<span style="color: #a31515;">"item"</span>].Children()</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">select</span> (<span style="color: blue;">string</span>)p[<span style="color: #a31515;">"title"</span>];</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: blue;">foreach</span> (<span style="color: blue;">var</span> item <span style="color: blue;">in</span> postTitles)</pre>
+<pre style="margin: 0px;">{</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: #2b91af;">Console</span>.WriteLine(item);</pre>
+<pre style="margin: 0px;">}</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: green;">//LINQ to JSON beta</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//Json.NET 1.3 + New license + Now on CodePlex</span></pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: blue;">var</span> categories =</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">from</span> c <span style="color: blue;">in</span> rss[<span style="color: #a31515;">"channel"</span>][<span style="color: #a31515;">"item"</span>].Children()[<span style="color: #a31515;">"category"</span>].Values&lt;<span style="color: blue;">string</span>&gt;()</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">group</span> c <span style="color: blue;">by</span> c <span style="color: blue;">into</span> g</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">orderby</span> g.Count() <span style="color: blue;">descending</span></pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">select</span> <span style="color: blue;">new</span> { Category = g.Key, Count = g.Count() };</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: blue;">foreach</span> (<span style="color: blue;">var</span> c <span style="color: blue;">in</span> categories)</pre>
+<pre style="margin: 0px;">{</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: #2b91af;">Console</span>.WriteLine(c.Category + <span style="color: #a31515;">" - Count: "</span> + c.Count);</pre>
+<pre style="margin: 0px;">}</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: green;">//Json.NET - Count: 2</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//LINQ - Count: 1</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//CodePlex - Count: 1</span></pre>
+</div>
+
+</div></div>
+
+<p>LINQ to JSON can also be used to manually convert from JSON to a .NET object.</p>
+
+<div class="overflowpanel"> <div class="code">
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">Shortie</span></pre>
+<pre style="margin: 0px;">{</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> Original { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> Shortened { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> Short { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: #2b91af;">ShortieException</span> Error { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">}</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">ShortieException</span></pre>
+<pre style="margin: 0px;">{</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">int</span> Code { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> ErrorMessage { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">}</pre>
+</div>
+</div></div>
+
+<p>Manually serializing and deserializing between .NET objects is most useful when working with JSON that doesn't closely match your .NET objects.</p>
+
+<div class="overflowpanel"> <div class="code">
+
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: blue;">string</span> jsonText = <span style="color: #a31515;">@"{</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; ""short"":{</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; ""original"":""http://www.foo.com/"",</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; ""short"":""krehqk"",</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; ""error"":{</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; ""code"":0,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; ""msg"":""No action taken""}</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">}"</span>;</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">JObject</span> json = <span style="color: #2b91af;">JObject</span>.Parse(jsonText);</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Shortie</span> shortie = <span style="color: blue;">new</span> <span style="color: #2b91af;">Shortie</span></pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Original = (<span style="color: blue;">string</span>)json[<span style="color: #a31515;">"short"</span>][<span style="color: #a31515;">"original"</span>],</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Short = (<span style="color: blue;">string</span>)json[<span style="color: #a31515;">"short"</span>][<span style="color: #a31515;">"short"</span>],</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Error = <span style="color: blue;">new</span> <span style="color: #2b91af;">ShortieException</span></pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Code = (<span style="color: blue;">int</span>)json[<span style="color: #a31515;">"short"</span>][<span style="color: #a31515;">"error"</span>][<span style="color: #a31515;">"code"</span>],</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ErrorMessage = (<span style="color: blue;">string</span>)json[<span style="color: #a31515;">"short"</span>][<span style="color: #a31515;">"error"</span>][<span style="color: #a31515;">"msg"</span>]</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; };</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(shortie.Original);</pre>
+<pre style="margin: 0px;"><span style="color: green;">// http://www.foo.com/</span></pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(shortie.Error.ErrorMessage);</pre>
+<pre style="margin: 0px;"><span style="color: green;">// No action taken</span></pre>
+</div>
+
+</div></div>
+
+      <div id="footer"></div>      
+    </div>
+
+  </body>
+
+</html>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Doc/PreserveObjectReferences.html b/trunk/Libraries/Json40r2/Source/Doc/PreserveObjectReferences.html
new file mode 100644 (file)
index 0000000..471ac68
--- /dev/null
@@ -0,0 +1,138 @@
+<html>
+  
+  <head>
+    <title>Serialization and Preserving Object References</title>
+    <link href="styles.css" rel="stylesheet" type="text/css" />
+    <link href="custom.css" rel="stylesheet" type="text/css" />
+  </head>
+  
+  <body>
+    
+    <div id="control">
+      <span class="productTitle">Json.NET - Quick Starts & API Documentation</span><br />
+        <span class="topicTitle">Serialization and Preserving Object References</span></div>
+
+    <div id="content">
+      <span style="color: DarkGray"> </span>
+    
+       <p>By default Json.NET will serialize all objects it encounters by value. If a list 
+        contains two Person references, and both references point to the same object 
+        then the JsonSerializer will write out all the names and values for each 
+        reference.</p>
+
+<div class="overflowpanel"> <div class="code">
+
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: #2b91af;">Person</span> p = <span style="color: blue;">new</span> <span style="color: #2b91af;">Person</span></pre>
+<pre style="margin: 0px;">&nbsp; {</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; BirthDate = <span style="color: blue;">new</span> <span style="color: #2b91af;">DateTime</span>(1980, 12, 23, 0, 0, 0, <span style="color: #2b91af;">DateTimeKind</span>.Utc),</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; LastModified = <span style="color: blue;">new</span> <span style="color: #2b91af;">DateTime</span>(2009, 2, 20, 12, 59, 21, <span style="color: #2b91af;">DateTimeKind</span>.Utc),</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; Name = <span style="color: #a31515;">"James"</span></pre>
+<pre style="margin: 0px;">&nbsp; };</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">List</span>&lt;<span style="color: #2b91af;">Person</span>&gt; people = <span style="color: blue;">new</span> <span style="color: #2b91af;">List</span>&lt;<span style="color: #2b91af;">Person</span>&gt;();</pre>
+<pre style="margin: 0px;">people.Add(p);</pre>
+<pre style="margin: 0px;">people.Add(p);</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: blue;">string</span> json = <span style="color: #2b91af;">JsonConvert</span>.SerializeObject(people, <span style="color: #2b91af;">Formatting</span>.Indented);</pre>
+<pre style="margin: 0px;"><span style="color: green;">//[</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; {</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "Name": "James",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "BirthDate": "\/Date(346377600000)\/",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "LastModified": "\/Date(1235134761000)\/"</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; },</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; {</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "Name": "James",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "BirthDate": "\/Date(346377600000)\/",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "LastModified": "\/Date(1235134761000)\/"</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; }</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//]</span></pre>
+</div>
+</div></div>
+<p>In most cases this is the desired result but in certain scenarios writing the second item in the list as a reference to the first is a better solution. 
+    If the above JSON was deserialized now then the returned list would contain two 
+    completely separate Person objects with the same values. Writing references by value will also cause problems on objects where a 
+    circular reference occurs.</p>
+    
+    <h3>PreserveReferencesHandling</h3>
+        <p>Settings PreserveReferencesHandling will track object references when serializing 
+            and deserializing JSON.</p>
+
+<div class="overflowpanel"> <div class="code">
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: blue;">string</span> json = <span style="color: #2b91af;">JsonConvert</span>.SerializeObject(people, <span style="color: #2b91af;">Formatting</span>.Indented,</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">new</span> <span style="color: #2b91af;">JsonSerializerSettings</span> { PreserveReferencesHandling = <span style="color: #2b91af;">PreserveReferencesHandling</span>.Objects });</pre>
+<pre style="margin: 0px;"><span style="color: green;">//[</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; {</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "$id": "1",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "Name": "James",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "BirthDate": "\/Date(346377600000)\/",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "LastModified": "\/Date(1235134761000)\/"</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; },</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; {</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "$ref": "1"</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; }</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//]</span></pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">List</span>&lt;<span style="color: #2b91af;">Person</span>&gt; deserializedPeople = <span style="color: #2b91af;">JsonConvert</span>.DeserializeObject&lt;<span style="color: #2b91af;">List</span>&lt;<span style="color: #2b91af;">Person</span>&gt;&gt;(json,</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">new</span> <span style="color: #2b91af;">JsonSerializerSettings</span> { PreserveReferencesHandling = <span style="color: #2b91af;">PreserveReferencesHandling</span>.Objects });</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(deserializedPeople.Count);</pre>
+<pre style="margin: 0px;"><span style="color: green;">// 2</span></pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Person</span> p1 = deserializedPeople[0];</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Person</span> p2 = deserializedPeople[1];</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(p1.Name);</pre>
+<pre style="margin: 0px;"><span style="color: green;">// James</span></pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(p2.Name);</pre>
+<pre style="margin: 0px;"><span style="color: green;">// James</span></pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: blue;">bool</span> equal = <span style="color: #2b91af;">Object</span>.ReferenceEquals(p1, p2);</pre>
+<pre style="margin: 0px;"><span style="color: green;">// true</span></pre>
+</div>
+</div></div>
+
+<p>The first Person in the list is serizlied with the addition of an object Id. The 
+    second Person in JSON is now only a reference to the first.</p>
+        <p>With PreserveReferencesHandling on now only one Person object is created on 
+            deserialization and the list contains two references to it, mirroring what we 
+            started with.</p>
+
+       <h3>IsReference on JsonObjectAttribute, JsonArrayAttribute and JsonPropertyAttribute</h3>
+
+
+       <p>The PreserveReferencesHandling setting on the JsonSerializer will change
+       how all objects are serialized and deserialized. For fine grain control over which 
+        objects and members should be serialized as a reference there is the IsReference property on 
+        the JsonObjectAttribute, JsonArrayAttribute and JsonPropertyAttribute.</p>
+        <p>Setting IsReference on JsonObjectAttribute or JsonArrayAttribute to true will 
+            mean the JsonSerializer will always serialize the type the attribute is against 
+            as a reference. Setting IsReference on the JsonPropertyAttribute to true will 
+            serialize only that property as a reference.</p>
+
+<div class="overflowpanel"> <div class="code">
+
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;">[<span style="color: #2b91af;">JsonObject</span>(IsReference = <span style="color: blue;">true</span>)]</pre>
+<pre style="margin: 0px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">EmployeeReference</span></pre>
+<pre style="margin: 0px;">{</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> Name { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: #2b91af;">EmployeeReference</span> Manager { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">}</pre>
+</div>
+
+</div></div>
+    <h3>IReferenceResolver</h3>
+        <p>To customize how references are generated and resolved the <a href="./html/T_Newtonsoft_Json_Serialization_IReferenceResolver.htm">IReferenceResolver</a> interface is available to inherit from and use with the JsonSerializer.</p>
+
+      <div id="footer">
+
+
+    
+        </div>      
+    </div>
+
+  </body>
+
+</html>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Doc/ReadingWritingJSON.html b/trunk/Libraries/Json40r2/Source/Doc/ReadingWritingJSON.html
new file mode 100644 (file)
index 0000000..207e146
--- /dev/null
@@ -0,0 +1,87 @@
+<html>
+  
+  <head>
+    <title>Reading and Writing JSON</title>
+    <link href="styles.css" rel="stylesheet" type="text/css" />
+    <link href="custom.css" rel="stylesheet" type="text/css" />
+  </head>
+  
+  <body>
+    
+    <div id="control">
+      <span class="productTitle">Json.NET - Quick Starts & API Documentation</span><br />
+        <span class="topicTitle">Reading and Writing JSON</span></div>
+
+    <div id="content">
+      <span style="color: DarkGray"> </span>
+    
+       <p>To manually read and write JSON Json.NET provides the <a href="./html/T_Newtonsoft_Json_JsonReader.htm">JsonReader</a> and <a href="./html/T_Newtonsoft_Json_JsonWriter.htm">JsonWriter</a> classes.</p>
+
+<h3>JsonTextReader and JsonTextWriter</h3>
+<p><a href="./html/T_Newtonsoft_Json_JsonTextReader.htm">JsonTextReader</a> and <a href="./html/T_Newtonsoft_Json_JsonTextWriter.htm">JsonTextWriter</a> are used to read and write JSON text. The JsonTextWriter has a number of settings on it to control how JSON is formatted when it is written. These options include formatting, indention character, indent count and quote character.</p>
+
+<div class="overflowpanel"> <div class="code">
+
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: #2b91af;">StringBuilder</span> sb = <span style="color: blue;">new</span> <span style="color: #2b91af;">StringBuilder</span>();</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">StringWriter</span> sw = <span style="color: blue;">new</span> <span style="color: #2b91af;">StringWriter</span>(sb);</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: blue;">using</span> (<span style="color: #2b91af;">JsonWriter</span> jsonWriter = <span style="color: blue;">new</span> <span style="color: #2b91af;">JsonTextWriter</span>(sw))</pre>
+<pre style="margin: 0px;">{</pre>
+<pre style="margin: 0px;">&nbsp; jsonWriter.Formatting = <span style="color: #2b91af;">Formatting</span>.Indented;</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;">&nbsp; jsonWriter.WriteStartObject();</pre>
+<pre style="margin: 0px;">&nbsp; jsonWriter.WritePropertyName(<span style="color: #a31515;">"CPU"</span>);</pre>
+<pre style="margin: 0px;">&nbsp; jsonWriter.WriteValue(<span style="color: #a31515;">"Intel"</span>);</pre>
+<pre style="margin: 0px;">&nbsp; jsonWriter.WritePropertyName(<span style="color: #a31515;">"PSU"</span>);</pre>
+<pre style="margin: 0px;">&nbsp; jsonWriter.WriteValue(<span style="color: #a31515;">"500W"</span>);</pre>
+<pre style="margin: 0px;">&nbsp; jsonWriter.WritePropertyName(<span style="color: #a31515;">"Drives"</span>);</pre>
+<pre style="margin: 0px;">&nbsp; jsonWriter.WriteStartArray();</pre>
+<pre style="margin: 0px;">&nbsp; jsonWriter.WriteValue(<span style="color: #a31515;">"DVD read/writer"</span>);</pre>
+<pre style="margin: 0px;">&nbsp; jsonWriter.WriteComment(<span style="color: #a31515;">"(broken)"</span>);</pre>
+<pre style="margin: 0px;">&nbsp; jsonWriter.WriteValue(<span style="color: #a31515;">"500 gigabyte hard drive"</span>);</pre>
+<pre style="margin: 0px;">&nbsp; jsonWriter.WriteValue(<span style="color: #a31515;">"200 gigabype hard drive"</span>);</pre>
+<pre style="margin: 0px;">&nbsp; jsonWriter.WriteEnd();</pre>
+<pre style="margin: 0px;">&nbsp; jsonWriter.WriteEndObject();</pre>
+<pre style="margin: 0px;">}</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: green;">// {</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp;  "CPU": "Intel",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp;  "PSU": "500W",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp;  "Drives": [</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp;  "DVD read/writer"</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp;  /*(broken)*/,</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp;  "500 gigabyte hard drive",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp;  "200 gigabype hard drive"</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp;  ]</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">// }</span></pre>
+</div>
+
+</div></div>
+
+<h3>JTokenReader and JTokenWriter</h3>
+<p><a href="./html/T_Newtonsoft_Json_Linq_JTokenReader.htm">JTokenReader</a> and <a href="./html/T_Newtonsoft_Json_Linq_JTokenWriter.htm">JTokenWriter</a> read and write LINQ to JSON objects. They are located in the <a href="./html/N_Newtonsoft_Json_Linq.htm">Newtonsoft.Json.Linq</a> namespace. These objects allow you to use LINQ to JSON objects with objects that read and write JSON such as the JsonSerializer. For example you can deserialize from a LINQ to JSON object into a regular .NET object and vice versa.</p>
+
+<div class="overflowpanel"> <div class="code">
+
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: #2b91af;">JObject</span> o = <span style="color: blue;">new</span> <span style="color: #2b91af;">JObject</span>(</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">new</span> <span style="color: #2b91af;">JProperty</span>(<span style="color: #a31515;">"Name"</span>, <span style="color: #a31515;">"John Smith"</span>),</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">new</span> <span style="color: #2b91af;">JProperty</span>(<span style="color: #a31515;">"BirthDate"</span>, <span style="color: blue;">new</span> <span style="color: #2b91af;">DateTime</span>(1983, 3, 20))</pre>
+<pre style="margin: 0px;">&nbsp; );</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">JsonSerializer</span> serializer = <span style="color: blue;">new</span> <span style="color: #2b91af;">JsonSerializer</span>();</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Person</span> p = (<span style="color: #2b91af;">Person</span>)serializer.Deserialize(<span style="color: blue;">new</span> <span style="color: #2b91af;">JTokenReader</span>(o), <span style="color: blue;">typeof</span>(<span style="color: #2b91af;">Person</span>));</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(p.Name);</pre>
+<pre style="margin: 0px;"><span style="color: green;">// John Smith</span></pre>
+</div>
+
+</div></div>
+
+      <div id="footer"></div>      
+    </div>
+
+  </body>
+
+</html>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Doc/ReducingSerializedJSONSize.html b/trunk/Libraries/Json40r2/Source/Doc/ReducingSerializedJSONSize.html
new file mode 100644 (file)
index 0000000..64d002e
--- /dev/null
@@ -0,0 +1,280 @@
+<html>
+  
+  <head>
+    <title>Reducing Serialized JSON Size</title>
+    <link href="styles.css" rel="stylesheet" type="text/css" />
+    <link href="custom.css" rel="stylesheet" type="text/css" />
+  </head>
+  
+  <body>
+    
+    <div id="control">
+      <span class="productTitle">Json.NET - Quick Starts & API Documentation</span><br />
+        <span class="topicTitle">Reducing Serialized JSON Size</span></div>
+
+    <div id="content">
+      <span style="color: DarkGray"> </span>
+        <p>One of the common problems encountered when serializing .NET objects to JSON is that the JSON ends up containing a lot of unwanted properties and values. This can be especially important when returning JSON to the client. More JSON means more bandwidth and a slower website.</p>
+
+<p>To solve the issue of unwanted JSON Json.NET has a range of built in options to fine tune what gets written from a serialized object.</p>
+
+<h3>JsonIgnoreAttribute and DataMemberAttribute </h3>
+<p>By default Json.NET will include all of a classes public properties and fields in 
+    the JSON it creates. Adding the <a href="./html/T_Newtonsoft_Json_JsonIgnoreAttribute.htm">JsonIgnoreAttribute</a> to a property tells the serializer 
+    to always skip writing it to the JSON result. </p>
+
+<div class="overflowpanel">
+  <div class="code">
+    <div style="font-family: courier new; color: black; font-size: 10pt;">
+      <pre style="margin: 0px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: rgb(43, 145, 175);">Car</span></pre>
+      <pre style="margin: 0px;">{</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: green;">// included in JSON</span></pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> Model { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: rgb(43, 145, 175);">DateTime</span> Year { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: rgb(43, 145, 175);">List</span>&lt;<span style="color: blue;">string</span>&gt; Features { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+      <pre style="margin: 0px;">&nbsp;</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: green;">// ignored</span></pre>
+      <pre style="margin: 0px;">&nbsp; [<span style="color: rgb(43, 145, 175);">JsonIgnore</span>]</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: rgb(43, 145, 175);">DateTime</span> LastModified { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+      <pre style="margin: 0px;">}</pre>
+    </div>
+  </div>
+</div>
+
+<p>If a class has many properties and you only want to serialize a small subset of 
+    them then adding JsonIgnore to all the others will be tedious and error prone. 
+    The way to tackle this scenario is to add the
+    <a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractattribute.aspx" 
+        target="_blank">DataContractAttribute</a> to the class and 
+    DataMemberAttributes to the properties to serialize. This is opt-in 
+    serialization, only the properties you mark up with be serialized, compared to 
+    opt-out serialization using JsonIgnoreAttribute.</p>
+
+<div class="overflowpanel">
+
+  <div class="code">
+    <div style="font-family: courier new; color: black; font-size: 10pt;">
+      <pre style="margin: 0px;">[<span style="color: rgb(43, 145, 175);">DataContract</span>]</pre>
+      <pre style="margin: 0px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: rgb(43, 145, 175);">Computer</span></pre>
+      <pre style="margin: 0px;">{</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: green;">// included in JSON</span></pre>
+      <pre style="margin: 0px;">&nbsp; [<span style="color: rgb(43, 145, 175);">DataMember</span>]</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> Name { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+      <pre style="margin: 0px;">&nbsp; [<span style="color: rgb(43, 145, 175);">DataMember</span>]</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">decimal</span> SalePrice { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+      <pre style="margin: 0px;">&nbsp;</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: green;">// ignored</span></pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> Manufacture { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">int</span> StockCount { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">decimal</span> WholeSalePrice { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: rgb(43, 145, 175);">DateTime</span> NextShipmentDate { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+      <pre style="margin: 0px;">}</pre>
+    </div>
+  </div>
+</div>
+
+<h3>Formatting </h3>
+
+<p>JSON written by the serializer with an option of <a href="./html/T_Newtonsoft_Json_Formatting.htm">Formatting.Indented</a> produces nicely formatted, easy to read JSON \96 great when you are developing. <a href="./html/T_Newtonsoft_Json_Formatting.htm">Formatting.None</a> on the other hand keeps the JSON result small, skipping all unnecessary spaces and line breaks to produce the most compact and efficient JSON possible. </p>
+
+<p><strong>NullValueHandling </strong></p>
+
+<p><a href="./html/T_Newtonsoft_Json_NullValueHandling.htm">NullValueHandling</a> is an option on the JsonSerializer and controls how the serializer handles properties with a null value. By setting a value of NullValueHandling.Ignore the JsonSerializer skips writing any properties that have a value of null.</p>
+
+<div class="overflowpanel">
+  <div class="code">
+    <div style="font-family: courier new; color: black; font-size: 10pt;">
+      <pre style="margin: 0px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: rgb(43, 145, 175);">Movie</span></pre>
+      <pre style="margin: 0px;">{</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> Name { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> Description { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> Classification { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> Studio { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: rgb(43, 145, 175);">DateTime</span>? ReleaseDate { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: rgb(43, 145, 175);">List</span>&lt;<span style="color: blue;">string</span>&gt; ReleaseCountries { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+      <pre style="margin: 0px;">}</pre>
+    </div>
+  </div>
+</div>
+
+<div class="overflowpanel">
+  <div class="code">
+    <div style="font-family: courier new; color: black; font-size: 10pt;">
+      <pre style="margin: 0px;"><span style="color: rgb(43, 145, 175);">Movie</span> movie = <span style="color: blue;">new</span> <span style="color: rgb(43, 145, 175);">Movie</span>();</pre>
+      <pre style="margin: 0px;">movie.Name = <span style="color: rgb(163, 21, 21);">"Bad Boys III"</span>;</pre>
+      <pre style="margin: 0px;">movie.Description = <span style="color: rgb(163, 21, 21);">"It's no Bad Boys"</span>;</pre>
+      <pre style="margin: 0px;">&nbsp;</pre>
+      <pre style="margin: 0px;"><span style="color: blue;">string</span> included = <span style="color: rgb(43, 145, 175);">JsonConvert</span>.SerializeObject(movie,</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: rgb(43, 145, 175);">Formatting</span>.Indented,</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">new</span> <span style="color: rgb(43, 145, 175);">JsonSerializerSettings</span> { });</pre>
+      <pre style="margin: 0px;">&nbsp;</pre>
+      <pre style="margin: 0px;"><span style="color: green;">// {</span></pre>
+      <pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp; "Name": "Bad Boys III",</span></pre>
+      <pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp; "Description": "It's no Bad Boys",</span></pre>
+      <pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp; "Classification": null,</span></pre>
+      <pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp; "Studio": null,</span></pre>
+      <pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp; "ReleaseDate": null,</span></pre>
+      <pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp; "ReleaseCountries": null</span></pre>
+      <pre style="margin: 0px;"><span style="color: green;">// }</span></pre>
+      <pre style="margin: 0px;">&nbsp;</pre>
+      <pre style="margin: 0px;"><span style="color: blue;">string</span> ignored = <span style="color: rgb(43, 145, 175);">JsonConvert</span>.SerializeObject(movie,</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: rgb(43, 145, 175);">Formatting</span>.Indented,</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">new</span> <span style="color: rgb(43, 145, 175);">JsonSerializerSettings</span> { NullValueHandling = <span style="color: rgb(43, 145, 175);">NullValueHandling</span>.Ignore });</pre>
+      <pre style="margin: 0px;">&nbsp;</pre>
+      <pre style="margin: 0px;"><span style="color: green;">// {</span></pre>
+      <pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp; "Name": "Bad Boys III",</span></pre>
+      <pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp; "Description": "It's no Bad Boys"</span></pre>
+      <pre style="margin: 0px;"><span style="color: green;">// }</span></pre>
+    </div>
+  </div>
+</div>
+
+<p>NullValueHandling can also be customized on individual properties using the a <a href="./html/T_Newtonsoft_Json_JsonPropertyAttribute.htm">JsonPropertyAttribute</a>. The JsonPropertyAttribute value of NullValueHandling will override the setting on the JsonSerializer for that property. </p>
+
+<h3>DefaultValueHandling </h3>
+
+<p><a href="./html/T_Newtonsoft_Json_NullValueHandling.htm">DefaultValueHandling</a> is an option on the JsonSerializer and controls how the serializer handles properties with a default value. Setting a value of DefaultValueHandling.Ignore will make the JsonSerializer skip writing any properties that have a default value to the JSON result. For object references this will be null. For value types like int and DateTime the serializer will skip the default unitialized value for that value type. </p>
+
+<p>Json.NET also allows you to customize what the default value of an individual property is using the <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.defaultvalueattribute.aspx" target="_blank">DefaultValueAttribute</a>. For example if a string property called Department always returns an empty string in its default state and you didn't want that empty string in your JSON then placing the DefaultValueAttribute on Department with that value will mean Department is no longer written to JSON unless it has a value. </p>
+
+<div class="overflowpanel">
+  <div class="code">
+    <div style="font-family: courier new; color: black; font-size: 10pt;">
+      <pre style="margin: 0px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: rgb(43, 145, 175);">Invoice</span></pre>
+      <pre style="margin: 0px;">{</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> Company { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">decimal</span> Amount { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+      <pre style="margin: 0px;">&nbsp;</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: green;">// false is default value of bool</span></pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">bool</span> Paid { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: green;">// null is default value of nullable</span></pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: rgb(43, 145, 175);">DateTime</span>? PaidDate { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+      <pre style="margin: 0px;">&nbsp;</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: green;">// customize default values</span></pre>
+      <pre style="margin: 0px;">&nbsp; [<span style="color: rgb(43, 145, 175);">DefaultValue</span>(30)]</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">int</span> FollowUpDays { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+      <pre style="margin: 0px;">&nbsp; [<span style="color: rgb(43, 145, 175);">DefaultValue</span>(<span style="color: rgb(163, 21, 21);">""</span>)]</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> FollowUpEmailAddress { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+      <pre style="margin: 0px;">}</pre>
+    </div>
+  </div>
+</div>
+
+<div class="overflowpanel">
+  <div class="code">
+    <div style="font-family: courier new; color: black; font-size: 10pt;">
+      <pre style="margin: 0px;"><span style="color: rgb(43, 145, 175);">Invoice</span> invoice = <span style="color: blue;">new</span> <span style="color: rgb(43, 145, 175);">Invoice</span></pre>
+      <pre style="margin: 0px;">{</pre>
+      <pre style="margin: 0px;">&nbsp; Company = <span style="color: rgb(163, 21, 21);">"Acme Ltd."</span>,</pre>
+      <pre style="margin: 0px;">&nbsp; Amount = 50.0m,</pre>
+      <pre style="margin: 0px;">&nbsp; Paid = <span style="color: blue;">false</span>,</pre>
+      <pre style="margin: 0px;">&nbsp; FollowUpDays = 30,</pre>
+      <pre style="margin: 0px;">&nbsp; FollowUpEmailAddress = <span style="color: blue;">string</span>.Empty,</pre>
+      <pre style="margin: 0px;">&nbsp; PaidDate = <span style="color: blue;">null</span></pre>
+      <pre style="margin: 0px;">};</pre>
+      <pre style="margin: 0px;">&nbsp;</pre>
+      <pre style="margin: 0px;"><span style="color: blue;">string</span> included = <span style="color: rgb(43, 145, 175);">JsonConvert</span>.SerializeObject(invoice,</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: rgb(43, 145, 175);">Formatting</span>.Indented,</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">new</span> <span style="color: rgb(43, 145, 175);">JsonSerializerSettings</span> { });</pre>
+      <pre style="margin: 0px;">&nbsp;</pre>
+      <pre style="margin: 0px;"><span style="color: green;">// {</span></pre>
+      <pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp; "Company": "Acme Ltd.",</span></pre>
+      <pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp; "Amount": 50.0,</span></pre>
+      <pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp; "Paid": false,</span></pre>
+      <pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp; "PaidDate": null,</span></pre>
+      <pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp; "FollowUpDays": 30,</span></pre>
+      <pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp; "FollowUpEmailAddress": ""</span></pre>
+      <pre style="margin: 0px;"><span style="color: green;">// }</span></pre>
+      <pre style="margin: 0px;">&nbsp;</pre>
+      <pre style="margin: 0px;"><span style="color: blue;">string</span> ignored = <span style="color: rgb(43, 145, 175);">JsonConvert</span>.SerializeObject(invoice,</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: rgb(43, 145, 175);">Formatting</span>.Indented,</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">new</span> <span style="color: rgb(43, 145, 175);">JsonSerializerSettings</span> { DefaultValueHandling = <span style="color: rgb(43, 145, 175);">DefaultValueHandling</span>.Ignore });</pre>
+      <pre style="margin: 0px;">&nbsp;</pre>
+      <pre style="margin: 0px;"><span style="color: green;">// {</span></pre>
+      <pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp; "Company": "Acme Ltd.",</span></pre>
+      <pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp; "Amount": 50.0</span></pre>
+      <pre style="margin: 0px;"><span style="color: green;">// }</span></pre>
+    </div>
+  </div>
+</div>
+
+<p>DefaultValueHandling can also be customized on individual properties using the a <a href="./html/T_Newtonsoft_Json_JsonPropertyAttribute.htm">JsonPropertyAttribute</a>. The JsonPropertyAttribute value of DefaultValueHandling will override the setting on the JsonSerializer for that property.</p>
+
+<h3>IContractResolver</h3>
+
+<p>For more flexibility the <a href="./html/T_Newtonsoft_Json_Serialization_IContractResolver.htm">IContractResolver</a> provides an interface to customize almost every aspect of how a .NET object gets serialized to JSON, including changing serialization behavior at runtime.</p>
+
+<div class="overflowpanel">
+  <div class="code">
+    <div style="font-family: courier new; color: black; font-size: 10pt;">
+      <pre style="margin: 0px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: rgb(43, 145, 175);">DynamicContractResolver</span> : <span style="color: rgb(43, 145, 175);">DefaultContractResolver</span></pre>
+      <pre style="margin: 0px;">{</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">private</span> <span style="color: blue;">readonly</span> <span style="color: blue;">char</span> _startingWithChar;</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> DynamicContractResolver(<span style="color: blue;">char</span> startingWithChar)</pre>
+      <pre style="margin: 0px;">&nbsp; {</pre>
+      <pre style="margin: 0px;">&nbsp;&nbsp;&nbsp; _startingWithChar = startingWithChar;</pre>
+      <pre style="margin: 0px;">&nbsp; }</pre>
+      <pre style="margin: 0px;">&nbsp;</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">protected</span> <span style="color: blue;">override</span> <span style="color: rgb(43, 145, 175);">IList</span>&lt;<span style="color: rgb(43, 145, 175);">JsonProperty</span>&gt; CreateProperties(<span style="color: rgb(43, 145, 175);">JsonObjectContract</span> contract)</pre>
+      <pre style="margin: 0px;">&nbsp; {</pre>
+      <pre style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: rgb(43, 145, 175);">IList</span>&lt;<span style="color: rgb(43, 145, 175);">JsonProperty</span>&gt; properties = <span style="color: blue;">base</span>.CreateProperties(contract);</pre>
+      <pre style="margin: 0px;">&nbsp;</pre>
+      <pre style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: green;">// only serializer properties that start with the specified character</span></pre>
+      <pre style="margin: 0px;">&nbsp;&nbsp;&nbsp; properties = </pre>
+      <pre style="margin: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; properties.Where(p =&gt; p.PropertyName.StartsWith(_startingWithChar.ToString())).ToList();</pre>
+      <pre style="margin: 0px;">&nbsp;</pre>
+      <pre style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">return</span> properties;</pre>
+      <pre style="margin: 0px;">&nbsp; }</pre>
+      <pre style="margin: 0px;">}</pre>
+      <pre style="margin: 0px;">&nbsp;</pre>
+      <pre style="margin: 0px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: rgb(43, 145, 175);">Book</span></pre>
+      <pre style="margin: 0px;">{</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> BookName { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">decimal</span> BookPrice { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> AuthorName { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">int</span> AuthorAge { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> AuthorCountry { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+      <pre style="margin: 0px;">}</pre>
+    </div>
+  </div>
+</div>
+
+<div class="overflowpanel">
+  <div class="code">
+    <div style="font-family: courier new; color: black; font-size: 10pt;">
+      <pre style="margin: 0px;"><span style="color: rgb(43, 145, 175);">Book</span> book = <span style="color: blue;">new</span> <span style="color: rgb(43, 145, 175);">Book</span></pre>
+      <pre style="margin: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</pre>
+      <pre style="margin: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BookName = <span style="color: rgb(163, 21, 21);">"The Gathering Storm"</span>,</pre>
+      <pre style="margin: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BookPrice = 16.19m,</pre>
+      <pre style="margin: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AuthorName = <span style="color: rgb(163, 21, 21);">"Brandon Sanderson"</span>,</pre>
+      <pre style="margin: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AuthorAge = 34,</pre>
+      <pre style="margin: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AuthorCountry = <span style="color: rgb(163, 21, 21);">"United States of America"</span></pre>
+      <pre style="margin: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };</pre>
+      <pre style="margin: 0px;">&nbsp;</pre>
+      <pre style="margin: 0px;"><span style="color: blue;">string</span> startingWithA = <span style="color: rgb(43, 145, 175);">JsonConvert</span>.SerializeObject(book, <span style="color: rgb(43, 145, 175);">Formatting</span>.Indented,</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">new</span> <span style="color: rgb(43, 145, 175);">JsonSerializerSettings</span> { ContractResolver = <span style="color: blue;">new</span> <span style="color: rgb(43, 145, 175);">DynamicContractResolver</span>(<span style="color: rgb(163, 21, 21);">'A'</span>) });</pre>
+      <pre style="margin: 0px;">&nbsp;</pre>
+      <pre style="margin: 0px;"><span style="color: green;">// {</span></pre>
+      <pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp; "AuthorName": "Brandon Sanderson",</span></pre>
+      <pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp; "AuthorAge": 34,</span></pre>
+      <pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp; "AuthorCountry": "United States of America"</span></pre>
+      <pre style="margin: 0px;"><span style="color: green;">// }</span></pre>
+      <pre style="margin: 0px;">&nbsp;</pre>
+      <pre style="margin: 0px;"><span style="color: blue;">string</span> startingWithB = <span style="color: rgb(43, 145, 175);">JsonConvert</span>.SerializeObject(book, <span style="color: rgb(43, 145, 175);">Formatting</span>.Indented,</pre>
+      <pre style="margin: 0px;">&nbsp; <span style="color: blue;">new</span> <span style="color: rgb(43, 145, 175);">JsonSerializerSettings</span> { ContractResolver = <span style="color: blue;">new</span> <span style="color: rgb(43, 145, 175);">DynamicContractResolver</span>(<span style="color: rgb(163, 21, 21);">'B'</span>) });</pre>
+      <pre style="margin: 0px;">&nbsp;</pre>
+      <pre style="margin: 0px;"><span style="color: green;">// {</span></pre>
+      <pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp; "BookName": "The Gathering Storm",</span></pre>
+      <pre style="margin: 0px;"><span style="color: green;">//&nbsp;&nbsp; "BookPrice": 16.19</span></pre>
+      <pre style="margin: 0px;"><span style="color: green;">// }</span></pre>
+    </div>
+  </div>
+</div>
+
+
+      <div id="footer"></div>      
+    </div>
+
+  </body>
+
+</html>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Doc/SelectToken.html b/trunk/Libraries/Json40r2/Source/Doc/SelectToken.html
new file mode 100644 (file)
index 0000000..14ecc5a
--- /dev/null
@@ -0,0 +1,116 @@
+<html>
+  
+  <head>
+    <title>Querying LINQ to JSON with SelectToken</title>
+    <link href="styles.css" rel="stylesheet" type="text/css" />
+    <link href="custom.css" rel="stylesheet" type="text/css" />
+  </head>
+  
+  <body>
+    
+    <div id="control">
+      <span class="productTitle">Json.NET - Quick Starts & API Documentation</span><br />
+        <span class="topicTitle">Querying LINQ to JSON with SelectToken</span></div>
+
+    <div id="content">
+      <span style="color: DarkGray"> </span>
+        <p><a href="./html/M_Newtonsoft_Json_Linq_JToken_SelectToken.htm">SelectToken</a> provides a method to query LINQ to JSON using a single string path to a 
+            desired <a href="./html/T_Newtonsoft_Json_Linq_JToken.htm">JToken</a>. SelectToken makes dynamic queries 
+            easy because the entire 
+            query is defined in a string.</p>
+            
+<div class="overflowpanel">
+  <div class="code">
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: blue;">string</span> name = (<span style="color: blue;">string</span>)o.SelectToken(<span style="color: #a31515;">&quot;Manufacturers[0].Name&quot;</span>);</pre>
+
+</div>
+  </div>
+</div>
+
+<h3>SelectToken</h3>
+<p>SelectToken is a method on JToken and takes a string path to a child token. 
+    SelectToken returns the child token or a null reference if a token couldn&#39;t be 
+    found at the path&#39;s location.</p>
+        <p>The 
+    path is made up of property names and array indexes separated by periods. Array indexes 
+            can use either square or round brackets. Both 
+    of the following are valid paths and are equivalent to each other: <code>Manufacturers[0].Name</code> 
+    and <code>Manufacturers(0).Name</code>.</p>
+
+<div class="overflowpanel">
+  <div class="code">
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: #2b91af;">JObject</span> o = <span style="color: #2b91af;">JObject</span>.Parse(<span style="color: #a31515;">@&quot;{</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &quot;&quot;Stores&quot;&quot;: [</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &quot;&quot;Lambton Quay&quot;&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &quot;&quot;Willis Street&quot;&quot;</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; ],</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &quot;&quot;Manufacturers&quot;&quot;: [</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; {</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &quot;&quot;Name&quot;&quot;: &quot;&quot;Acme Co&quot;&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &quot;&quot;Products&quot;&quot;: [</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; {</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;Name&quot;&quot;: &quot;&quot;Anvil&quot;&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;Price&quot;&quot;: 50</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; }</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; ]</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; },</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; {</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &quot;&quot;Name&quot;&quot;: &quot;&quot;Contoso&quot;&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &quot;&quot;Products&quot;&quot;: [</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; {</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;Name&quot;&quot;: &quot;&quot;Elbow Grease&quot;&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;Price&quot;&quot;: 99.95</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; },</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; {</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;Name&quot;&quot;: &quot;&quot;Headlight Fluid&quot;&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;Price&quot;&quot;: 4</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; }</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; ]</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; }</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; ]</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">}&quot;</span>);</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: blue;">string</span> name = (<span style="color: blue;">string</span>)o.SelectToken(<span style="color: #a31515;">&quot;Manufacturers[0].Name&quot;</span>);</pre>
+<pre style="margin: 0px;"><span style="color: green;">// Acme Co</span></pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: blue;">decimal</span> productPrice = (<span style="color: blue;">decimal</span>)o.SelectToken(<span style="color: #a31515;">&quot;Manufacturers[0].Products[0].Price&quot;</span>);</pre>
+<pre style="margin: 0px;"><span style="color: green;">// 50</span></pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: blue;">string</span> productName = (<span style="color: blue;">string</span>)o.SelectToken(<span style="color: #a31515;">&quot;Manufacturers[1].Products[0].Name&quot;</span>);</pre>
+<pre style="margin: 0px;"><span style="color: green;">// Elbow Grease</span></pre>
+</div>
+  </div>
+</div>
+
+<h3>SelectToken with LINQ</h3>
+
+<p>SelectToken can be used in combination with standard LINQ methods.</p>
+
+<div class="overflowpanel">
+
+  <div class="code">
+
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: #2b91af;">IList</span>&lt;<span style="color: blue;">string</span>&gt; storeNames = o.SelectToken(<span style="color: #a31515;">&quot;Stores&quot;</span>).Select(s =&gt; (<span style="color: blue;">string</span>)s).ToList();</pre>
+<pre style="margin: 0px;"><span style="color: green;">// Lambton Quay</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">// Willis Street</span></pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">IList</span>&lt;<span style="color: blue;">string</span>&gt; firstProductNames = o[<span style="color: #a31515;">&quot;Manufacturers&quot;</span>].Select(m =&gt; (<span style="color: blue;">string</span>)m.SelectToken(<span style="color: #a31515;">&quot;Products[1].Name&quot;</span>)).ToList();</pre>
+<pre style="margin: 0px;"><span style="color: green;">// null</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">// Headlight Fluid</span></pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: blue;">decimal</span> totalPrice = o[<span style="color: #a31515;">&quot;Manufacturers&quot;</span>].Sum(m =&gt; (<span style="color: blue;">decimal</span>)m.SelectToken(<span style="color: #a31515;">&quot;Products[0].Price&quot;</span>));</pre>
+<pre style="margin: 0px;"><span style="color: green;">// 149.95</span></pre>
+</div>
+
+  </div>
+</div>
+
+      <div id="footer"></div>      
+    </div>
+
+  </body>
+
+</html>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Doc/SerializationAttributes.html b/trunk/Libraries/Json40r2/Source/Doc/SerializationAttributes.html
new file mode 100644 (file)
index 0000000..eb3cce7
--- /dev/null
@@ -0,0 +1,123 @@
+<html>
+  
+  <head>
+    <title>Customizing JSON serialization with attributes</title>
+    <link href="styles.css" rel="stylesheet" type="text/css" />
+    <link href="custom.css" rel="stylesheet" type="text/css" />
+  </head>
+  
+  <body>
+    
+    <div id="control">
+      <span class="productTitle">Json.NET - Quick Starts & API Documentation</span><br />
+        <span class="topicTitle">Customizing JSON serialization with attributes</span></div>
+
+    <div id="content">
+      <span style="color: DarkGray"> </span>
+    
+          <p>Attributes can be used to control how Json.NET serializes and deserializes .NET objects.</p>
+          <ul>
+            <li><a href="./html/T_Newtonsoft_Json_JsonObjectAttribute.htm">JsonObjectAttribute</a> - Placed on classes to control how it should be serialized as a JSON object.</li>
+            <li><a href="./html/T_Newtonsoft_Json_JsonArrayAttribute.htm">JsonArrayAttribute</a> - Placed on collections to control how it should be serialized as a JSON array.</li>
+            <li><a href="./html/T_Newtonsoft_Json_JsonPropertyAttribute.htm">JsonPropertyAttribute</a> - Placed on fields and properties to control how it should be serialized as a property in a JSON object.</li>
+            <li><a href="./html/T_Newtonsoft_Json_JsonConverterAttribute.htm">JsonConverterAttribute</a> - Placed on either classes or fields and properties to specify which JsonConverter should be used during serialization.</li>
+          </ul>
+          <p>As well as using the built-in Json.NET attributes, Json.NET also looks for the 
+              <a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractattribute.aspx" target="_blank">DataContract</a> and 
+              <a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractattribute.aspx" target="_blank">DataMember</a> attributes when determining how JSON is to be serialized and deserialized. If both are present the Json.NET serialization attributes take precedence.</p>
+          
+<div class="overflowpanel"> <div class="code">
+
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;">[<span style="color: #2b91af;">JsonObject</span>(<span style="color: #2b91af;">MemberSerialization</span>.OptIn)]</pre>
+<pre style="margin: 0px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">Person</span></pre>
+<pre style="margin: 0px;">{</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: green;">// "John Smith"</span></pre>
+<pre style="margin: 0px;">&nbsp; [<span style="color: #2b91af;">JsonProperty</span>]</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> Name { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: green;">// "2000-12-15T22:11:03"</span></pre>
+<pre style="margin: 0px;">&nbsp; [<span style="color: #2b91af;">JsonProperty</span>]</pre>
+<pre style="margin: 0px;">&nbsp; [<span style="color: #2b91af;">JsonConverter</span>(<span style="color: blue;">typeof</span>(<span style="color: #2b91af;">IsoDateTimeConverter</span>))]</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: #2b91af;">DateTime</span> BirthDate { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: green;">// new Date(976918263055)</span></pre>
+<pre style="margin: 0px;">&nbsp; [<span style="color: #2b91af;">JsonProperty</span>]</pre>
+<pre style="margin: 0px;">&nbsp; [<span style="color: #2b91af;">JsonConverter</span>(<span style="color: blue;">typeof</span>(<span style="color: #2b91af;">JavaScriptDateTimeConverter</span>))]</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: #2b91af;">DateTime</span> LastModified { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: green;">// not serialized</span></pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> Department { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">}</pre>
+</div>
+
+</div></div>
+
+    <h5>JsonObjectAttribute</h5>
+<p>The MemberSerialization flag on this attribute specifies whether member serialization is opt-in (a member must have the JsonProperty or DataMember attribute to be serialized) or opt-out (everything is serialized by default but can be ignored with the JsonIgnoreAttribute, 
+    Json.NET&#39;s default behavor).</p>
+<p>Json.NET serializes .NET classes that implement IEnumerable as an 
+    JSON array populated with the IEnumerable values. Placing the JsonPropertyAttribute overrides this 
+    behavor and forces the serializer to serialize the class's fields and properties.</p>
+    <h5>JsonPropertyAttribute</h5>
+<p>JsonPropertyAttribute has a number of uses:</p>
+<ul>
+    <li>By default the JSON property will have the same name as the .NET property. This attribute allows the name to be customized.</li>
+    <li>Indicates that a property should be serialized when member serialization is set to opt-in.</li>
+    <li>Includes non-public properties in serialization and deserialization.</li>
+</ul>
+    <h5>JsonIgnoreAttribute</h5>
+<p>Excludes a field or property from serialization.</p>
+    <h5>JsonConverterAttribute</h5>
+<p>The JsonConverterAttribute specifies which JsonSerializer is used to convert an object.</p>
+<p>The attribute can be placed on a class or a member. When placed on a class the JsonConverter 
+    specified by the attribute will be the default way of serializing that class. When the attribute is on a field
+or property then the specified JsonConverter will always be used to serialize that value.</p>
+<p>The priority of which JsonConverter is used is member attribute then class attribute and
+finally any converters passed to the JsonSerializer.</p>
+
+<div class="overflowpanel"> <div class="code">
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">MemberConverterClass</span></pre>
+<pre style="margin: 0px;">{</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: #2b91af;">DateTime</span> DefaultConverter { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">&nbsp; [<span style="color: #2b91af;">JsonConverter</span>(<span style="color: blue;">typeof</span>(<span style="color: #2b91af;">IsoDateTimeConverter</span>))]</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: #2b91af;">DateTime</span> MemberConverter { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">}</pre>
+</div>
+</div></div>
+<p>This example shows the JsonConverterAttribute being applied to a property.</p>
+
+
+<div class="overflowpanel"> <div class="code">
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: #2b91af;">DateTime</span> date = <span style="color: #2b91af;">Convert</span>.ToDateTime(<span style="color: #a31515;">"1970-01-01T00:00:00Z"</span>).ToUniversalTime();</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">MemberConverterClass</span> c = <span style="color: blue;">new</span> <span style="color: #2b91af;">MemberConverterClass</span></pre>
+<pre style="margin: 0px;">&nbsp; {</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; DefaultConverter = date,</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; MemberConverter = date</pre>
+<pre style="margin: 0px;">&nbsp; };</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: blue;">string</span> json = <span style="color: #2b91af;">JsonConvert</span>.SerializeObject(c, <span style="color: #2b91af;">Formatting</span>.Indented);</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(json);</pre>
+<pre style="margin: 0px;"><span style="color: green;">//{</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; "DefaultConverter": "\/Date(0)\/",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; "MemberConverter": "1970-01-01T00:00:00Z"</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//}</span></pre>
+</div>
+
+</div></div>
+
+
+      <div id="footer">
+
+
+    
+        </div>      
+    </div>
+
+  </body>
+
+</html>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Doc/SerializationCallbacks.html b/trunk/Libraries/Json40r2/Source/Doc/SerializationCallbacks.html
new file mode 100644 (file)
index 0000000..11fd37c
--- /dev/null
@@ -0,0 +1,143 @@
+<html>
+  
+  <head>
+    <title>Serialization Callbacks</title>
+    <link href="styles.css" rel="stylesheet" type="text/css" />
+    <link href="custom.css" rel="stylesheet" type="text/css" />
+  </head>
+  
+  <body>
+    
+    <div id="control">
+      <span class="productTitle">Json.NET - Quick Starts & API Documentation</span><br />
+        <span class="topicTitle">Serialization Callbacks</span></div>
+
+    <div id="content">
+      <span style="color: DarkGray"> </span>
+    
+       <p>Json.NET supports serialization callback methods. A callback can be used to 
+        manipulate an object before and after its serialization and deserialization by 
+        the JsonSerializer.</p>
+       <ul>
+           <li><b>OnSerializing</b></li>
+           <li><b>OnSerialized</b></li>
+           <li><b>OnDeserializing</b></li>
+           <li><b>OnDeserialized</b></li>
+       </ul>
+       <p>To tell the serializer which methods should be called during the object&#39;s serialization 
+        lifecycle, decorate a method with the appropraite attribute (<a 
+            href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.onserializingattribute.aspx" target="_blank">OnSerializingAttribute</a>, 
+        <a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.onserializedattribute.aspx" target="_blank">OnSerializedAttribute</a>, 
+        <a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.ondeserializingattribute.aspx" target="_blank">OnDeserializingAttribute</a>, 
+        <a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.ondeserializedattribute.aspx" target="_blank">OnDeserializedAttribute</a>).</p>
+<p>Example object with serialization callback methods:</p>
+
+<div class="overflowpanel"> <div class="code">
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">SerializationEventTestObject</span></pre>
+<pre style="margin: 0px;">{</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: green;">// This member is serialized and deserialized with no change.</span></pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">int</span> Member1 { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: green;">// The value of this field is set and reset during and </span></pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: green;">// after serialization.</span></pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> Member2 { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: green;">// This field is not serialized. The OnDeserializedAttribute </span></pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: green;">// is used to set the member value after serialization.</span></pre>
+<pre style="margin: 0px;">&nbsp; [<span style="color: #2b91af;">JsonIgnore</span>]</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> Member3 { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: green;">// This field is set to null, but populated after deserialization.</span></pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> Member4 { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> SerializationEventTestObject()</pre>
+<pre style="margin: 0px;">&nbsp; {</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; Member1 = 11;</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; Member2 = <span style="color: #a31515;">"Hello World!"</span>;</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; Member3 = <span style="color: #a31515;">"This is a nonserialized value"</span>;</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; Member4 = <span style="color: blue;">null</span>;</pre>
+<pre style="margin: 0px;">&nbsp; }</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;">&nbsp; [<span style="color: #2b91af;">OnSerializing</span>]</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">internal</span> <span style="color: blue;">void</span> OnSerializingMethod(<span style="color: #2b91af;">StreamingContext</span> context)</pre>
+<pre style="margin: 0px;">&nbsp; {</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; Member2 = <span style="color: #a31515;">"This value went into the data file during serialization."</span>;</pre>
+<pre style="margin: 0px;">&nbsp; }</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;">&nbsp; [<span style="color: #2b91af;">OnSerialized</span>]</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">internal</span> <span style="color: blue;">void</span> OnSerializedMethod(<span style="color: #2b91af;">StreamingContext</span> context)</pre>
+<pre style="margin: 0px;">&nbsp; {</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; Member2 = <span style="color: #a31515;">"This value was reset after serialization."</span>;</pre>
+<pre style="margin: 0px;">&nbsp; }</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;">&nbsp; [<span style="color: #2b91af;">OnDeserializing</span>]</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">internal</span> <span style="color: blue;">void</span> OnDeserializingMethod(<span style="color: #2b91af;">StreamingContext</span> context)</pre>
+<pre style="margin: 0px;">&nbsp; {</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; Member3 = <span style="color: #a31515;">"This value was set during deserialization"</span>;</pre>
+<pre style="margin: 0px;">&nbsp; }</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;">&nbsp; [<span style="color: #2b91af;">OnDeserialized</span>]</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">internal</span> <span style="color: blue;">void</span> OnDeserializedMethod(<span style="color: #2b91af;">StreamingContext</span> context)</pre>
+<pre style="margin: 0px;">&nbsp; {</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; Member4 = <span style="color: #a31515;">"This value was set after deserialization."</span>;</pre>
+<pre style="margin: 0px;">&nbsp; }</pre>
+<pre style="margin: 0px;">}</pre>
+</div>
+</div></div>
+
+<p>The example object being serialized and deserialized by Json.NET:</p>
+
+<div class="overflowpanel"> <div class="code">
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: #2b91af;">SerializationEventTestObject</span> obj = <span style="color: blue;">new</span> <span style="color: #2b91af;">SerializationEventTestObject</span>();</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(obj.Member1);</pre>
+<pre style="margin: 0px;"><span style="color: green;">// 11</span></pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(obj.Member2);</pre>
+<pre style="margin: 0px;"><span style="color: green;">// Hello World!</span></pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(obj.Member3);</pre>
+<pre style="margin: 0px;"><span style="color: green;">// This is a nonserialized value</span></pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(obj.Member4);</pre>
+<pre style="margin: 0px;"><span style="color: green;">// null</span></pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: blue;">string</span> json = <span style="color: #2b91af;">JsonConvert</span>.SerializeObject(obj, <span style="color: #2b91af;">Formatting</span>.Indented);</pre>
+<pre style="margin: 0px;"><span style="color: green;">// {</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp;  "Member1": 11,</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp;  "Member2": "This value went into the data file during serialization.",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp;  "Member4": null</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">// }</span></pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(obj.Member1);</pre>
+<pre style="margin: 0px;"><span style="color: green;">// 11</span></pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(obj.Member2);</pre>
+<pre style="margin: 0px;"><span style="color: green;">// This value was reset after serialization.</span></pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(obj.Member3);</pre>
+<pre style="margin: 0px;"><span style="color: green;">// This is a nonserialized value</span></pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(obj.Member4);</pre>
+<pre style="margin: 0px;"><span style="color: green;">// null</span></pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;">obj = <span style="color: #2b91af;">JsonConvert</span>.DeserializeObject&lt;<span style="color: #2b91af;">SerializationEventTestObject</span>&gt;(json);</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(obj.Member1);</pre>
+<pre style="margin: 0px;"><span style="color: green;">// 11</span></pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(obj.Member2);</pre>
+<pre style="margin: 0px;"><span style="color: green;">// This value went into the data file during serialization.</span></pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(obj.Member3);</pre>
+<pre style="margin: 0px;"><span style="color: green;">// This value was set during deserialization</span></pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(obj.Member4);</pre>
+<pre style="margin: 0px;"><span style="color: green;">// This value was set after deserialization.</span></pre>
+</div>
+</div></div>
+
+
+      <div id="footer">
+
+
+    
+        </div>      
+    </div>
+
+  </body>
+
+</html>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Doc/SerializationErrorHandling.html b/trunk/Libraries/Json40r2/Source/Doc/SerializationErrorHandling.html
new file mode 100644 (file)
index 0000000..5a50730
--- /dev/null
@@ -0,0 +1,172 @@
+<html>
+  
+  <head>
+    <title>Serialization Error Handling</title>
+    <link href="styles.css" rel="stylesheet" type="text/css" />
+    <link href="custom.css" rel="stylesheet" type="text/css" />
+  </head>
+  
+  <body>
+    
+    <div id="control">
+      <span class="productTitle">Json.NET - Quick Starts & API Documentation</span><br />
+        <span class="topicTitle">Serialization Error Handling</span></div>
+
+    <div id="content">
+      <span style="color: DarkGray"> </span>
+    
+       <p>Json.NET supports error handling during serialization and deserialization. Error handling lets
+       you catch an error and choose whether to handle it and continue with serialization or let the error
+       bubble up and be thrown in your application.</p>
+       <p>Error handling is defined through two methods:
+           the Error event on JsonSerializer and the OnErrorAttribute.</p>
+               <h3>Error Event</h3>
+
+       <p>
+           The <a href="./html/E_Newtonsoft_Json_JsonSerializer_Error.htm">Error</a> event is an event handler found on <a href="./html/T_Newtonsoft_Json_JsonSerializer.htm">JsonSerializer</a>. The error event is raised whenever an
+           exception is thrown while serializing or deserialing JSON. Like all settings found on JsonSerializer
+           it can also be set on <a href="./html/T_Newtonsoft_Json_JsonSerializer.htm">JsonSerializerSettings</a> and passed to the serialization methods on JsonConvert.</p>
+           
+       <div class="overflowpanel"> <div class="code">
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: #2b91af;">List</span>&lt;<span style="color: blue;">string</span>&gt; errors = <span style="color: blue;">new</span> <span style="color: #2b91af;">List</span>&lt;<span style="color: blue;">string</span>&gt;();</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">List</span>&lt;<span style="color: #2b91af;">DateTime</span>&gt; c = <span style="color: #2b91af;">JsonConvert</span>.DeserializeObject&lt;<span style="color: #2b91af;">List</span>&lt;<span style="color: #2b91af;">DateTime</span>&gt;&gt;(<span style="color: #a31515;">@"[</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; ""2009-09-09T00:00:00Z"",</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; ""I am not a date and will error!"",</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; [</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; 1</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; ],</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; ""1977-02-20T00:00:00Z"",</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; null,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; ""2000-12-01T00:00:00Z""</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">]"</span>,</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">new</span> <span style="color: #2b91af;">JsonSerializerSettings</span></pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; {</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; Error = <span style="color: blue;">delegate</span>(<span style="color: blue;">object</span> sender, <span style="color: #2b91af;">ErrorEventArgs</span> args)</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; {</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; errors.Add(args.ErrorContext.Error.Message);</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; args.ErrorContext.Handled = <span style="color: blue;">true</span>;</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; },</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; Converters = { <span style="color: blue;">new</span> <span style="color: #2b91af;">IsoDateTimeConverter</span>() }</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; });</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: green;">// 2009-09-09T00:00:00Z</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">// 1977-02-20T00:00:00Z</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">// 2000-12-01T00:00:00Z</span></pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: green;">// The string was not recognized as a valid DateTime. There is a unknown word starting at index 0.</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">// Unexpected token parsing date. Expected String, got StartArray.</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">// Cannot convert null value to System.DateTime.</span></pre>
+</div>
+</div>
+</div>
+<p>
+    In this example we are deserializing a JSON array to a collection of DateTimes. On the JsonSerializerSettings
+    a handler has been assigned to the Error event which will log the error message and mark the error as handled.
+</p>
+<p>
+    The result of deserializing the JSON is three successfully deserialized dates and three error messages:
+    one for the badly formatted string, "I am not a date and will error!", one for the nested JSON array and one
+    for the null value since the list doesn't allow nullable DateTimes. The event handler has logged these messages
+    and Json.NET has continued on deserializing the JSON because the errors were marked as handled.
+</p>
+<p>
+    One thing to note with error handling in Json.NET is that an unhandled error will bubble up and raise the event
+    on each of its parents, e.g. an unhandled error when serializing a collection of objects will be raised twice,
+    once against the object and then again on the collection. This will let you handle an error either where it
+    occurred or on one of its parents.
+</p>
+
+
+<div class="overflowpanel"> <div class="code">
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: #2b91af;">JsonSerializer</span> serializer = <span style="color: blue;">new</span> <span style="color: #2b91af;">JsonSerializer</span>();</pre>
+<pre style="margin: 0px;">serializer.Error += <span style="color: blue;">delegate</span>(<span style="color: blue;">object</span> sender, <span style="color: #2b91af;">ErrorEventArgs</span> args)</pre>
+<pre style="margin: 0px;">&nbsp; {</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; <span style="color: green;">// only log an error once</span></pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; <span style="color: blue;">if</span> (args.CurrentObject == args.ErrorContext.OriginalObject)</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; errors.Add(args.ErrorContext.Error.Message);</pre>
+<pre style="margin: 0px;">&nbsp; };</pre>
+</div>
+</div></div>
+
+<p>If you aren't immediately handling an error and only want to perform an action against it once then
+you can check to see whether the <a href="./html/T_Newtonsoft_Json_Serialization_ErrorEventArgs.htm">ErrorEventArg</a>'s CurrentObject is equal to the OriginalObject.
+OriginalObject is the object that threw the error and CurrentObject is the object that the event is being raised
+against. They will only equal the first time the event is raised against the OriginalObject.</p>
+           
+               <h3>OnErrorAttribute</h3>
+
+       <p>
+           The <a href="./html/T_Newtonsoft_Json_Serialization_OnErrorAttribute.htm">OnErrorAttribute</a> works much like the other <a href="SerializationCallbacks.html">.NET serialization attributes</a> that Json.NET supports.
+           To use it you simply place the attribute on a method which takes the correct parameters: a StreamingContext and a ErrorContext.
+           The name of the method doesn't matter.      </p>
+       <div class="overflowpanel"> <div class="code">
+
+       <div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">PersonError</span></pre>
+<pre style="margin: 0px;">{</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">private</span> <span style="color: #2b91af;">List</span>&lt;<span style="color: blue;">string</span>&gt; _roles;</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> Name { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">int</span> Age { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: #2b91af;">List</span>&lt;<span style="color: blue;">string</span>&gt; Roles</pre>
+<pre style="margin: 0px;">&nbsp; {</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; <span style="color: blue;">get</span></pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; {</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; <span style="color: blue;">if</span> (_roles == <span style="color: blue;">null</span>)</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">Exception</span>(<span style="color: #a31515;">"Roles not loaded!"</span>);</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; &nbsp; <span style="color: blue;">return</span> _roles;</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; }</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; <span style="color: blue;">set</span> { _roles = <span style="color: blue;">value</span>; }</pre>
+<pre style="margin: 0px;">&nbsp; }</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> Title { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;">&nbsp; [<span style="color: #2b91af;">OnError</span>]</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">internal</span> <span style="color: blue;">void</span> OnError(<span style="color: #2b91af;">StreamingContext</span> context, <span style="color: #2b91af;">ErrorContext</span> errorContext)</pre>
+<pre style="margin: 0px;">&nbsp; {</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; errorContext.Handled = <span style="color: blue;">true</span>;</pre>
+<pre style="margin: 0px;">&nbsp; }</pre>
+<pre style="margin: 0px;">}</pre>
+</div>
+</div></div>
+       <p>
+       In this example accessing the the Roles property will throw an exception when no roles have
+       been set. The HandleError method will set the error when serializing Roles as handled and allow Json.NET to continue
+       serializing the class.
+       </p>
+       
+       <div class="overflowpanel"> <div class="code">
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: #2b91af;">PersonError</span> person = <span style="color: blue;">new</span> <span style="color: #2b91af;">PersonError</span></pre>
+<pre style="margin: 0px;">&nbsp; {</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; Name = <span style="color: #a31515;">"George Michael Bluth"</span>,</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; Age = 16,</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; Roles = <span style="color: blue;">null</span>,</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; Title = <span style="color: #a31515;">"Mister Manager"</span></pre>
+<pre style="margin: 0px;">&nbsp; };</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: blue;">string</span> json = <span style="color: #2b91af;">JsonConvert</span>.SerializeObject(person, <span style="color: #2b91af;">Formatting</span>.Indented);</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(json);</pre>
+<pre style="margin: 0px;"><span style="color: green;">//{</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; "Name": "George Michael Bluth",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; "Age": 16,</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; "Title": "Mister Manager"</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//}</span></pre>
+</div>
+</div></div>
+
+
+      <div id="footer">
+
+
+    
+        </div>      
+    </div>
+
+  </body>
+
+</html>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Doc/SerializingCollections.html b/trunk/Libraries/Json40r2/Source/Doc/SerializingCollections.html
new file mode 100644 (file)
index 0000000..53e59d3
--- /dev/null
@@ -0,0 +1,128 @@
+<html>
+  
+  <head>
+    <title>Serializing Collections</title>
+    <link href="styles.css" rel="stylesheet" type="text/css" />
+    <link href="custom.css" rel="stylesheet" type="text/css" />
+  </head>
+  
+  <body>
+    
+    <div id="control">
+      <span class="productTitle">Json.NET - Quick Starts & API Documentation</span><br />
+        <span class="topicTitle">Serializing Collections</span></div>
+
+    <div id="content">
+      <span style="color: DarkGray"> </span>
+    
+       <p>The <a href="./html/T_Newtonsoft_Json_JsonSerializer.htm">JsonSerializer</a> has 
+        great support for serializing and deserializing collections of objects.</p>
+
+    <h3>Serializing</h3>
+       <p>To serialize a collection - a generic list, array, dictionary, or your own custom collection - simply call the serializer with the object you want to get JSON for.
+       Json.NET will serialize the collection and all of the values it contains.</p>
+
+
+<div class="overflowpanel"> <div class="code">
+
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: #2b91af;">Product</span> p1 = <span style="color: blue;">new</span> <span style="color: #2b91af;">Product</span></pre>
+<pre style="margin: 0px;">&nbsp; {</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; Name = <span style="color: #a31515;">"Product 1"</span>,</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; Price = 99.95m,</pre>
+<pre style="margin: 0px;">&nbsp; &nbsp; ExpiryDate = <span style="color: blue;">new</span> <span style="color: #2b91af;">DateTime</span>(2000, 12, 29, 0, 0, 0, <span style="color: #2b91af;">DateTimeKind</span>.Utc),</pre>
+<pre style="margin: 0px;">&nbsp; };</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Product</span> p2 = <span style="color: blue;">new</span> <span style="color: #2b91af;">Product</span></pre>
+<pre style="margin: 0px;">{</pre>
+<pre style="margin: 0px;">&nbsp; Name = <span style="color: #a31515;">"Product 2"</span>,</pre>
+<pre style="margin: 0px;">&nbsp; Price = 12.50m,</pre>
+<pre style="margin: 0px;">&nbsp; ExpiryDate = <span style="color: blue;">new</span> <span style="color: #2b91af;">DateTime</span>(2009, 7, 31, 0, 0, 0, <span style="color: #2b91af;">DateTimeKind</span>.Utc),</pre>
+<pre style="margin: 0px;">};</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">List</span>&lt;<span style="color: #2b91af;">Product</span>&gt; products = <span style="color: blue;">new</span> <span style="color: #2b91af;">List</span>&lt;<span style="color: #2b91af;">Product</span>&gt;();</pre>
+<pre style="margin: 0px;">products.Add(p1);</pre>
+<pre style="margin: 0px;">products.Add(p2);</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: blue;">string</span> json = <span style="color: #2b91af;">JsonConvert</span>.SerializeObject(products, <span style="color: #2b91af;">Formatting</span>.Indented);</pre>
+<pre style="margin: 0px;"><span style="color: green;">//[</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; {</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "Name": "Product 1",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "ExpiryDate": "\/Date(978048000000)\/",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "Price": 99.95,</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "Sizes": null</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; },</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; {</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "Name": "Product 2",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "ExpiryDate": "\/Date(1248998400000)\/",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "Price": 12.50,</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "Sizes": null</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; }</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//]</span></pre>
+</div>
+
+</div></div>
+
+    <h3>Deserializing</h3>
+       <p>To deserialize JSON into a .NET collection just specify the collection type you want to deserialize to. Json.NET supports a wide range of collection types.</p>
+
+<div class="overflowpanel"> <div class="code">
+
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: blue;">string</span> json = <span style="color: #a31515;">@"[</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; {</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; ""Name"": ""Product 1"",</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; ""ExpiryDate"": ""\/Date(978048000000)\/"",</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; ""Price"": 99.95,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; ""Sizes"": null</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; },</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; {</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; ""Name"": ""Product 2"",</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; ""ExpiryDate"": ""\/Date(1248998400000)\/"",</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; ""Price"": 12.50,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; ""Sizes"": null</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; }</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">]"</span>;</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">List</span>&lt;<span style="color: #2b91af;">Product</span>&gt; products = <span style="color: #2b91af;">JsonConvert</span>.DeserializeObject&lt;<span style="color: #2b91af;">List</span>&lt;<span style="color: #2b91af;">Product</span>&gt;&gt;(json);</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(products.Count);</pre>
+<pre style="margin: 0px;"><span style="color: green;">// 2</span></pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Product</span> p1 = products[0];</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(p1.Name);</pre>
+<pre style="margin: 0px;"><span style="color: green;">// Product 1</span></pre>
+</div>
+
+</div></div>
+
+    <h3>Deserializing Dictionaries</h3>
+
+<p>Using Json.NET you can also deserialize a JSON object into a .NET generic dictionary. The JSON object's property names and values will be added to the dictionary.</p>
+
+<div class="overflowpanel"> <div class="code">
+
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: blue;">string</span> json = <span style="color: #a31515;">@"{""key1"":""value1"",""key2"":""value2""}"</span>;</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Dictionary</span>&lt;<span style="color: blue;">string</span>, <span style="color: blue;">string</span>&gt; values = <span style="color: #2b91af;">JsonConvert</span>.DeserializeObject&lt;<span style="color: #2b91af;">Dictionary</span>&lt;<span style="color: blue;">string</span>, <span style="color: blue;">string</span>&gt;&gt;(json);</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(values.Count);</pre>
+<pre style="margin: 0px;"><span style="color: green;">// 2</span></pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Console</span>.WriteLine(values[<span style="color: #a31515;">"key1"</span>]);</pre>
+<pre style="margin: 0px;"><span style="color: green;">// value1</span></pre>
+</div>
+
+</div></div>
+    
+      <div id="footer">
+
+
+    
+        </div>      
+    </div>
+
+  </body>
+
+</html>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Doc/SerializingJSON.html b/trunk/Libraries/Json40r2/Source/Doc/SerializingJSON.html
new file mode 100644 (file)
index 0000000..b08e870
--- /dev/null
@@ -0,0 +1,146 @@
+<html>
+  
+  <head>
+    <title>Serializing and deserializing JSON</title>
+    <link href="styles.css" rel="stylesheet" type="text/css" />
+    <link href="custom.css" rel="stylesheet" type="text/css" />
+  </head>
+  
+  <body>
+    
+    <div id="control">
+      <span class="productTitle">Json.NET - Quick Starts & API Documentation</span><br />
+        <span class="topicTitle">Serializing and deserializing JSON</span></div>
+
+    <div id="content">
+      <span style="color: DarkGray"> </span>
+    
+       <p>The quickest method of converting between JSON text and a .NET object is using 
+        the <a href="./html/T_Newtonsoft_Json_JsonSerializer.htm">JsonSerializer</a>. The JsonSerializer converts .NET objects into their JSON 
+        equivalent and back again.</p>
+
+
+       <p>For simple scenarios where you want to convert to and from a JSON string the <a href="./html/Overload_Newtonsoft_Json_JsonConvert_SerializeObject.htm">SerializeObject</a> and <a href="./html/Overload_Newtonsoft_Json_JsonConvert_DeserializeObject.htm">DeserializeObject</a> methods on <a href="./html/T_Newtonsoft_Json_JsonConvert.htm">JsonConvert</a> provide an easy to use wrapper over 
+        JsonSerializer.</p>
+
+
+<div class="overflowpanel"> <div class="code">
+
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: #2b91af;">Product</span> product = <span style="color: blue;">new</span> <span style="color: #2b91af;">Product</span>();</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;">product.Name = <span style="color: #a31515;">"Apple"</span>;</pre>
+<pre style="margin: 0px;">product.Expiry = <span style="color: blue;">new</span> <span style="color: #2b91af;">DateTime</span>(2008, 12, 28);</pre>
+<pre style="margin: 0px;">product.Price = 3.99M;</pre>
+<pre style="margin: 0px;">product.Sizes = <span style="color: blue;">new</span> <span style="color: blue;">string</span>[] { <span style="color: #a31515;">"Small"</span>, <span style="color: #a31515;">"Medium"</span>, <span style="color: #a31515;">"Large"</span> };</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: blue;">string</span> output = <span style="color: #2b91af;">JsonConvert</span>.SerializeObject(product);</pre>
+<pre style="margin: 0px;"><span style="color: green;">//{</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; "Name": "Apple",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; "Expiry": &quot;\/Date(1230375600000+1300)\/&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; "Price": 3.99,</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; "Sizes": [</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "Small",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "Medium",</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; &nbsp; "Large"</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//&nbsp; ]</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">//}</span></pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">Product</span> deserializedProduct = <span style="color: #2b91af;">JsonConvert</span>.DeserializeObject&lt;<span style="color: #2b91af;">Product</span>&gt;(output);</pre>
+</div>
+
+</div></div>
+
+       <h3>JsonSerializer</h3>
+
+
+       <p>For more control over how an object is serialized the JsonSerializer can be used 
+        directly. The JsonSerializer is able to read and write JSON text directly to 
+        a stream via <a href="./html/T_Newtonsoft_Json_JsonTextReader.htm">JsonTextReader</a> and <a href="./html/T_Newtonsoft_Json_JsonTextWriter.htm">JsonTextWriter</a>. Other kinds of JsonWriters can 
+        also be used such as <a href="./html/T_Newtonsoft_Json_Linq_JTokenReader.htm">JTokenReader</a>/<a href="./html/T_Newtonsoft_Json_Linq_JTokenWriter.htm">JTokenWriter</a> to 
+        convert your object to and 
+        from LINQ to JSON objects or <a href="./html/T_Newtonsoft_Json_Bson_BsonReader.htm">BsonReader</a>/<a href="./html/T_Newtonsoft_Json_Bson_BsonWriter.htm">BsonWriter</a> to convert to and from BSON.</p>
+
+<div class="overflowpanel"> <div class="code">
+
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: #2b91af;">Product</span> product = <span style="color: blue;">new</span> <span style="color: #2b91af;">Product</span>();</pre>
+<pre style="margin: 0px;">product.Expiry = <span style="color: blue;">new</span> <span style="color: #2b91af;">DateTime</span>(2008, 12, 28);</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">JsonSerializer</span> serializer = <span style="color: blue;">new</span> <span style="color: #2b91af;">JsonSerializer</span>();</pre>
+<pre style="margin: 0px;">serializer.Converters.Add(<span style="color: blue;">new</span> <span style="color: #2b91af;">JavaScriptDateTimeConverter</span>());</pre>
+<pre style="margin: 0px;">serializer.NullValueHandling = <span style="color: #2b91af;">NullValueHandling</span>.Ignore;</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: blue;">using</span> (<span style="color: #2b91af;">StreamWriter</span> sw = <span style="color: blue;">new</span> <span style="color: #2b91af;">StreamWriter</span>(<span style="color: #a31515;">@"c:\json.txt"</span>))</pre>
+<pre style="margin: 0px;"><span style="color: blue;">using</span> (<span style="color: #2b91af;">JsonWriter</span> writer = <span style="color: blue;">new</span> <span style="color: #2b91af;">JsonTextWriter</span>(sw))</pre>
+<pre style="margin: 0px;">{</pre>
+<pre style="margin: 0px;">&nbsp; serializer.Serialize(writer, product);</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: green;">// {"Expiry":new Date(1230375600000),"Price":0}</span></pre>
+<pre style="margin: 0px;">}</pre>
+</div>
+
+</div></div>
+<p>JsonSerializer has a number of properties on it to customize how it serializes JSON. 
+    These can also be used with the methods on JsonConvert via the 
+    JsonSerializerSettings overloads.</p>
+
+<h5>ReferenceLoopHandling</h5>
+<p>Controls how circular referencing objects are serialized. Error, ignore or 
+    serialize.</p>
+    <h5>MissingMemberHandling</h5>
+<p>Controls how missing members (e.g. JSON contains a property that isn&#39;t a member 
+    on the object) are handled during deserialization. Ignore or error.</p>
+    <h5>NullValueHandling</h5>
+<p>Controls how null values are handled during serialization and deserialization. 
+    Include or ignore.</p>
+<h5>DefaultValueHandling</h5>
+<p>Controls whether a value will be written to JSON or not if it matches the value specified in
+the member's DefaultValueAttribute. Include or ignore.</p>
+    <h5>ObjectCreationHandling</h5>
+<p>Controls how objects are created during deserialization. Auto, reuse, replace.</p>
+    <h5>TypeNameHandling</h5>
+<p>Controls whether .NET type names are included in serialized JSON and read during deserialization when creating objects. None, Objects, Arrays or All.</p>
+    <h5>ConstructorHandling</h5>
+<p>Controls how constructors are used when initializing objects during deserialization. Default or AllowNonPublicDefaultConstructor.</p>
+    <h5>Converters</h5>
+<p>A collection of JsonConverters that will be used during serialization and 
+    deserialization.</p>
+
+
+    <h3>JsonConverters</h3>
+<p>JsonConverters allows JSON to be manually written during serialization and read during deserialization. This is useful for particularly complex JSON structures or for when you want to change how a type is serialized.</p>
+<p>To create your own custom converter inherit from the JsonConverter class. Json.NET also comes with a number of JsonConverters:</p>
+
+
+
+       <h5>DateTime JSON Converters</h5>
+       <p>Json.NET comes with a number of JsonConverters for serializing and deserializing DateTimes. Read 
+        more about dates and Json.NET <a href="DatesInJSON.html">here</a>.</p>
+
+       <h5>XmlNodeConverter</h5>
+       <p>Converts an XmlNode to and from JSON. Note that to convert a JSON object it must have only a single property 
+        or you must define a root node name to be inserted when using this converter. This is required because properties are converted into nodes and 
+        well formed XML can only have one root node. XmlNodeConverter has an option to 
+        insert a root node for you.</p>
+
+    
+       <h5>BinaryConverter</h5>
+       <p>Converts binary data like the SqlBinary object to JSON. The binary 
+        data is written as a string in JSON and is encoded in Base64.</p>
+
+       <h5>CustomCreationConverter</h5>
+       <p>An abstract JsonConverter for customizing how an object is create during deserialization.
+        Inherit from this class and implement the Create method with your own code to create and return an object.
+        The object will then be populated with JSON values by the serializer.</p>
+        <p>A possible example of using this converter would be to call out to a dependency injection framework to resolve what object should be created.</p>
+    
+      <div id="footer">
+
+
+    
+        </div>      
+    </div>
+
+  </body>
+
+</html>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Doc/SerializingJSONFragments.html b/trunk/Libraries/Json40r2/Source/Doc/SerializingJSONFragments.html
new file mode 100644 (file)
index 0000000..dca923f
--- /dev/null
@@ -0,0 +1,125 @@
+<html>
+  
+  <head>
+    <title>Serializing Partial JSON Fragments</title>
+    <link href="styles.css" rel="stylesheet" type="text/css" />
+    <link href="custom.css" rel="stylesheet" type="text/css" />
+  </head>
+  
+  <body>
+    
+    <div id="control">
+      <span class="productTitle">Json.NET - Quick Starts & API Documentation</span><br />
+        <span class="topicTitle">Serializing Partial JSON Fragments</span></div>
+
+    <div id="content">
+      <span style="color: DarkGray"> </span>
+        <p>Often when working with large JSON documents you're only interested in a small fragment of information.
+            This scenario can be annoying when you want to serialize that Json.NET into .NET 
+            objects because you have to define .NET classes for the entire JSON result.</p>
+        <p>With Json.NET it is easy to get around this problem. Using LINQ to JSON you can 
+            extract the pieces of JSON you want to serialize before passing them to the Json.NET serializer.</p>
+
+<div class="overflowpanel">
+  <div class="code">
+
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">SearchResult</span></pre>
+<pre style="margin: 0px;">{</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> Title { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> Content { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">string</span> Url { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }</pre>
+<pre style="margin: 0px;">}</pre>
+</div>
+
+  </div>
+</div>
+
+<div class="overflowpanel">
+  <div class="code">
+  
+<div style="font-family: Courier New; font-size: 10pt; color: black;">
+<pre style="margin: 0px;"><span style="color: blue;">string</span> googleSearchText = <span style="color: #a31515;">@&quot;{</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &quot;&quot;responseData&quot;&quot;: {</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &quot;&quot;results&quot;&quot;: [</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; {</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;GsearchResultClass&quot;&quot;: &quot;&quot;GwebSearch&quot;&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;unescapedUrl&quot;&quot;: &quot;&quot;http://en.wikipedia.org/wiki/Paris_Hilton&quot;&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;url&quot;&quot;: &quot;&quot;http://en.wikipedia.org/wiki/Paris_Hilton&quot;&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;visibleUrl&quot;&quot;: &quot;&quot;en.wikipedia.org&quot;&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;cacheUrl&quot;&quot;: &quot;&quot;http://www.google.com/search?q=cache:TwrPfhd22hYJ:en.wikipedia.org&quot;&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;title&quot;&quot;: &quot;&quot;&lt;b&gt;Paris Hilton&lt;/b&gt; - Wikipedia, the free encyclopedia&quot;&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;titleNoFormatting&quot;&quot;: &quot;&quot;Paris Hilton - Wikipedia, the free encyclopedia&quot;&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;content&quot;&quot;: &quot;&quot;[1] In 2006, she released her debut album...&quot;&quot;</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; },</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; {</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;GsearchResultClass&quot;&quot;: &quot;&quot;GwebSearch&quot;&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;unescapedUrl&quot;&quot;: &quot;&quot;http://www.imdb.com/name/nm0385296/&quot;&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;url&quot;&quot;: &quot;&quot;http://www.imdb.com/name/nm0385296/&quot;&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;visibleUrl&quot;&quot;: &quot;&quot;www.imdb.com&quot;&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;cacheUrl&quot;&quot;: &quot;&quot;http://www.google.com/search?q=cache:1i34KkqnsooJ:www.imdb.com&quot;&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;title&quot;&quot;: &quot;&quot;&lt;b&gt;Paris Hilton&lt;/b&gt;&quot;&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;titleNoFormatting&quot;&quot;: &quot;&quot;Paris Hilton&quot;&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;content&quot;&quot;: &quot;&quot;Self: Zoolander. Socialite &lt;b&gt;Paris Hilton&lt;/b&gt;...&quot;&quot;</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; }</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; ],</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &quot;&quot;cursor&quot;&quot;: {</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &quot;&quot;pages&quot;&quot;: [</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; {</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;start&quot;&quot;: &quot;&quot;0&quot;&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;label&quot;&quot;: 1</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; },</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; {</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;start&quot;&quot;: &quot;&quot;4&quot;&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;label&quot;&quot;: 2</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; },</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; {</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;start&quot;&quot;: &quot;&quot;8&quot;&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;label&quot;&quot;: 3</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; },</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; {</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;start&quot;&quot;: &quot;&quot;12&quot;&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;label&quot;&quot;: 4</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &nbsp; }</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; ],</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &quot;&quot;estimatedResultCount&quot;&quot;: &quot;&quot;59600000&quot;&quot;,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &quot;&quot;currentPageIndex&quot;&quot;: 0,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; &nbsp; &quot;&quot;moreResultsUrl&quot;&quot;: &quot;&quot;http://www.google.com/search?oe=utf8&amp;ie=utf8...&quot;&quot;</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &nbsp; }</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; },</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &quot;&quot;responseDetails&quot;&quot;: null,</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">&nbsp; &quot;&quot;responseStatus&quot;&quot;: 200</span></pre>
+<pre style="margin: 0px;"><span style="color: #a31515;">}&quot;</span>;</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">JObject</span> googleSearch = <span style="color: #2b91af;">JObject</span>.Parse(googleSearchText);</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: green;">// get JSON result objects into a list</span></pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">IList</span>&lt;<span style="color: #2b91af;">JToken</span>&gt; results = googleSearch[<span style="color: #a31515;">&quot;responseData&quot;</span>][<span style="color: #a31515;">&quot;results&quot;</span>].Children().ToList();</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: green;">// serialize JSON results into .NET objects</span></pre>
+<pre style="margin: 0px;"><span style="color: #2b91af;">IList</span>&lt;<span style="color: #2b91af;">SearchResult</span>&gt; searchResults = <span style="color: blue;">new</span> <span style="color: #2b91af;">List</span>&lt;<span style="color: #2b91af;">SearchResult</span>&gt;();</pre>
+<pre style="margin: 0px;"><span style="color: blue;">foreach</span> (<span style="color: #2b91af;">JToken</span> result <span style="color: blue;">in</span> results)</pre>
+<pre style="margin: 0px;">{</pre>
+<pre style="margin: 0px;">&nbsp; <span style="color: #2b91af;">SearchResult</span> searchResult = <span style="color: #2b91af;">JsonConvert</span>.DeserializeObject&lt;<span style="color: #2b91af;">SearchResult</span>&gt;(result.ToString());</pre>
+<pre style="margin: 0px;">&nbsp; searchResults.Add(searchResult);</pre>
+<pre style="margin: 0px;">}</pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: green;">// Title = &lt;b&gt;Paris Hilton&lt;/b&gt; - Wikipedia, the free encyclopedia</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">// Content = [1] In 2006, she released her debut album...</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">// Url = http://en.wikipedia.org/wiki/Paris_Hilton</span></pre>
+<pre style="margin: 0px;">&nbsp;</pre>
+<pre style="margin: 0px;"><span style="color: green;">// Title = &lt;b&gt;Paris Hilton&lt;/b&gt;</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">// Content = Self: Zoolander. Socialite &lt;b&gt;Paris Hilton&lt;/b&gt;...</span></pre>
+<pre style="margin: 0px;"><span style="color: green;">// Url = http://www.imdb.com/name/nm0385296/</span></pre>
+</div>
+
+
+</div>
+  </div>
+
+      <div id="footer"></div>      
+    </div>
+
+  </body>
+
+</html>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Doc/custom.css b/trunk/Libraries/Json40r2/Source/Doc/custom.css
new file mode 100644 (file)
index 0000000..3bcd480
--- /dev/null
@@ -0,0 +1,19 @@
+div#content {
+       padding: 0 10px 10px 10px;
+}
+
+.overflowpanel
+{
+       width: 98%;
+       border: solid 1px #ccc;
+       overflow: auto;
+       overflow-y: hidden;
+       background-color: #fcfcfc;
+       margin-bottom: 1em;
+}
+
+.overflowpanel .code
+{
+       padding: 10px 4px 20px 10px;
+       display: block;
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Doc/doc.shfbproj b/trunk/Libraries/Json40r2/Source/Doc/doc.shfbproj
new file mode 100644 (file)
index 0000000..84f6d68
--- /dev/null
@@ -0,0 +1,87 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+  <PropertyGroup>
+    <!-- The configuration and platform will be used to determine which
+         assemblies to include from solution and project documentation
+         sources -->
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{fd19f68e-72c8-4576-9775-b4480b0db686}</ProjectGuid>
+    <SHFBSchemaVersion>1.9.0.0</SHFBSchemaVersion>
+    <!-- AssemblyName, Name, and RootNamespace are not used by SHFB but Visual
+         Studio adds them anyway -->
+    <AssemblyName>Documentation</AssemblyName>
+    <RootNamespace>Documentation</RootNamespace>
+    <Name>Documentation</Name>
+    <!-- SHFB properties -->
+    <OutputPath>..\Working\Documentation\</OutputPath>
+    <HtmlHelpName>Documentation</HtmlHelpName>
+    <ProjectSummary>
+    </ProjectSummary>
+    <MissingTags>Summary, Parameter, Returns, AutoDocumentCtors, Namespace, TypeParameter</MissingTags>
+    <VisibleItems>InheritedMembers, InheritedFrameworkMembers, Protected, SealedProtected</VisibleItems>
+    <HtmlHelp1xCompilerPath>
+    </HtmlHelp1xCompilerPath>
+    <HtmlHelp2xCompilerPath>
+    </HtmlHelp2xCompilerPath>
+    <SandcastlePath>
+    </SandcastlePath>
+    <WorkingPath>
+    </WorkingPath>
+    <BuildLogFile>
+    </BuildLogFile>
+    <HelpFileFormat>HtmlHelp1, MSHelpViewer, Website</HelpFileFormat>
+    <FrameworkVersion>3.5</FrameworkVersion>
+    <HelpTitle>Json.NET - Quick Starts &amp;amp%3b API Documentation</HelpTitle>
+    <PresentationStyle>Prototype</PresentationStyle>
+    <NamingMethod>MemberName</NamingMethod>
+    <DocumentationSourcePath>..\Src\Newtonsoft.Json\bin\Release</DocumentationSourcePath>
+    <DocumentationSources>
+      <DocumentationSource sourceFile="$(DocumentationSourcePath)\Newtonsoft.Json.dll" />
+      <DocumentationSource sourceFile="$(DocumentationSourcePath)\Newtonsoft.Json.xml" />
+    </DocumentationSources>
+    <NamespaceSummaries>
+      <NamespaceSummaryItem name="(global)" isDocumented="False" />
+      <NamespaceSummaryItem name="Newtonsoft.Json" isDocumented="True">The &lt;b&gt;Newtonsoft.Json&lt;/b&gt; namespace provides classes that are used to implement the core services of the framework.</NamespaceSummaryItem>
+      <NamespaceSummaryItem name="Newtonsoft.Json.Converters" isDocumented="True">The &lt;b&gt;Newtonsoft.Json.Converters&lt;/b&gt; namespace provides classes that inherit from &lt;a href="T_Newtonsoft_Json_JsonConverter.htm"&gt;JsonConverter&lt;/a&gt;.</NamespaceSummaryItem>
+      <NamespaceSummaryItem name="Newtonsoft.Json.Linq" isDocumented="True">The &lt;b&gt;Newtonsoft.Json.Linq&lt;/b&gt; namespace provides classes that are used to implement LINQ to JSON.</NamespaceSummaryItem>
+      <NamespaceSummaryItem name="Newtonsoft.Json.Linq.ComponentModel" isDocumented="True">The &lt;b&gt;Newtonsoft.Json.Linq.ComponentModel&lt;/b&gt; namespace provides classes for LINQ to JSON databinding.</NamespaceSummaryItem>
+      <NamespaceSummaryItem name="Newtonsoft.Json.Schema" isDocumented="True">The &lt;b&gt;Newtonsoft.Json.Schema&lt;/b&gt; namespace provides classes that are used to implement JSON schema.</NamespaceSummaryItem>
+      <NamespaceSummaryItem name="Newtonsoft.Json.Serialization" isDocumented="True">The &lt;b&gt;Newtonsoft.Json.Linq&lt;/b&gt; namespace provides classes that are used when serializing and deserializing JSON.</NamespaceSummaryItem>
+      <NamespaceSummaryItem name="Newtonsoft.Json.Utilities" isDocumented="False" />
+      <NamespaceSummaryItem name="Newtonsoft.Json.Bson" isDocumented="True">The &lt;b&gt;Newtonsoft.Json.Linq&lt;/b&gt; namespace provides classes that are used to implement BSON.</NamespaceSummaryItem>
+    </NamespaceSummaries>
+  </PropertyGroup>
+  <!-- There are no properties for these two groups but they need to appear in
+       order for Visual Studio to perform the build. -->
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+  </PropertyGroup>
+  <ItemGroup>
+    <SiteMap Include="doc.sitemap" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="CustomCreationConverter.html" />
+    <Content Include="ContractResolver.html" />
+    <Content Include="custom.css" />
+    <Content Include="ConvertingJSONandXML.html" />
+    <Content Include="SerializingJSONFragments.html" />
+    <Content Include="SelectToken.html" />
+    <Content Include="ReducingSerializedJSONSize.html" />
+    <Content Include="donate.gif" />
+    <Content Include="styles.css" />
+    <Content Include="ReadingWritingJSON.html" />
+    <Content Include="LINQtoJSON.html" />
+    <Content Include="PreserveObjectReferences.html" />
+    <Content Include="SerializationErrorHandling.html" />
+    <Content Include="SerializationCallbacks.html" />
+    <Content Include="SerializingCollections.html" />
+    <Content Include="DatesInJSON.html" />
+    <Content Include="SerializationAttributes.html" />
+    <Content Include="SerializingJSON.html" />
+    <Content Include="Introduction.html" />
+  </ItemGroup>
+  <!-- Import the SHFB build targets -->
+  <Import Project="$(SHFBROOT)\SandcastleHelpFileBuilder.targets" />
+</Project>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Doc/doc.sitemap b/trunk/Libraries/Json40r2/Source/Doc/doc.sitemap
new file mode 100644 (file)
index 0000000..996625e
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0">
+  <siteMapNode title="Introduction" url="Introduction.html" isDefault="true" />
+  <siteMapNode title="Serializing and deserializing JSON" url="SerializingJSON.html">
+    <siteMapNode title="Customizing JSON serialization with attributes" url="SerializationAttributes.html" />
+    <siteMapNode title="Serializing Dates in JSON" url="DatesInJSON.html" />
+    <siteMapNode title="Serializing Collections" url="SerializingCollections.html" />
+    <siteMapNode title="Serialization Callbacks" url="SerializationCallbacks.html" />
+    <siteMapNode title="Serialization Error Handling" url="SerializationErrorHandling.html" />
+    <siteMapNode title="Serialization and Preserving Object References" url="PreserveObjectReferences.html" />
+    <siteMapNode title="CustomCreationConverter" url="CustomCreationConverter.html" />
+    <siteMapNode title="Contract Resolvers" url="ContractResolver.html" />
+    <siteMapNode title="Reducing Serialized JSON Size" url="ReducingSerializedJSONSize.html" />
+    <siteMapNode title="Serializing Partial JSON Fragments" url="SerializingJSONFragments.html" />
+  </siteMapNode>
+  <siteMapNode title="LINQ to JSON" url="LINQtoJSON.html">
+    <siteMapNode title="Querying LINQ to JSON with SelectToken" url="SelectToken.html" />
+  </siteMapNode>
+  <siteMapNode title="Reading and writing JSON" url="ReadingWritingJSON.html" />
+  <siteMapNode title="Converting between JSON and XML" url="ConvertingJSONandXML.html" />
+</siteMap>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Doc/donate.gif b/trunk/Libraries/Json40r2/Source/Doc/donate.gif
new file mode 100644 (file)
index 0000000..d017250
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Doc/donate.gif differ
diff --git a/trunk/Libraries/Json40r2/Source/Doc/readme.txt b/trunk/Libraries/Json40r2/Source/Doc/readme.txt
new file mode 100644 (file)
index 0000000..ca85148
--- /dev/null
@@ -0,0 +1,59 @@
+Json.NET
+
+http://james.newtonking.com/projects/json-net.aspx
+http://www.codeplex.com/json/
+
+
+Description:
+
+Json.NET makes working with JSON formatted data in .NET simple. Quickly read and write JSON using LINQ to JSON or serialize your .NET objects with a single method call using the JsonSerializer.
+
+-Flexible JSON serializer to convert .NET objects to JSON and back again 
+-LINQ to JSON for reading and writing JSON 
+-Writes indented, easy to read JSON 
+-Convert JSON to and from XML 
+-Supports Silverlight and Windows Phone
+
+
+
+Versions:
+
+Json.NET comes in different versions for the various .NET frameworks.
+
+-DotNet:
+  .NET latest (4.0)
+
+-DotNet35:
+  .NET 3.5 SP1, Mono
+
+-DotNet20:
+  .NET 2.0
+
+-Silverlight:
+  Silverlight 4.0
+
+-WindowsPhone:
+  Windows Phone 7
+
+Microsoft stopped support for the Compact Framework in Visual Studio 2010.
+For a Compact Framework 3.5 build download Json.NET 3.5.
+
+For a Silverlight 3.0 build down download Json.NET 3.5.
+
+
+Instructions:
+
+ 1. Extract Newtonsoft.Json.dll and Newtonsoft.Json.xml from the archive's /bin directory into your own applications.
+ 2. Add a reference to Newtonsoft.Json.dll within Visual Studio.NET to your project.
+
+
+
+License:
+
+Copyright (c) 2007 James Newton-King
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Doc/styles.css b/trunk/Libraries/Json40r2/Source/Doc/styles.css
new file mode 100644 (file)
index 0000000..47278fb
--- /dev/null
@@ -0,0 +1,439 @@
+/* page style */
+
+body {
+       margin: 0;
+       background-color: #FFFFFF;
+       padding: 0;
+       font-size: 8.5pt;
+       font-family: verdana, arial, sans-serif;
+       color: #000000;
+}
+
+html>body {
+       margin: 0;
+       background-color: #FFFFFF;
+       padding: 0;
+       font-size: 8.5pt;
+       font-family: verdana, arial, sans-serif;
+       color: #000000;
+       overflow: auto;
+}
+
+table {
+       /* this is a trick to force tables to inherit the body font size */
+       font-size: 100%;
+}
+
+/* non-scrolling (control) region style */
+
+div#control {
+       margin: 0;
+       background-color: #D4DFFF;
+       padding: 4px;
+       width: 100%;
+       border-bottom-color: #C8CDDE;
+       border-bottom-style: solid;
+       border-bottom-width: 1px;
+       z-index: 2;
+}
+
+span.productTitle {
+       font-size: 80%;
+}
+
+span.topicTitle {
+       font-size: 140%;
+       font-weight: bold;
+       color: #003399;
+}
+
+span#chickenFeet {
+       float: left;
+}
+
+span#languageFilter {
+       float: right;
+       height: 1px;
+       max-height: 1px;
+       vertical-align: bottom;
+       overflow: visible;
+}
+
+/* scrolling (content) region style */
+
+div#main
+{
+       clear: both;
+       margin: 0;
+       padding: 1em;
+       width: 100%;
+       z-index: 1;
+    overflow: auto;
+}
+
+/* sections */
+
+div#header {
+       font-size: 80%;
+       color: #666666;
+       margin-bottom: 0.5em;
+}
+
+div.summary {
+       margin-top: 0em;
+       margin-bottom: 1em;
+}
+
+div.section {
+       margin-bottom: 1em;
+}
+
+div.sectionTitle {
+       display: inline;
+       font-size: 120%;
+       font-weight: bold;
+       color: #003399;
+}
+
+div.sectionContent {
+       margin-top: 0.2em;
+}
+
+span.subsectionTitle {
+       font-weight: bold;
+}
+
+div#footer {
+       margin-top: 1em;
+       border-top: thin solid #003399;
+       padding-top: 0.5em;
+}
+
+div#footer p {
+       margin-top: 0.2em;
+       margin-bottom: 0.2em;
+}
+
+/* authored content (block) */
+
+p {
+       margin-top: 1em;
+       margin-bottom: 1em;
+}
+
+dl, ul, ol {
+       margin-top: 0.5em;
+       margin-bottom: 0.5em;
+}
+
+pre {
+       margin: 0;
+       padding: 0;
+       font-family: "Andale Mono", "Courier New", Courier, monospace;
+}
+
+table.authoredTable {
+       table-layout: fixed;
+       width: 100%;
+       margin-bottom: 1em;
+}
+
+table.authoredTable th {
+       border-bottom-color: #C8CDDE;
+       border-bottom-style: solid;
+       border-bottom-width: 1px;
+       background: #EFEFF7;
+       padding: 0.2em;
+       text-align: left;
+       color: #000066;
+       font-weight: bold;
+}
+
+table.authoredTable td {
+       border-bottom-style: solid;
+       border-bottom-color: #C8CDDE;
+       border-bottom-width: 1px;
+       background: #F7F7FF;
+       padding: 0.2em;
+       vertical-align: top;
+}
+
+div.alert {
+       border: 1px solid #C8CDDE;
+       background: #F7F7FF;
+}
+
+div.media {
+       text-align: center;
+       margin-bottom: 1em;
+}
+
+
+/* authored content (inline) */
+
+span.keyword {
+       font-weight: bold;
+}
+
+span.code {
+       font-family: "Andale Mono", "Courier New", Courier, monospace;
+       font-size: 110%;
+       color:  #000066;
+}
+
+/* auto-generated controls */
+
+div.langTabs {
+       /*width: 100%;*/
+}
+
+div.langTab {
+       float: left;
+       width: 15%;
+       border-top: 1px solid #C8CDDE;
+       border-left: 1px solid #C8CDDE;
+       border-right: 1px solid #C8CDDE;
+       background: #F7F7FF;
+       padding: 0.2em;
+       text-align: left;
+       color: #000066;
+       font-weight: normal;
+}
+
+div.activeLangTab {
+       float: left;
+       width: 15%;
+       border-top: 1px solid #C8CDDE;
+       border-left: 1px solid #C8CDDE;
+       border-right: 1px solid #C8CDDE;
+       background: #EFEFF7;
+       padding: 0.2em;
+       text-align: left;
+       color: #000066;
+       font-weight: bold;
+}
+
+table.members {
+       /* table-layout: fixed; */
+       width: 100%;
+}
+
+table.members th.iconColumn {
+       width: 60px;
+}
+
+table.members th.nameColumn {
+       width: 40%;
+}
+
+table.members th.descriptionColumn {
+       width: 60%;
+}
+
+table.members th {
+       border-bottom-color: #C8CDDE;
+       border-bottom-style: solid;
+       border-bottom-width: 1px;
+       background: #EFEFF7;
+       padding: 0.2em;
+       text-align: left;
+       color: #000066;
+       font-weight: bold;
+}
+
+table.members td {
+       border-bottom-style: solid;
+       border-bottom-color: #C8CDDE;
+       border-bottom-width: 1px;
+       background: #F7F7FF;
+       padding: 0.2em;
+       vertical-align: top;
+       overflow: hidden;
+}
+
+table.exceptions {
+       table-layout: fixed;
+       width: 100%;
+}
+
+
+table.exceptions th.exceptionNameColumn {
+       width: 40%;
+}
+
+table.exceptions th.exceptionConditionColumn {
+       width: 60%;
+}
+
+table.exceptions th {
+       border-bottom-color: #C8CDDE;
+       border-bottom-style: solid;
+       border-bottom-width: 1px;
+       background: #EFEFF7;
+       padding: 0.2em;
+       text-align: left;
+       color: #000066;
+       font-weight: bold;
+}
+
+table.exceptions td {
+       border-bottom-style: solid;
+       border-bottom-color: #C8CDDE;
+       border-bottom-width: 1px;
+       background: #F7F7FF;
+       padding: 0.2em;
+       vertical-align: top;
+}
+
+table.permissions {
+       table-layout: fixed;
+       width: 100%;
+}
+
+
+table.permissions th.permissionNameColumn {
+       width: 40%;
+}
+
+table.permissions th.permissionConditionColumn {
+       width: 60%;
+}
+
+table.permissions th {
+       border-bottom-color: #C8CDDE;
+       border-bottom-style: solid;
+       border-bottom-width: 1px;
+       background: #EFEFF7;
+       padding: 0.2em;
+       text-align: left;
+       color: #000066;
+       font-weight: bold;
+}
+
+table.permissions td {
+       border-bottom-style: solid;
+       border-bottom-color: #C8CDDE;
+       border-bottom-width: 1px;
+       background: #F7F7FF;
+       padding: 0.2em;
+       vertical-align: top;
+}
+
+span.obsolete {
+       color: red;
+}
+
+span.cs {
+       display: inline;
+}
+
+span.vb {
+       display: none;
+}
+
+span.cpp {
+       display: none;
+}
+
+span.nu
+{
+       display: none;
+}
+
+/* syntax styling */
+
+div.code span.identifier {
+       font-weight: bold;
+}
+
+div.code span.keyword {
+       color: green;
+}
+
+div.code span.parameter {
+       font-style: italic;
+       color: purple;
+}
+
+div.code span.literal {
+       color: purple;
+}
+
+div.code span.comment {
+       color: red;
+}
+
+span.foreignPhrase {
+       font-style: italic;
+}
+
+span.placeholder {
+       font-style: italic;
+}
+
+span.parameter
+{
+  font-style: italic;
+}
+
+span.typeparameter
+{
+  font-style: italic;
+}
+
+a {
+       color: blue;
+       text-decoration: none;
+}
+
+a:hover {
+       text-decoration: underline;
+}
+
+MSHelp\:link {
+       color: blue;
+       hoverColor: #3366ff;
+}
+
+span.nolink {
+       font-weight: bold;
+}
+
+span.selflink {
+       font-weight: bold;
+}
+
+table.filter {
+       table-layout: fixed;
+}
+
+tr.tabs td.tab {
+       width: 10em;
+       background: #F7F7FF;
+       padding: 0.2em;
+       text-align: left;
+       color: #000066;
+       font-weight: normal;
+       overflow: hidden;
+       cursor: pointer;
+}
+
+tr.tabs td.activeTab {
+       width: 10em;
+       background: #EFEFF7;
+       padding: 0.2em;
+       text-align: left;
+       color: #000066;
+       font-weight: bold;
+       overflow: hidden;
+}
+
+td.line {
+       background: #EFEFF7;
+}
+
+dt {
+       font-weight: bold;
+    margin-top: 10px;
+    margin-left: 10px;
+}
diff --git a/trunk/Libraries/Json40r2/Source/Doc/versions.txt b/trunk/Libraries/Json40r2/Source/Doc/versions.txt
new file mode 100644 (file)
index 0000000..db86a13
--- /dev/null
@@ -0,0 +1,23 @@
+Versions:
+
+Json.NET comes in different versions for the various .NET frameworks.
+
+-DotNet:
+  .NET latest (4.0)
+
+-DotNet35:
+  .NET 3.5 SP1, Mono
+
+-DotNet20:
+  .NET 2.0
+
+-Silverlight:
+  Silverlight 4.0
+
+-WindowsPhone:
+  Windows Phone 7
+
+Microsoft stopped support for the Compact Framework in Visual Studio 2010.
+For a Compact Framework 3.5 build download Json.NET 3.5.
+
+For a Silverlight 3.0 build down download Json.NET 3.5.
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Lib/LinqBridge.dll b/trunk/Libraries/Json40r2/Source/Src/Lib/LinqBridge.dll
new file mode 100644 (file)
index 0000000..305c9bb
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Src/Lib/LinqBridge.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Src/Lib/NUnit/Compact/NUnitLite.dll b/trunk/Libraries/Json40r2/Source/Src/Lib/NUnit/Compact/NUnitLite.dll
new file mode 100644 (file)
index 0000000..2bf1533
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Src/Lib/NUnit/Compact/NUnitLite.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Src/Lib/NUnit/DotNet/nunit.framework.dll b/trunk/Libraries/Json40r2/Source/Src/Lib/NUnit/DotNet/nunit.framework.dll
new file mode 100644 (file)
index 0000000..de687d9
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Src/Lib/NUnit/DotNet/nunit.framework.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Src/Lib/NUnit/DotNet/nunit.framework.xml b/trunk/Libraries/Json40r2/Source/Src/Lib/NUnit/DotNet/nunit.framework.xml
new file mode 100644 (file)
index 0000000..bf4c30c
--- /dev/null
@@ -0,0 +1,5521 @@
+<?xml version="1.0"?>
+<doc>
+    <assembly>
+        <name>nunit.framework</name>
+    </assembly>
+    <members>
+        <member name="T:NUnit.Framework.Constraints.SubstringConstraint">
+            <summary>
+            SubstringConstraint can test whether a string contains
+            the expected substring.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.Constraint">
+            <summary>
+            The Constraint class is the base of all built-in or
+            user-defined constraints in NUnit. It provides the operator
+            overloads used to combine constraints.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.Constraint.UNSET">
+            <summary>
+            Static UnsetObject used to detect derived constraints
+            failing to set the actual value.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.Constraint.caseInsensitive">
+            <summary>
+            If true, all string comparisons will ignore case
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.Constraint.compareAsCollection">
+            <summary>
+            If true, arrays will be treated as collections, allowing
+            those of different dimensions to be compared
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.Constraint.tolerance">
+            <summary>
+            If non-zero, equality comparisons within the specified 
+            tolerance will succeed.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.Constraint.compareWith">
+            <summary>
+            IComparer object used in comparisons for some constraints.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.Constraint.actual">
+            <summary>
+            The actual value being tested against a constraint
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Constraint.Within(System.Object)">
+            <summary>
+            Flag the constraint to use a tolerance when determining equality.
+            Currently only used for doubles and floats.
+            </summary>
+            <param name="tolerance">Tolerance to be used</param>
+            <returns>Self.</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Constraint.Comparer(System.Collections.IComparer)">
+            <summary>
+            Flag the constraint to use the supplied IComparer object.
+            </summary>
+            <param name="comparer">The IComparer object to use.</param>
+            <returns>Self.</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Constraint.WriteMessageTo(NUnit.Framework.MessageWriter)">
+            <summary>
+            Write the failure message to the MessageWriter provided
+            as an argument. The default implementation simply passes
+            the constraint and the actual value to the writer, which
+            then displays the constraint description and the value.
+            
+            Constraints that need to provide additional details,
+            such as where the error occured can override this.
+            </summary>
+            <param name="writer">The MessageWriter on which to display the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Constraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Constraint.WriteDescriptionTo(NUnit.Framework.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Constraint.WriteActualValueTo(NUnit.Framework.MessageWriter)">
+            <summary>
+            Write the actual value for a failing constraint test to a
+            MessageWriter. The default implementation simply writes
+            the raw value of actual, leaving it to the writer to
+            perform any formatting.
+            </summary>
+            <param name="writer">The writer on which the actual value is displayed</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Constraint.op_BitwiseAnd(NUnit.Framework.Constraints.Constraint,NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            This operator creates a constraint that is satisfied only if both 
+            argument constraints are satisfied.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Constraint.op_BitwiseOr(NUnit.Framework.Constraints.Constraint,NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            This operator creates a constraint that is satisfied if either 
+            of the argument constraints is satisfied.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Constraint.op_LogicalNot(NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            This operator creates a constraint that is satisfied if the 
+            argument constraint is not satisfied.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.Constraint.IgnoreCase">
+            <summary>
+            Flag the constraint to ignore case and return self.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.Constraint.AsCollection">
+            <summary>
+            Flag the constraint to compare arrays as collections
+            and return self.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.Constraint.UnsetObject">
+            <summary>
+            Class used to detect any derived constraints
+            that fail to set the actual value in their
+            Matches override.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.SubstringConstraint.#ctor(System.String)">
+            <summary>
+            Initializes a new instance of the <see cref="T:SubstringConstraint"/> class.
+            </summary>
+            <param name="expected">The expected.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.SubstringConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.SubstringConstraint.WriteDescriptionTo(NUnit.Framework.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.StartsWithConstraint">
+            <summary>
+            StartsWithConstraint can test whether a string starts
+            with an expected substring.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.StartsWithConstraint.#ctor(System.String)">
+            <summary>
+            Initializes a new instance of the <see cref="T:StartsWithConstraint"/> class.
+            </summary>
+            <param name="expected">The expected string</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.StartsWithConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is matched by the actual value.
+            This is a template method, which calls the IsMatch method
+            of the derived class.
+            </summary>
+            <param name="actual"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.StartsWithConstraint.WriteDescriptionTo(NUnit.Framework.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.EndsWithConstraint">
+            <summary>
+            EndsWithConstraint can test whether a string ends
+            with an expected substring.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EndsWithConstraint.#ctor(System.String)">
+            <summary>
+            Initializes a new instance of the <see cref="T:EndsWithConstraint"/> class.
+            </summary>
+            <param name="expected">The expected string</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EndsWithConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is matched by the actual value.
+            This is a template method, which calls the IsMatch method
+            of the derived class.
+            </summary>
+            <param name="actual"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EndsWithConstraint.WriteDescriptionTo(NUnit.Framework.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.RegexConstraint">
+            <summary>
+            RegexConstraint can test whether a string matches
+            the pattern provided.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.RegexConstraint.#ctor(System.String)">
+            <summary>
+            Initializes a new instance of the <see cref="T:RegexConstraint"/> class.
+            </summary>
+            <param name="pattern">The pattern.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.RegexConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.RegexConstraint.WriteDescriptionTo(NUnit.Framework.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.EmptyConstraint">
+            <summary>
+            EmptyConstraint tests a whether a string or collection is empty,
+            postponing the decision about which test is applied until the
+            type of the actual argument is known.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EmptyConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EmptyConstraint.WriteDescriptionTo(NUnit.Framework.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.ConstraintBuilder">
+            <summary>
+            ConstraintBuilder is used to resolve the Not and All properties,
+            which serve as prefix operators for constraints. With the addition
+            of an operand stack, And and Or could be supported, but we have
+            left them out in favor of a simpler, more type-safe implementation.
+            Use the &amp; and | operator overloads to combine constraints.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.op_Implicit(NUnit.Framework.Constraints.ConstraintBuilder)~NUnit.Framework.Constraints.Constraint">
+            <summary>
+            Implicitly convert ConstraintBuilder to an actual Constraint
+            at the point where the syntax demands it.
+            </summary>
+            <param name="builder"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.EqualTo(System.Object)">
+            <summary>
+            Resolves the chain of constraints using an
+            EqualConstraint as base.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.SameAs(System.Object)">
+            <summary>
+            Resolves the chain of constraints using a
+            SameAsConstraint as base.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.LessThan(System.IComparable)">
+            <summary>
+            Resolves the chain of constraints using a
+            LessThanConstraint as base.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.GreaterThan(System.IComparable)">
+            <summary>
+            Resolves the chain of constraints using a
+            GreaterThanConstraint as base.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.LessThanOrEqualTo(System.IComparable)">
+            <summary>
+            Resolves the chain of constraints using a
+            LessThanOrEqualConstraint as base.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.AtMost(System.IComparable)">
+            <summary>
+            Resolves the chain of constraints using a
+            LessThanOrEqualConstraint as base.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.GreaterThanOrEqualTo(System.IComparable)">
+            <summary>
+            Resolves the chain of constraints using a
+            GreaterThanOrEqualConstraint as base.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.AtLeast(System.IComparable)">
+            <summary>
+            Resolves the chain of constraints using a
+            GreaterThanOrEqualConstraint as base.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.TypeOf(System.Type)">
+            <summary>
+            Resolves the chain of constraints using an
+            ExactTypeConstraint as base.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.InstanceOfType(System.Type)">
+            <summary>
+            Resolves the chain of constraints using an
+            InstanceOfTypeConstraint as base.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.AssignableFrom(System.Type)">
+            <summary>
+            Resolves the chain of constraints using an
+            AssignableFromConstraint as base.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.Contains(System.Object)">
+            <summary>
+            Resolves the chain of constraints using a
+            ContainsConstraint as base. This constraint
+            will, in turn, make use of the appropriate
+            second-level constraint, depending on the
+            type of the actual argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.Member(System.Object)">
+            <summary>
+            Resolves the chain of constraints using a 
+            CollectionContainsConstraint as base.
+            </summary>
+            <param name="expected">The expected object</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.StartsWith(System.String)">
+            <summary>
+            Resolves the chain of constraints using a
+            StartsWithConstraint as base.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.EndsWith(System.String)">
+            <summary>
+            Resolves the chain of constraints using a
+            StringEndingConstraint as base.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.Matches(System.String)">
+            <summary>
+            Resolves the chain of constraints using a
+            StringMatchingConstraint as base.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.EquivalentTo(System.Collections.ICollection)">
+            <summary>
+            Resolves the chain of constraints using a
+            CollectionEquivalentConstraint as base.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.CollectionContaining(System.Object)">
+            <summary>
+            Resolves the chain of constraints using a
+            CollectionContainingConstraint as base.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.SubsetOf(System.Collections.ICollection)">
+            <summary>
+            Resolves the chain of constraints using a
+            CollectionSubsetConstraint as base.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.Property(System.String,System.Object)">
+            <summary>
+            Resolves the chain of constraints using a 
+            PropertyConstraint as base
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.Length(System.Int32)">
+            <summary>
+            Resolves the chain of constraints using a
+            PropertyCOnstraint on Length as base
+            </summary>
+            <param name="length"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.Count(System.Int32)">
+            <summary>
+            Resolves the chain of constraints using a
+            PropertyCOnstraint on Length as base
+            </summary>
+            <param name="count"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.Property(System.String)">
+            <summary>
+            Modifies the ConstraintBuilder by pushing a Prop operator on the
+            ops stack and the name of the property on the opnds stack.
+            </summary>
+            <param name="name"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.Resolve(NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Resolve a constraint that has been recognized by applying
+            any pending operators and returning the resulting Constraint.
+            </summary>
+            <returns>A constraint that incorporates all pending operators</returns>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintBuilder.Null">
+            <summary>
+            Resolves the chain of constraints using
+            EqualConstraint(null) as base.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintBuilder.True">
+            <summary>
+            Resolves the chain of constraints using
+            EqualConstraint(true) as base.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintBuilder.False">
+            <summary>
+            Resolves the chain of constraints using
+            EqualConstraint(false) as base.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintBuilder.NaN">
+            <summary>
+            Resolves the chain of constraints using
+            Is.NaN as base.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintBuilder.Empty">
+            <summary>
+            Resolves the chain of constraints using
+            Is.Empty as base.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintBuilder.Unique">
+            <summary>
+            Resolves the chain of constraints using
+            Is.Unique as base.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintBuilder.Not">
+            <summary>
+            Modifies the ConstraintBuilder by pushing a Not operator on the stack.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintBuilder.No">
+            <summary>
+            Modifies the ConstraintBuilder by pushing a Not operator on the stack.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintBuilder.All">
+            <summary>
+            Modifies the ConstraintBuilder by pushing an All operator on the stack.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintBuilder.Some">
+            <summary>
+            Modifies the ConstraintBuilder by pushing a Some operator on the stack.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintBuilder.None">
+            <summary>
+            Modifies the constraint builder by pushing All and Not operators on the stack
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.CollectionConstraint">
+            <summary>
+            CollectionConstraint is the abstract base class for
+            constraints that operate on collections.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionConstraint.doMatch(System.Collections.ICollection)">
+            <summary>
+            Protected method to be implemented by derived classes
+            </summary>
+            <param name="collecton"></param>
+            <returns></returns>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.CollectionConstraint.CollectionTally">
+            <summary>
+            CollectionTally counts (tallies) the number of
+            occurences of each object in one or more enuerations.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionConstraint.CollectionTally.#ctor(System.Collections.IEnumerable)">
+            <summary>
+            Construct a CollectionTally object from a collection
+            </summary>
+            <param name="collection"></param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionConstraint.CollectionTally.CanRemove(System.Collections.IEnumerable)">
+            <summary>
+            Remove the counts for a collection from the tally,
+            so long as their are sufficient items to remove.
+            The tallies are not permitted to become negative.
+            </summary>
+            <param name="c">The collection to remove</param>
+            <returns>True if there were enough items to remove, otherwise false</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionConstraint.CollectionTally.AllCountsEqualTo(System.Int32)">
+            <summary>
+            Test whether all the counts are equal to a given value
+            </summary>
+            <param name="count">The value to be looked for</param>
+            <returns>True if all counts are equal to the value, otherwise false</returns>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.CollectionConstraint.CollectionTally.Item(System.Object)">
+            <summary>
+            Get the count of the number of times an object is present in the tally
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.UniqueItemsConstraint">
+            <summary>
+            UniqueItemsConstraint tests whether all the items in a 
+            collection are unique.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.UniqueItemsConstraint.doMatch(System.Collections.ICollection)">
+            <summary>
+            Apply the item constraint to each item in the collection,
+            failing if any item fails.
+            </summary>
+            <param name="actual"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.UniqueItemsConstraint.WriteDescriptionTo(NUnit.Framework.MessageWriter)">
+            <summary>
+            Write a description of this constraint to a MessageWriter
+            </summary>
+            <param name="writer"></param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.CollectionContainsConstraint">
+            <summary>
+            CollectionContainsConstraint is used to test whether a collection
+            contains an expected object as a member.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionContainsConstraint.#ctor(System.Object)">
+            <summary>
+            Construct a CollectionContainsConstraint
+            </summary>
+            <param name="expected"></param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionContainsConstraint.doMatch(System.Collections.ICollection)">
+            <summary>
+            Test whether the expected item is contained in the collection
+            </summary>
+            <param name="actual"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionContainsConstraint.WriteDescriptionTo(NUnit.Framework.MessageWriter)">
+            <summary>
+            Write a descripton of the constraint to a MessageWriter
+            </summary>
+            <param name="writer"></param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.CollectionEquivalentConstraint">
+            <summary>
+            CollectionEquivalentCOnstraint is used to determine whether two
+            collections are equivalent.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionEquivalentConstraint.#ctor(System.Collections.IEnumerable)">
+            <summary>
+            Construct a CollectionEquivalentConstraint
+            </summary>
+            <param name="expected"></param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionEquivalentConstraint.doMatch(System.Collections.ICollection)">
+            <summary>
+            Test whether two collections are equivalent
+            </summary>
+            <param name="actual"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionEquivalentConstraint.WriteDescriptionTo(NUnit.Framework.MessageWriter)">
+            <summary>
+            Write a description of this constraint to a MessageWriter
+            </summary>
+            <param name="writer"></param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.CollectionSubsetConstraint">
+            <summary>
+            CollectionSubsetConstraint is used to determine whether
+            one collection is a subset of another
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionSubsetConstraint.#ctor(System.Collections.IEnumerable)">
+            <summary>
+            Construct a CollectionSubsetConstraint
+            </summary>
+            <param name="expected">The collection that the actual value is expected to be a subset of</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionSubsetConstraint.doMatch(System.Collections.ICollection)">
+            <summary>
+            Test whether the actual collection is a subset of 
+            the expected collection provided.
+            </summary>
+            <param name="actual"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionSubsetConstraint.WriteDescriptionTo(NUnit.Framework.MessageWriter)">
+            <summary>
+            Write a description of this constraint to a MessageWriter
+            </summary>
+            <param name="writer"></param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.EqualConstraint">
+            <summary>
+            EqualConstraint is able to compare an actual value with the
+            expected value provided in its constructor.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EqualConstraint.#ctor(System.Object)">
+            <summary>
+            Initializes a new instance of the <see cref="T:EqualConstraint"/> class.
+            </summary>
+            <param name="expected">The expected value.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EqualConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EqualConstraint.WriteMessageTo(NUnit.Framework.MessageWriter)">
+            <summary>
+            Write a failure message. Overridden to provide custom 
+            failure messages for EqualConstraint.
+            </summary>
+            <param name="writer">The MessageWriter to write to</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EqualConstraint.WriteDescriptionTo(NUnit.Framework.MessageWriter)">
+            <summary>
+            Write description of this constraint
+            </summary>
+            <param name="writer">The MessageWriter to write to</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EqualConstraint.ArraysEqual(System.Array,System.Array)">
+            <summary>
+            Helper method to compare two arrays
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EqualConstraint.DisplayCollectionDifferences(NUnit.Framework.MessageWriter,System.Collections.ICollection,System.Collections.ICollection,System.Int32)">
+            <summary>
+            Display the failure information for two collections that did not match.
+            </summary>
+            <param name="writer">The MessageWriter on which to display</param>
+            <param name="expected">The expected collection.</param>
+            <param name="actual">The actual collection</param>
+            <param name="depth">The depth of this failure in a set of nested collections</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EqualConstraint.DisplayCollectionTypesAndSizes(NUnit.Framework.MessageWriter,System.Collections.ICollection,System.Collections.ICollection,System.Int32)">
+            <summary>
+            Displays a single line showing the types and sizes of the expected
+            and actual collections or arrays. If both are identical, the value is 
+            only shown once.
+            </summary>
+            <param name="writer">The MessageWriter on which to display</param>
+            <param name="expected">The expected collection or array</param>
+            <param name="actual">The actual collection or array</param>
+            <param name="indent">The indentation level for the message line</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EqualConstraint.DisplayFailurePoint(NUnit.Framework.MessageWriter,System.Collections.ICollection,System.Collections.ICollection,System.Int32,System.Int32)">
+            <summary>
+            Displays a single line showing the point in the expected and actual
+            arrays at which the comparison failed. If the arrays have different
+            structures or dimensions, both values are shown.
+            </summary>
+            <param name="writer">The MessageWriter on which to display</param>
+            <param name="expected">The expected array</param>
+            <param name="actual">The actual array</param>
+            <param name="failurePoint">Index of the failure point in the underlying collections</param>
+            <param name="indent">The indentation level for the message line</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.PrefixConstraint">
+            <summary>
+            Abstract base class used for prefixes
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.PrefixConstraint.baseConstraint">
+            <summary>
+            The base constraint
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.PrefixConstraint.#ctor(NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Construct given a base constraint
+            </summary>
+            <param name="baseConstraint"></param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.PrefixConstraint.PassModifiersToBase">
+            <summary>
+            Set all modifiers applied to the prefix into
+            the base constraint before matching
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.NotConstraint">
+            <summary>
+            NotConstraint negates the effect of some other constraint
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.NotConstraint.#ctor(NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Initializes a new instance of the <see cref="T:NotConstraint"/> class.
+            </summary>
+            <param name="baseConstraint">The base constraint to be negated.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.NotConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for if the base constraint fails, false if it succeeds</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.NotConstraint.WriteDescriptionTo(NUnit.Framework.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.NotConstraint.WriteActualValueTo(NUnit.Framework.MessageWriter)">
+            <summary>
+            Write the actual value for a failing constraint test to a MessageWriter.
+            </summary>
+            <param name="writer">The writer on which the actual value is displayed</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.AllItemsConstraint">
+            <summary>
+            AllItemsConstraint applies another constraint to each
+            item in a collection, succeeding if they all succeed.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AllItemsConstraint.#ctor(NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Construct an AllItemsConstraint on top of an existing constraint
+            </summary>
+            <param name="itemConstraint"></param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AllItemsConstraint.Matches(System.Object)">
+            <summary>
+            Apply the item constraint to each item in the collection,
+            failing if any item fails.
+            </summary>
+            <param name="actual"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AllItemsConstraint.WriteDescriptionTo(NUnit.Framework.MessageWriter)">
+            <summary>
+            Write a description of this constraint to a MessageWriter
+            </summary>
+            <param name="writer"></param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.SomeItemsConstraint">
+            <summary>
+            SomeItemsConstraint applies another constraint to each
+            item in a collection, succeeding if any of them succeeds.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.SomeItemsConstraint.#ctor(NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Construct a SomeItemsConstraint on top of an existing constraint
+            </summary>
+            <param name="itemConstraint"></param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.SomeItemsConstraint.Matches(System.Object)">
+            <summary>
+            Apply the item constraint to each item in the collection,
+            failing if any item fails.
+            </summary>
+            <param name="actual"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.SomeItemsConstraint.WriteDescriptionTo(NUnit.Framework.MessageWriter)">
+            <summary>
+            Write a description of this constraint to a MessageWriter
+            </summary>
+            <param name="writer"></param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.NoItemConstraint">
+            <summary>
+            SomeItemsConstraint applies another constraint to each
+            item in a collection, succeeding if any of them succeeds.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.NoItemConstraint.#ctor(NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Construct a SomeItemsConstraint on top of an existing constraint
+            </summary>
+            <param name="itemConstraint"></param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.NoItemConstraint.Matches(System.Object)">
+            <summary>
+            Apply the item constraint to each item in the collection,
+            failing if any item fails.
+            </summary>
+            <param name="actual"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.NoItemConstraint.WriteDescriptionTo(NUnit.Framework.MessageWriter)">
+            <summary>
+            Write a description of this constraint to a MessageWriter
+            </summary>
+            <param name="writer"></param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.SameAsConstraint">
+            <summary>
+            SameAsConstraint tests whether an object is identical to
+            the object passed to its constructor
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.SameAsConstraint.#ctor(System.Object)">
+            <summary>
+            Initializes a new instance of the <see cref="T:SameAsConstraint"/> class.
+            </summary>
+            <param name="expected">The expected object.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.SameAsConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.SameAsConstraint.WriteDescriptionTo(NUnit.Framework.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.TypeConstraint">
+            <summary>
+            TypeConstraint is the abstract base for constraints
+            that take a Type as their expected value.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.TypeConstraint.expectedType">
+            <summary>
+            The expected Type used by the constraint
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.TypeConstraint.#ctor(System.Type)">
+            <summary>
+            Construct a TypeConstraint for a given Type
+            </summary>
+            <param name="type"></param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.TypeConstraint.WriteActualValueTo(NUnit.Framework.MessageWriter)">
+            <summary>
+            Write the actual value for a failing constraint test to a
+            MessageWriter. TypeCOnstraints override this method to write
+            the name of the type.
+            </summary>
+            <param name="writer">The writer on which the actual value is displayed</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.ExactTypeConstraint">
+            <summary>
+            ExactTypeConstraint is used to test that an object
+            is of the exact type provided in the constructor
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ExactTypeConstraint.#ctor(System.Type)">
+            <summary>
+            Construct an ExactTypeConstraint for a given Type
+            </summary>
+            <param name="type"></param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ExactTypeConstraint.Matches(System.Object)">
+            <summary>
+            Test that an object is of the exact type specified
+            </summary>
+            <param name="actual"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ExactTypeConstraint.WriteDescriptionTo(NUnit.Framework.MessageWriter)">
+            <summary>
+            Write the description of this constraint to a MessageWriter
+            </summary>
+            <param name="writer"></param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.InstanceOfTypeConstraint">
+            <summary>
+            InstanceOfTypeConstraint is used to test that an object
+            is of the same type provided or derived from it.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.InstanceOfTypeConstraint.#ctor(System.Type)">
+            <summary>
+            Construct an InstanceOfTypeConstraint for the type provided
+            </summary>
+            <param name="type"></param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.InstanceOfTypeConstraint.Matches(System.Object)">
+            <summary>
+            Test whether an object is of the specified type or a derived type
+            </summary>
+            <param name="actual"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.InstanceOfTypeConstraint.WriteDescriptionTo(NUnit.Framework.MessageWriter)">
+            <summary>
+            Write a description of this constraint to a MessageWriter
+            </summary>
+            <param name="writer"></param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.AssignableFromConstraint">
+            <summary>
+            AssignableFromConstraint is used to test that an object
+            can be assigned from a given Type.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AssignableFromConstraint.#ctor(System.Type)">
+            <summary>
+            Construct an AssignableFromConstraint for the type provided
+            </summary>
+            <param name="type"></param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AssignableFromConstraint.Matches(System.Object)">
+            <summary>
+            Test whether an object can be assigned from the specified type
+            </summary>
+            <param name="actual"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AssignableFromConstraint.WriteDescriptionTo(NUnit.Framework.MessageWriter)">
+            <summary>
+            Write a description of this constraint to a MessageWriter
+            </summary>
+            <param name="writer"></param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.ComparisonConstraint">
+            <summary>
+            Abstract base class for constraints that compare values to
+            determine if one is greater than, equal to or less than
+            the other.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.ComparisonConstraint.expected">
+            <summary>
+            The value against which a comparison is to be made
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.ComparisonConstraint.ltOK">
+            <summary>
+            If true, less than returns success
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.ComparisonConstraint.eqOK">
+            <summary>
+            if true, equal returns success
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.ComparisonConstraint.gtOK">
+            <summary>
+            if true, greater than returns success
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.ComparisonConstraint.predicate">
+            <summary>
+            The predicate used as a part of the description
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ComparisonConstraint.#ctor(System.IComparable,System.Boolean,System.Boolean,System.Boolean,System.String)">
+            <summary>
+            Initializes a new instance of the <see cref="T:ComparisonConstraint"/> class.
+            </summary>
+            <param name="value">The value against which to make a comparison.</param>
+            <param name="ltOK">if set to <c>true</c> less succeeds.</param>
+            <param name="eqOK">if set to <c>true</c> equal succeeds.</param>
+            <param name="gtOK">if set to <c>true</c> greater succeeds.</param>
+            <param name="predicate">String used in describing the constraint.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ComparisonConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ComparisonConstraint.WriteDescriptionTo(NUnit.Framework.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.GreaterThanConstraint">
+            <summary>
+            Tests whether a value is greater than the value supplied to its constructor
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.GreaterThanConstraint.#ctor(System.IComparable)">
+            <summary>
+            Initializes a new instance of the <see cref="T:GreaterThanConstraint"/> class.
+            </summary>
+            <param name="expected">The expected value.</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.GreaterThanOrEqualConstraint">
+            <summary>
+            Tests whether a value is greater than or equal to the value supplied to its constructor
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.GreaterThanOrEqualConstraint.#ctor(System.IComparable)">
+            <summary>
+            Initializes a new instance of the <see cref="T:GreaterThanOrEqualConstraint"/> class.
+            </summary>
+            <param name="expected">The expected value.</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.LessThanConstraint">
+            <summary>
+            Tests whether a value is less than the value supplied to its constructor
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.LessThanConstraint.#ctor(System.IComparable)">
+            <summary>
+            Initializes a new instance of the <see cref="T:LessThanConstraint"/> class.
+            </summary>
+            <param name="expected">The expected value.</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.LessThanOrEqualConstraint">
+            <summary>
+            Tests whether a value is less than or equal to the value supplied to its constructor
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.LessThanOrEqualConstraint.#ctor(System.IComparable)">
+            <summary>
+            Initializes a new instance of the <see cref="T:LessThanOrEqualConstraint"/> class.
+            </summary>
+            <param name="expected">The expected value.</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.ContainsConstraint">
+            <summary>
+            ContainsConstraint tests a whether a string contains a substring
+            or a collection contains an object. It postpones the decision of
+            which test to use until the type of the actual argument is known.
+            This allows testing whether a string is contained in a collection
+            or as a substring of another string using the same syntax.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ContainsConstraint.#ctor(System.Object)">
+            <summary>
+            Initializes a new instance of the <see cref="T:ContainsConstraint"/> class.
+            </summary>
+            <param name="expected">The expected.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ContainsConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ContainsConstraint.WriteDescriptionTo(NUnit.Framework.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.PropertyConstraint">
+            <summary>
+            Summary description for PropertyConstraint.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.PropertyConstraint.#ctor(System.String,NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Initializes a new instance of the <see cref="T:PropertyConstraint"/> class.
+            </summary>
+            <param name="name">The name.</param>
+            <param name="baseConstraint">The constraint to apply to the property.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.PropertyConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.PropertyConstraint.WriteDescriptionTo(NUnit.Framework.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.PropertyConstraint.WriteActualValueTo(NUnit.Framework.MessageWriter)">
+            <summary>
+            Write the actual value for a failing constraint test to a
+            MessageWriter. The default implementation simply writes
+            the raw value of actual, leaving it to the writer to
+            perform any formatting.
+            </summary>
+            <param name="writer">The writer on which the actual value is displayed</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.BinaryOperation">
+            <summary>
+            BinaryOperation is the abstract base of all constraints
+            that combine two other constraints in some fashion.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.BinaryOperation.left">
+            <summary>
+            The first constraint being combined
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.BinaryOperation.right">
+            <summary>
+            The second constraint being combined
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.BinaryOperation.#ctor(NUnit.Framework.Constraints.Constraint,NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Construct a BinaryOperation from two other constraints
+            </summary>
+            <param name="left">The first constraint</param>
+            <param name="right">The second constraint</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.AndConstraint">
+            <summary>
+            AndConstraint succeeds only if both members succeed.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AndConstraint.#ctor(NUnit.Framework.Constraints.Constraint,NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Create an AndConstraint from two other constraints
+            </summary>
+            <param name="left">The first constraint</param>
+            <param name="right">The second constraint</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AndConstraint.Matches(System.Object)">
+            <summary>
+            Apply both member constraints to an actual value, succeeding 
+            succeeding only if both of them succeed.
+            </summary>
+            <param name="actual">The actual value</param>
+            <returns>True if the constraints both succeeded</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AndConstraint.WriteDescriptionTo(NUnit.Framework.MessageWriter)">
+            <summary>
+            Write a description for this contraint to a MessageWriter
+            </summary>
+            <param name="writer">The MessageWriter to receive the description</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.OrConstraint">
+            <summary>
+            OrConstraint succeeds if either member succeeds
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.OrConstraint.#ctor(NUnit.Framework.Constraints.Constraint,NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Create an OrConstraint from two other constraints
+            </summary>
+            <param name="left">The first constraint</param>
+            <param name="right">The second constraint</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.OrConstraint.Matches(System.Object)">
+            <summary>
+            Apply the member constraints to an actual value, succeeding 
+            succeeding as soon as one of them succeeds.
+            </summary>
+            <param name="actual">The actual value</param>
+            <returns>True if either constraint succeeded</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.OrConstraint.WriteDescriptionTo(NUnit.Framework.MessageWriter)">
+            <summary>
+            Write a description for this contraint to a MessageWriter
+            </summary>
+            <param name="writer">The MessageWriter to receive the description</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.Numerics">
+            <summary>
+            The Numerics class contains common operations on numeric values.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Numerics.IsNumericType(System.Object)">
+            <summary>
+            Checks the type of the object, returning true if
+            the object is a numeric type.
+            </summary>
+            <param name="obj">The object to check</param>
+            <returns>true if the object is a numeric type</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Numerics.IsFloatingPointNumeric(System.Object)">
+            <summary>
+            Checks the type of the object, returning true if
+            the object is a floating point numeric type.
+            </summary>
+            <param name="obj">The object to check</param>
+            <returns>true if the object is a floating point numeric type</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Numerics.IsFixedPointNumeric(System.Object)">
+            <summary>
+            Checks the type of the object, returning true if
+            the object is a fixed point numeric type.
+            </summary>
+            <param name="obj">The object to check</param>
+            <returns>true if the object is a fixed point numeric type</returns>
+        </member>
+        <member name="T:NUnit.Framework.SyntaxHelpers.Is">
+            <summary>
+            The Is class is a helper class with properties and methods
+            that supply a number of constraints used in Asserts.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.SyntaxHelpers.Is.Null">
+            <summary>
+            Is.Null returns a static constraint that tests for null
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.SyntaxHelpers.Is.True">
+            <summary>
+            Is.True returns a static constraint that tests whether a value is true
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.SyntaxHelpers.Is.False">
+            <summary>
+            Is.False returns a static constraint that tests whether a value is false
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.SyntaxHelpers.Is.NaN">
+            <summary>
+            Is.NaN returns a static constraint that tests whether a value is an NaN
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.SyntaxHelpers.Is.Empty">
+            <summary>
+            Is.Empty returns a static constraint that tests whether a string or collection is empty
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.SyntaxHelpers.Is.Unique">
+            <summary>
+            Is.Unique returns a static constraint that tests whether a collection contains all unque items.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.SyntaxHelpers.Is.EqualTo(System.Object)">
+            <summary>
+            Is.EqualTo returns a constraint that tests whether the
+            actual value equals the supplied argument
+            </summary>
+            <param name="expected"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.SyntaxHelpers.Is.SameAs(System.Object)">
+            <summary>
+            Is.SameAs returns a constraint that tests whether the
+            actual value is the same object as the supplied argument.
+            </summary>
+            <param name="expected"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.SyntaxHelpers.Is.GreaterThan(System.IComparable)">
+            <summary>
+            Is.GreaterThan returns a constraint that tests whether the
+            actual value is greater than the suppled argument
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.SyntaxHelpers.Is.GreaterThanOrEqualTo(System.IComparable)">
+            <summary>
+            Is.GreaterThanOrEqualTo returns a constraint that tests whether the
+            actual value is greater than or equal to the suppled argument
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.SyntaxHelpers.Is.AtLeast(System.IComparable)">
+            <summary>
+            Is.AtLeast is a synonym for Is.GreaterThanOrEqualTo
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.SyntaxHelpers.Is.LessThan(System.IComparable)">
+            <summary>
+            Is.LessThan returns a constraint that tests whether the
+            actual value is less than the suppled argument
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.SyntaxHelpers.Is.LessThanOrEqualTo(System.IComparable)">
+            <summary>
+            Is.LessThanOrEqualTo returns a constraint that tests whether the
+            actual value is less than or equal to the suppled argument
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.SyntaxHelpers.Is.AtMost(System.IComparable)">
+            <summary>
+            Is.AtMost is a synonym for Is.LessThanOrEqualTo
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.SyntaxHelpers.Is.TypeOf(System.Type)">
+            <summary>
+            Is.TypeOf returns a constraint that tests whether the actual
+            value is of the exact type supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.SyntaxHelpers.Is.InstanceOfType(System.Type)">
+            <summary>
+            Is.InstanceOfType returns a constraint that tests whether 
+            the actual value is of the type supplied as an argument
+            or a derived type.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.SyntaxHelpers.Is.AssignableFrom(System.Type)">
+            <summary>
+            Is.AssignableFrom returns a constraint that tests whether
+            the actual value is assignable from the type supplied as
+            an argument.
+            </summary>
+            <param name="expectedType"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.SyntaxHelpers.Is.EquivalentTo(System.Collections.ICollection)">
+            <summary>
+            Is.EquivalentTo returns a constraint that tests whether
+            the actual value is a collection containing the same
+            elements as the collection supplied as an arument
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.SyntaxHelpers.Is.SubsetOf(System.Collections.ICollection)">
+            <summary>
+            Is.SubsetOf returns a constraint that tests whether
+            the actual value is a subset of the collection 
+            supplied as an arument
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.SyntaxHelpers.Is.Not">
+            <summary>
+            Is.Not returns a ConstraintBuilder that negates
+            the constraint that follows it.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.SyntaxHelpers.Is.All">
+            <summary>
+            Is.All returns a ConstraintBuilder, which will apply
+            the following constraint to all members of a collection,
+            succeeding if all of them succeed. This property is
+            a synonym for Has.AllItems.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.SyntaxHelpers.Iz">
+            <summary>
+            The Iz class is a synonym for Is intended for use in VB,
+            which regards Is as a keyword.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.SyntaxHelpers.Text">
+            <summary>
+            The Text class is a helper class with properties and methods
+            that supply a number of constraints used with strings.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.SyntaxHelpers.Text.Contains(System.String)">
+            <summary>
+            Contains returns a constraint that succeeds if the actual
+            value contains the substring supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.SyntaxHelpers.Text.DoesNotContain(System.String)">
+            <summary>
+            DoesNotContain returns a constraint that fails if the actual
+            value contains the substring supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.SyntaxHelpers.Text.StartsWith(System.String)">
+            <summary>
+            StartsWith returns a constraint that succeeds if the actual
+            value starts with the substring supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.SyntaxHelpers.Text.DoesNotStartWith(System.String)">
+            <summary>
+            DoesNotStartWith returns a constraint that fails if the actual
+            value starts with the substring supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.SyntaxHelpers.Text.EndsWith(System.String)">
+            <summary>
+            EndsWith returns a constraint that succeeds if the actual
+            value ends with the substring supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.SyntaxHelpers.Text.DoesNotEndWith(System.String)">
+            <summary>
+            DoesNotEndWith returns a constraint that fails if the actual
+            value ends with the substring supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.SyntaxHelpers.Text.Matches(System.String)">
+            <summary>
+            Matches returns a constraint that succeeds if the actual
+            value matches the pattern supplied as an argument.
+            </summary>
+            <param name="pattern"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.SyntaxHelpers.Text.DoesNotMatch(System.String)">
+            <summary>
+            DoesNotMatch returns a constraint that failss if the actual
+            value matches the pattern supplied as an argument.
+            </summary>
+            <param name="pattern"></param>
+            <returns></returns>
+        </member>
+        <member name="P:NUnit.Framework.SyntaxHelpers.Text.All">
+            <summary>
+            Text.All returns a ConstraintBuilder, which will apply
+            the following constraint to all members of a collection,
+            succeeding if all of them succeed.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.SyntaxHelpers.List">
+            <summary>
+            The List class is a helper class with properties and methods
+            that supply a number of constraints used with lists and collections.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.SyntaxHelpers.List.Map(System.Collections.ICollection)">
+            <summary>
+            List.Map returns a ListMapper, which can be used to map
+            the original collection to another collection.
+            </summary>
+            <param name="actual"></param>
+            <returns></returns>
+        </member>
+        <member name="T:NUnit.Framework.SyntaxHelpers.ListMapper">
+            <summary>
+            ListMapper is used to transform a collection used as an actual argument
+            producing another collection to be used in the assertion.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.SyntaxHelpers.ListMapper.#ctor(System.Collections.ICollection)">
+            <summary>
+            Construct a ListMapper based on a collection
+            </summary>
+            <param name="original">The collection to be transformed</param>
+        </member>
+        <member name="M:NUnit.Framework.SyntaxHelpers.ListMapper.Property(System.String)">
+            <summary>
+            Produces a collection containing all the values of a property
+            </summary>
+            <param name="name">The collection of property values</param>
+            <returns></returns>
+        </member>
+        <member name="T:NUnit.Framework.SyntaxHelpers.Has">
+            <summary>
+            Summary description for HasNoPrefixB.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.SyntaxHelpers.Has.Property(System.String)">
+            <summary>
+            Returns a new ConstraintBuilder, which will apply the
+            following constraint to a named property of the object
+            being tested.
+            </summary>
+            <param name="name">The name of the property</param>
+        </member>
+        <member name="M:NUnit.Framework.SyntaxHelpers.Has.Property(System.String,System.Object)">
+            <summary>
+            Returns a new PropertyConstraint checking for the
+            existence of a particular property value.
+            </summary>
+            <param name="name">The name of the property to look for</param>
+            <param name="expected">The expected value of the property</param>
+        </member>
+        <member name="M:NUnit.Framework.SyntaxHelpers.Has.Length(System.Int32)">
+            <summary>
+            Returns a new PropertyConstraint for the Length property
+            </summary>
+            <param name="length"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.SyntaxHelpers.Has.Count(System.Int32)">
+            <summary>
+            Returns a new PropertyConstraint or the Count property
+            </summary>
+            <param name="count"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.SyntaxHelpers.Has.Member(System.Object)">
+            <summary>
+            Returns a new CollectionContainsConstraint checking for the
+            presence of a particular object in the collection.
+            </summary>
+            <param name="expected">The expected object</param>
+        </member>
+        <member name="P:NUnit.Framework.SyntaxHelpers.Has.No">
+            <summary>
+            Has.No returns a ConstraintBuilder that negates
+            the constraint that follows it.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.SyntaxHelpers.Has.All">
+            <summary>
+            Has.AllItems returns a ConstraintBuilder, which will apply
+            the following constraint to all members of a collection,
+            succeeding if all of them succeed.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.SyntaxHelpers.Has.Some">
+            <summary>
+            Has.Some returns a ConstraintBuilder, which will apply
+            the following constraint to all members of a collection,
+            succeeding if any of them succeed. It is a synonym
+            for Has.Item.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.SyntaxHelpers.Has.None">
+            <summary>
+            Has.None returns a ConstraintBuilder, which will apply
+            the following constraint to all members of a collection,
+            succeeding only if none of them succeed.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.SyntaxHelpers.Has.HasNoPrefixBuilder">
+            <summary>
+            Nested class that allows us to restrict the number
+            of key words that may appear after Has.No.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.SyntaxHelpers.Has.HasNoPrefixBuilder.Property(System.String)">
+            <summary>
+            Return a ConstraintBuilder conditioned to apply
+            the following constraint to a property.
+            </summary>
+            <param name="name">The property name</param>
+            <returns>A ConstraintBuilder</returns>
+        </member>
+        <member name="M:NUnit.Framework.SyntaxHelpers.Has.HasNoPrefixBuilder.Member(System.Object)">
+            <summary>
+            Return a Constraint that succeeds if the expected object is
+            not contained in a collection.
+            </summary>
+            <param name="expected">The expected object</param>
+            <returns>A Constraint</returns>
+        </member>
+        <member name="T:NUnit.Framework.Assert">
+            <summary>
+            The Assert class contains a collection of static methods that
+            implement the most common assertions used in NUnit.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Assert.#ctor">
+            <summary>
+            We don't actually want any instances of this object, but some people
+            like to inherit from it to add other static methods. Hence, the
+            protected constructor disallows any instances of this object. 
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Equals(System.Object,System.Object)">
+            <summary>
+            The Equals method throws an AssertionException. This is done 
+            to make sure there is no mistake by calling this function.
+            </summary>
+            <param name="a"></param>
+            <param name="b"></param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.ReferenceEquals(System.Object,System.Object)">
+            <summary>
+            override the default ReferenceEquals to throw an AssertionException. This 
+            implementation makes sure there is no mistake in calling this function 
+            as part of Assert. 
+            </summary>
+            <param name="a"></param>
+            <param name="b"></param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsTrue(System.Boolean,System.String,System.Object[])">
+            <summary>
+            Asserts that a condition is true. If the condition is false the method throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>.
+            </summary> 
+            <param name="condition">The evaluated condition</param>
+            <param name="message">The message to display if the condition is false</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsTrue(System.Boolean,System.String)">
+            <summary>
+            Asserts that a condition is true. If the condition is false the method throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>.
+            </summary>
+            <param name="condition">The evaluated condition</param>
+            <param name="message">The message to display if the condition is false</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsTrue(System.Boolean)">
+            <summary>
+            Asserts that a condition is true. If the condition is false the method throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>.
+            </summary>
+            <param name="condition">The evaluated condition</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsFalse(System.Boolean,System.String,System.Object[])">
+            <summary>
+            Asserts that a condition is false. If the condition is true the method throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>.
+            </summary>
+            <param name="condition">The evaluated condition</param>
+            <param name="message">The message to display if the condition is true</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsFalse(System.Boolean,System.String)">
+            <summary>
+            Asserts that a condition is false. If the condition is true the method throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>.
+            </summary>
+            <param name="condition">The evaluated condition</param>
+            <param name="message">The message to display if the condition is true</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsFalse(System.Boolean)">
+            <summary>
+            Asserts that a condition is false. If the condition is true the method throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>.
+            </summary>
+            <param name="condition">The evaluated condition</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotNull(System.Object,System.String,System.Object[])">
+            <summary>
+            Verifies that the object that is passed in is not equal to <code>null</code>
+            If the object is <code>null</code> then an <see cref="T:NUnit.Framework.AssertionException"/>
+            is thrown.
+            </summary>
+            <param name="anObject">The object that is to be tested</param>
+            <param name="message">The message to be displayed when the object is null</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotNull(System.Object,System.String)">
+            <summary>
+            Verifies that the object that is passed in is not equal to <code>null</code>
+            If the object is <code>null</code> then an <see cref="T:NUnit.Framework.AssertionException"/>
+            is thrown.
+            </summary>
+            <param name="anObject">The object that is to be tested</param>
+            <param name="message">The message to be displayed when the object is null</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotNull(System.Object)">
+            <summary>
+            Verifies that the object that is passed in is not equal to <code>null</code>
+            If the object is <code>null</code> then an <see cref="T:NUnit.Framework.AssertionException"/>
+            is thrown.
+            </summary>
+            <param name="anObject">The object that is to be tested</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNull(System.Object,System.String,System.Object[])">
+            <summary>
+            Verifies that the object that is passed in is equal to <code>null</code>
+            If the object is not <code>null</code> then an <see cref="T:NUnit.Framework.AssertionException"/>
+            is thrown.
+            </summary>
+            <param name="anObject">The object that is to be tested</param>
+            <param name="message">The message to be displayed when the object is not null</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNull(System.Object,System.String)">
+            <summary>
+            Verifies that the object that is passed in is equal to <code>null</code>
+            If the object is not <code>null</code> then an <see cref="T:NUnit.Framework.AssertionException"/>
+            is thrown.
+            </summary>
+            <param name="anObject">The object that is to be tested</param>
+            <param name="message">The message to be displayed when the object is not null</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNull(System.Object)">
+            <summary>
+            Verifies that the object that is passed in is equal to <code>null</code>
+            If the object is not null <code>null</code> then an <see cref="T:NUnit.Framework.AssertionException"/>
+            is thrown.
+            </summary>
+            <param name="anObject">The object that is to be tested</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNaN(System.Double,System.String,System.Object[])">
+            <summary>
+            Verifies that the double is passed is an <code>NaN</code> value.
+            If the object is not <code>NaN</code> then an <see cref="T:NUnit.Framework.AssertionException"/>
+            is thrown.
+            </summary>
+            <param name="aDouble">The value that is to be tested</param>
+            <param name="message">The message to be displayed when the object is not null</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNaN(System.Double,System.String)">
+            <summary>
+            Verifies that the double is passed is an <code>NaN</code> value.
+            If the object is not <code>NaN</code> then an <see cref="T:NUnit.Framework.AssertionException"/>
+            is thrown.
+            </summary>
+            <param name="aDouble">The object that is to be tested</param>
+            <param name="message">The message to be displayed when the object is not null</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNaN(System.Double)">
+            <summary>
+            Verifies that the double is passed is an <code>NaN</code> value.
+            If the object is not <code>NaN</code> then an <see cref="T:NUnit.Framework.AssertionException"/>
+            is thrown.
+            </summary>
+            <param name="aDouble">The object that is to be tested</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsEmpty(System.String,System.String,System.Object[])">
+            <summary>
+            Assert that a string is empty - that is equal to string.Empty
+            </summary>
+            <param name="aString">The string to be tested</param>
+            <param name="message">The message to be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsEmpty(System.String,System.String)">
+            <summary>
+            Assert that a string is empty - that is equal to string.Emtpy
+            </summary>
+            <param name="aString">The string to be tested</param>
+            <param name="message">The message to be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsEmpty(System.String)">
+            <summary>
+            Assert that a string is empty - that is equal to string.Emtpy
+            </summary>
+            <param name="aString">The string to be tested</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsEmpty(System.Collections.ICollection,System.String,System.Object[])">
+            <summary>
+            Assert that an array, list or other collection is empty
+            </summary>
+            <param name="collection">An array, list or other collection implementing ICollection</param>
+            <param name="message">The message to be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsEmpty(System.Collections.ICollection,System.String)">
+            <summary>
+            Assert that an array, list or other collection is empty
+            </summary>
+            <param name="collection">An array, list or other collection implementing ICollection</param>
+            <param name="message">The message to be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsEmpty(System.Collections.ICollection)">
+            <summary>
+            Assert that an array,list or other collection is empty
+            </summary>
+            <param name="collection">An array, list or other collection implementing ICollection</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotEmpty(System.String,System.String,System.Object[])">
+            <summary>
+            Assert that a string is not empty - that is not equal to string.Empty
+            </summary>
+            <param name="aString">The string to be tested</param>
+            <param name="message">The message to be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotEmpty(System.String,System.String)">
+            <summary>
+            Assert that a string is empty - that is equal to string.Emtpy
+            </summary>
+            <param name="aString">The string to be tested</param>
+            <param name="message">The message to be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotEmpty(System.String)">
+            <summary>
+            Assert that a string is empty - that is equal to string.Emtpy
+            </summary>
+            <param name="aString">The string to be tested</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotEmpty(System.Collections.ICollection,System.String,System.Object[])">
+            <summary>
+            Assert that an array, list or other collection is empty
+            </summary>
+            <param name="collection">An array, list or other collection implementing ICollection</param>
+            <param name="message">The message to be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotEmpty(System.Collections.ICollection,System.String)">
+            <summary>
+            Assert that an array, list or other collection is empty
+            </summary>
+            <param name="collection">An array, list or other collection implementing ICollection</param>
+            <param name="message">The message to be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotEmpty(System.Collections.ICollection)">
+            <summary>
+            Assert that an array,list or other collection is empty
+            </summary>
+            <param name="collection">An array, list or other collection implementing ICollection</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsAssignableFrom(System.Type,System.Object)">
+            <summary>
+            Asserts that an object may be assigned a  value of a given Type.
+            </summary>
+            <param name="expected">The expected Type.</param>
+            <param name="actual">The object under examination</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsAssignableFrom(System.Type,System.Object,System.String)">
+            <summary>
+            Asserts that an object may be assigned a  value of a given Type.
+            </summary>
+            <param name="expected">The expected Type.</param>
+            <param name="actual">The object under examination</param>
+            <param name="message">The messge to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsAssignableFrom(System.Type,System.Object,System.String,System.Object[])">
+            <summary>
+            Asserts that an object may be assigned a  value of a given Type.
+            </summary>
+            <param name="expected">The expected Type.</param>
+            <param name="actual">The object under examination</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotAssignableFrom(System.Type,System.Object)">
+            <summary>
+            Asserts that an object may not be assigned a  value of a given Type.
+            </summary>
+            <param name="expected">The expected Type.</param>
+            <param name="actual">The object under examination</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotAssignableFrom(System.Type,System.Object,System.String)">
+            <summary>
+            Asserts that an object may not be assigned a  value of a given Type.
+            </summary>
+            <param name="expected">The expected Type.</param>
+            <param name="actual">The object under examination</param>
+            <param name="message">The messge to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotAssignableFrom(System.Type,System.Object,System.String,System.Object[])">
+            <summary>
+            Asserts that an object may not be assigned a  value of a given Type.
+            </summary>
+            <param name="expected">The expected Type.</param>
+            <param name="actual">The object under examination</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsInstanceOfType(System.Type,System.Object)">
+            <summary>
+            Asserts that an object is an instance of a given type.
+            </summary>
+            <param name="expected">The expected Type</param>
+            <param name="actual">The object being examined</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsInstanceOfType(System.Type,System.Object,System.String)">
+            <summary>
+            Asserts that an object is an instance of a given type.
+            </summary>
+            <param name="expected">The expected Type</param>
+            <param name="actual">The object being examined</param>
+            <param name="message">A message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsInstanceOfType(System.Type,System.Object,System.String,System.Object[])">
+            <summary>
+            Asserts that an object is an instance of a given type.
+            </summary>
+            <param name="expected">The expected Type</param>
+            <param name="actual">The object being examined</param>
+            <param name="message">A message to display in case of failure</param>
+            <param name="args">An array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotInstanceOfType(System.Type,System.Object)">
+            <summary>
+            Asserts that an object is not an instance of a given type.
+            </summary>
+            <param name="expected">The expected Type</param>
+            <param name="actual">The object being examined</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotInstanceOfType(System.Type,System.Object,System.String)">
+            <summary>
+            Asserts that an object is not an instance of a given type.
+            </summary>
+            <param name="expected">The expected Type</param>
+            <param name="actual">The object being examined</param>
+            <param name="message">A message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotInstanceOfType(System.Type,System.Object,System.String,System.Object[])">
+            <summary>
+            Asserts that an object is not an instance of a given type.
+            </summary>
+            <param name="expected">The expected Type</param>
+            <param name="actual">The object being examined</param>
+            <param name="message">A message to display in case of failure</param>
+            <param name="args">An array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Int32,System.Int32,System.String,System.Object[])">
+            <summary>
+            Verifies that two ints are equal. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Int32,System.Int32,System.String)">
+            <summary>
+            Verifies that two ints are equal. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Int32,System.Int32)">
+            <summary>
+            Verifies that two ints are equal. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Int64,System.Int64,System.String,System.Object[])">
+            <summary>
+            Verifies that two longs are equal. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Int64,System.Int64,System.String)">
+            <summary>
+            Verifies that two longs are equal. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Int64,System.Int64)">
+            <summary>
+            Verifies that two longs are equal. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.UInt32,System.UInt32,System.String,System.Object[])">
+            <summary>
+            Verifies that two uints are equal. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.UInt32,System.UInt32,System.String)">
+            <summary>
+            Verifies that two uints are equal. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.UInt32,System.UInt32)">
+            <summary>
+            Verifies that two uints are equal. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.UInt64,System.UInt64,System.String,System.Object[])">
+            <summary>
+            Verifies that two ulongs are equal. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.UInt64,System.UInt64,System.String)">
+            <summary>
+            Verifies that two ulongs are equal. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.UInt64,System.UInt64)">
+            <summary>
+            Verifies that two ulongs are equal. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Decimal,System.Decimal,System.String,System.Object[])">
+            <summary>
+            Verifies that two decimals are equal. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Decimal,System.Decimal,System.String)">
+            <summary>
+            Verifies that two decimal are equal. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Decimal,System.Decimal)">
+            <summary>
+            Verifies that two decimals are equal. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Double,System.Double,System.Double,System.String,System.Object[])">
+            <summary>
+            Verifies that two doubles are equal considering a delta. If the
+            expected value is infinity then the delta value is ignored. If 
+            they are not equals then an <see cref="T:NUnit.Framework.AssertionException"/> is
+            thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="delta">The maximum acceptable difference between the
+            the expected and the actual</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Double,System.Double,System.Double,System.String)">
+            <summary>
+            Verifies that two doubles are equal considering a delta. If the
+            expected value is infinity then the delta value is ignored. If 
+            they are not equals then an <see cref="T:NUnit.Framework.AssertionException"/> is
+            thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="delta">The maximum acceptable difference between the
+            the expected and the actual</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Double,System.Double,System.Double)">
+            <summary>
+            Verifies that two doubles are equal considering a delta. If the
+            expected value is infinity then the delta value is ignored. If 
+            they are not equals then an <see cref="T:NUnit.Framework.AssertionException"/> is
+            thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="delta">The maximum acceptable difference between the
+            the expected and the actual</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Single,System.Single,System.Single,System.String,System.Object[])">
+            <summary>
+            Verifies that two floats are equal considering a delta. If the
+            expected value is infinity then the delta value is ignored. If 
+            they are not equals then an <see cref="T:NUnit.Framework.AssertionException"/> is
+            thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="delta">The maximum acceptable difference between the
+            the expected and the actual</param>
+            <param name="message">The message displayed upon failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Single,System.Single,System.Single,System.String)">
+            <summary>
+            Verifies that two floats are equal considering a delta. If the
+            expected value is infinity then the delta value is ignored. If 
+            they are not equals then an <see cref="T:NUnit.Framework.AssertionException"/> is
+            thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="delta">The maximum acceptable difference between the
+            the expected and the actual</param>
+            <param name="message">The message displayed upon failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Single,System.Single,System.Single)">
+            <summary>
+            Verifies that two floats are equal considering a delta. If the
+            expected value is infinity then the delta value is ignored. If 
+            they are not equals then an <see cref="T:NUnit.Framework.AssertionException"/> is
+            thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="delta">The maximum acceptable difference between the
+            the expected and the actual</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Object,System.Object,System.String,System.Object[])">
+            <summary>
+            Verifies that two objects are equal.  Two objects are considered
+            equal if both are null, or if both have the same value.  All
+            non-numeric types are compared by using the <c>Equals</c> method.
+            Arrays are compared by comparing each element using the same rules.
+            If they are not equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The value that is expected</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message to display if objects are not equal</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Object,System.Object,System.String)">
+            <summary>
+            Verifies that two objects are equal.  Two objects are considered
+            equal if both are null, or if both have the same value.  All
+            non-numeric types are compared by using the <c>Equals</c> method.
+            If they are not equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The value that is expected</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message to display if objects are not equal</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Object,System.Object)">
+            <summary>
+            Verifies that two objects are equal.  Two objects are considered
+            equal if both are null, or if both have the same value.  All
+            non-numeric types are compared by using the <c>Equals</c> method.
+            If they are not equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The value that is expected</param>
+            <param name="actual">The actual value</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Object,System.Object,System.String,System.Object[])">
+            <summary>
+            Asserts that two objects are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+            <param name="message">The message to be displayed when the two objects are the same object.</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Object,System.Object,System.String)">
+            <summary>
+            Asserts that two objects are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+            <param name="message">The message to be displayed when the objects are the same</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Object,System.Object)">
+            <summary>
+            Asserts that two objects are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Int32,System.Int32,System.String,System.Object[])">
+            <summary>
+            Asserts that two ints are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+            <param name="message">The message to be displayed when the two objects are the same object.</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Int32,System.Int32,System.String)">
+            <summary>
+            Asserts that two ints are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+            <param name="message">The message to be displayed when the objects are the same</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Int32,System.Int32)">
+            <summary>
+            Asserts that two ints are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Int64,System.Int64,System.String,System.Object[])">
+            <summary>
+            Asserts that two longss are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+            <param name="message">The message to be displayed when the two objects are the same object.</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Int64,System.Int64,System.String)">
+            <summary>
+            Asserts that two longs are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+            <param name="message">The message to be displayed when the objects are the same</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Int64,System.Int64)">
+            <summary>
+            Asserts that two longs are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.UInt32,System.UInt32,System.String,System.Object[])">
+            <summary>
+            Asserts that two uints are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+            <param name="message">The message to be displayed when the two objects are the same object.</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.UInt32,System.UInt32,System.String)">
+            <summary>
+            Asserts that two uints are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+            <param name="message">The message to be displayed when the objects are the same</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.UInt32,System.UInt32)">
+            <summary>
+            Asserts that two uints are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.UInt64,System.UInt64,System.String,System.Object[])">
+            <summary>
+            Asserts that two ulongs are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+            <param name="message">The message to be displayed when the two objects are the same object.</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.UInt64,System.UInt64,System.String)">
+            <summary>
+            Asserts that two ulongs are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+            <param name="message">The message to be displayed when the objects are the same</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.UInt64,System.UInt64)">
+            <summary>
+            Asserts that two ulong are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Decimal,System.Decimal,System.String,System.Object[])">
+            <summary>
+            Asserts that two decimals are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+            <param name="message">The message to be displayed when the two objects are the same object.</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Decimal,System.Decimal,System.String)">
+            <summary>
+            Asserts that two decimals are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+            <param name="message">The message to be displayed when the objects are the same</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Decimal,System.Decimal)">
+            <summary>
+            Asserts that two decimals are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Single,System.Single,System.String,System.Object[])">
+            <summary>
+            Asserts that two floats are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+            <param name="message">The message to be displayed when the two objects are the same object.</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Single,System.Single,System.String)">
+            <summary>
+            Asserts that two floats are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+            <param name="message">The message to be displayed when the objects are the same</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Single,System.Single)">
+            <summary>
+            Asserts that two floats are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Double,System.Double,System.String,System.Object[])">
+            <summary>
+            Asserts that two doubles are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+            <param name="message">The message to be displayed when the two objects are the same object.</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Double,System.Double,System.String)">
+            <summary>
+            Asserts that two doubles are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+            <param name="message">The message to be displayed when the objects are the same</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Double,System.Double)">
+            <summary>
+            Asserts that two doubles are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreSame(System.Object,System.Object,System.String,System.Object[])">
+            <summary>
+            Asserts that two objects refer to the same object. If they
+            are not the same an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+            <param name="message">The message to be displayed when the two objects are not the same object.</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreSame(System.Object,System.Object,System.String)">
+            <summary>
+            Asserts that two objects refer to the same object. If they
+            are not the same an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+            <param name="message">The message to be displayed when the object is null</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreSame(System.Object,System.Object)">
+            <summary>
+            Asserts that two objects refer to the same object. If they
+            are not the same an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotSame(System.Object,System.Object,System.String,System.Object[])">
+            <summary>
+            Asserts that two objects do not refer to the same object. If they
+            are the same an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+            <param name="message">The message to be displayed when the two objects are the same object.</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotSame(System.Object,System.Object,System.String)">
+            <summary>
+            Asserts that two objects do not refer to the same object. If they
+            are the same an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+            <param name="message">The message to be displayed when the objects are the same</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotSame(System.Object,System.Object)">
+            <summary>
+            Asserts that two objects do not refer to the same object. If they
+            are the same an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.Int32,System.Int32,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If they are not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.Int32,System.Int32,System.String)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.Int32,System.Int32)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.UInt32,System.UInt32,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.UInt32,System.UInt32,System.String)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.UInt32,System.UInt32)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.Int64,System.Int64,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.Int64,System.Int64,System.String)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.Int64,System.Int64)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.UInt64,System.UInt64,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.UInt64,System.UInt64,System.String)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.UInt64,System.UInt64)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.Decimal,System.Decimal,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.Decimal,System.Decimal,System.String)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.Decimal,System.Decimal)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.Double,System.Double,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.Double,System.Double,System.String)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.Double,System.Double)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.Single,System.Single,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.Single,System.Single,System.String)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.Single,System.Single)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.IComparable,System.IComparable,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.IComparable,System.IComparable,System.String)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.IComparable,System.IComparable)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.Int32,System.Int32,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.Int32,System.Int32,System.String)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.Int32,System.Int32)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.UInt32,System.UInt32,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.UInt32,System.UInt32,System.String)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.UInt32,System.UInt32)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.Int64,System.Int64,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.Int64,System.Int64,System.String)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.Int64,System.Int64)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.UInt64,System.UInt64,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.UInt64,System.UInt64,System.String)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.UInt64,System.UInt64)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.Decimal,System.Decimal,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.Decimal,System.Decimal,System.String)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.Decimal,System.Decimal)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.Double,System.Double,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.Double,System.Double,System.String)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.Double,System.Double)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.Single,System.Single,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.Single,System.Single,System.String)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.Single,System.Single)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.IComparable,System.IComparable,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.IComparable,System.IComparable,System.String)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.IComparable,System.IComparable)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Contains(System.Object,System.Collections.ICollection,System.String,System.Object[])">
+            <summary>
+            Asserts that an object is contained in a list.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The list to be examined</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Arguments used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Contains(System.Object,System.Collections.ICollection,System.String)">
+            <summary>
+            Asserts that an object is contained in a list.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The list to be examined</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Contains(System.Object,System.Collections.ICollection)">
+            <summary>
+            Asserts that an object is contained in a list.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The list to be examined</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Fail(System.String,System.Object[])">
+            <summary>
+            Throws an <see cref="T:NUnit.Framework.AssertionException"/> with the message and arguments 
+            that are passed in. This is used by the other Assert functions. 
+            </summary>
+            <param name="message">The message to initialize the <see cref="T:NUnit.Framework.AssertionException"/> with.</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Fail(System.String)">
+            <summary>
+            Throws an <see cref="T:NUnit.Framework.AssertionException"/> with the message that is 
+            passed in. This is used by the other Assert functions. 
+            </summary>
+            <param name="message">The message to initialize the <see cref="T:NUnit.Framework.AssertionException"/> with.</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Fail">
+            <summary>
+            Throws an <see cref="T:NUnit.Framework.AssertionException"/>. 
+            This is used by the other Assert functions. 
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Ignore(System.String,System.Object[])">
+            <summary>
+            Throws an <see cref="T:NUnit.Framework.IgnoreException"/> with the message and arguments 
+            that are passed in.  This causes the test to be reported as ignored.
+            </summary>
+            <param name="message">The message to initialize the <see cref="T:NUnit.Framework.AssertionException"/> with.</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Ignore(System.String)">
+            <summary>
+            Throws an <see cref="T:NUnit.Framework.IgnoreException"/> with the message that is 
+            passed in. This causes the test to be reported as ignored. 
+            </summary>
+            <param name="message">The message to initialize the <see cref="T:NUnit.Framework.AssertionException"/> with.</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Ignore">
+            <summary>
+            Throws an <see cref="T:NUnit.Framework.IgnoreException"/>. 
+            This causes the test to be reported as ignored. 
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Assert.DoAssert(NUnit.Framework.IAsserter)">
+            <summary>
+            NOTE: The use of asserters for extending NUnit has
+            now been replaced by the use of constraints. This
+            method is marked obsolete.
+            
+            Test the condition asserted by an asserter and throw
+            an assertion exception using provided message on failure.
+            </summary>
+            <param name="asserter">An object that implements IAsserter</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.That(System.Object,NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Apply a constraint to an actual value, succeeding if the constraint
+            is satisfied and throwing an assertion exception on failure.
+            </summary>
+            <param name="constraint">A Constraint to be applied</param>
+            <param name="actual">The actual value to test</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.That(System.Object,NUnit.Framework.Constraints.Constraint,System.String)">
+            <summary>
+            Apply a constraint to an actual value, succeedingt if the constraint
+            is satisfied and throwing an assertion exception on failure.
+            </summary>
+            <param name="constraint">A Constraint to be applied</param>
+            <param name="actual">The actual value to test</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.That(System.Object,NUnit.Framework.Constraints.Constraint,System.String,System.Object[])">
+            <summary>
+            Apply a constraint to an actual value, succeedingt if the constraint
+            is satisfied and throwing an assertion exception on failure.
+            </summary>
+            <param name="constraint">A Constraint to be applied</param>
+            <param name="actual">The actual value to test</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.That(System.Boolean,System.String,System.Object[])">
+            <summary>
+            Asserts that a condition is true. If the condition is false the method throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>.
+            </summary> 
+            <param name="condition">The evaluated condition</param>
+            <param name="message">The message to display if the condition is false</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.That(System.Boolean,System.String)">
+            <summary>
+            Asserts that a condition is true. If the condition is false the method throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>.
+            </summary>
+            <param name="condition">The evaluated condition</param>
+            <param name="message">The message to display if the condition is false</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.That(System.Boolean)">
+            <summary>
+            Asserts that a condition is true. If the condition is false the method throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>.
+            </summary>
+            <param name="condition">The evaluated condition</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.Int32,System.Int32,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than or equal to the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.Int32,System.Int32,System.String)">
+            <summary>
+            Verifies that the first value is greater than or equal to the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.Int32,System.Int32)">
+            <summary>
+            Verifies that the first value is greater than or equal to the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.UInt32,System.UInt32,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than or equal to the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.UInt32,System.UInt32,System.String)">
+            <summary>
+            Verifies that the first value is greater than or equal to the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.UInt32,System.UInt32)">
+            <summary>
+            Verifies that the first value is greater or equal to than the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.Int64,System.Int64,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than or equal to the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.Int64,System.Int64,System.String)">
+            <summary>
+            Verifies that the first value is greater than or equal to the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.Int64,System.Int64)">
+            <summary>
+            Verifies that the first value is greater or equal to than the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.UInt64,System.UInt64,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than or equal to the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.UInt64,System.UInt64,System.String)">
+            <summary>
+            Verifies that the first value is greater than or equal to the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.UInt64,System.UInt64)">
+            <summary>
+            Verifies that the first value is greater or equal to than the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.Decimal,System.Decimal,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than or equal to the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.Decimal,System.Decimal,System.String)">
+            <summary>
+            Verifies that the first value is greater than or equal to the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.Decimal,System.Decimal)">
+            <summary>
+            Verifies that the first value is greater than or equal to the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.Double,System.Double,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than or equal to the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.Double,System.Double,System.String)">
+            <summary>
+            Verifies that the first value is greater than or equal to the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.Double,System.Double)">
+            <summary>
+            Verifies that the first value is greater than or equal to the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.Single,System.Single,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than or equal to the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.Single,System.Single,System.String)">
+            <summary>
+            Verifies that the first value is greater than or equal to the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.Single,System.Single)">
+            <summary>
+            Verifies that the first value is greater than or equal to the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.IComparable,System.IComparable,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.IComparable,System.IComparable,System.String)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.IComparable,System.IComparable)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.Int32,System.Int32,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.Int32,System.Int32,System.String)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.Int32,System.Int32)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.UInt32,System.UInt32,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.UInt32,System.UInt32,System.String)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.UInt32,System.UInt32)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.Int64,System.Int64,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.Int64,System.Int64,System.String)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.Int64,System.Int64)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.UInt64,System.UInt64,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.UInt64,System.UInt64,System.String)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.UInt64,System.UInt64)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.Decimal,System.Decimal,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.Decimal,System.Decimal,System.String)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.Decimal,System.Decimal)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.Double,System.Double,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.Double,System.Double,System.String)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.Double,System.Double)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.Single,System.Single,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.Single,System.Single,System.String)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.Single,System.Single)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.IComparable,System.IComparable,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.IComparable,System.IComparable,System.String)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.IComparable,System.IComparable)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="P:NUnit.Framework.Assert.Counter">
+            <summary>
+            Gets the number of assertions executed so far and 
+            resets the counter to zero.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.MessageMatch">
+            <summary>
+            Enumeration indicating how the expected message parameter is to be used
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.MessageMatch.Exact">
+            Expect an exact match
+        </member>
+        <member name="F:NUnit.Framework.MessageMatch.Contains">
+            Expect a message containing the parameter string
+        </member>
+        <member name="F:NUnit.Framework.MessageMatch.Regex">
+            Match the regular expression provided as a parameter
+        </member>
+        <member name="T:NUnit.Framework.ExpectedExceptionAttribute">
+            <summary>
+            ExpectedExceptionAttribute
+            </summary>
+            
+        </member>
+        <member name="M:NUnit.Framework.ExpectedExceptionAttribute.#ctor">
+            <summary>
+            Constructor for a non-specific exception
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.ExpectedExceptionAttribute.#ctor(System.Type)">
+            <summary>
+            Constructor for a given type of exception
+            </summary>
+            <param name="exceptionType">The type of the expected exception</param>
+        </member>
+        <member name="M:NUnit.Framework.ExpectedExceptionAttribute.#ctor(System.String)">
+            <summary>
+            Constructor for a given exception name
+            </summary>
+            <param name="exceptionName">The full name of the expected exception</param>
+        </member>
+        <member name="M:NUnit.Framework.ExpectedExceptionAttribute.#ctor(System.Type,System.String)">
+            <summary>
+            Constructor for a given type of exception and expected message text
+            </summary>
+            <param name="exceptionType">The type of the expected exception</param>
+            <param name="expectedMessage">The expected message text</param>
+        </member>
+        <member name="M:NUnit.Framework.ExpectedExceptionAttribute.#ctor(System.String,System.String)">
+            <summary>
+            Constructor for a given exception name and expected message text
+            </summary>
+            <param name="exceptionName">The full name of the expected exception</param>
+            <param name="expectedMessage">The expected messge text</param>
+        </member>
+        <member name="P:NUnit.Framework.ExpectedExceptionAttribute.ExceptionType">
+            <summary>
+            Gets or sets the expected exception type
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.ExpectedExceptionAttribute.ExceptionName">
+            <summary>
+            Gets or sets the full Type name of the expected exception
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.ExpectedExceptionAttribute.ExpectedMessage">
+            <summary>
+            Gets or sets the expected message text
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.ExpectedExceptionAttribute.UserMessage">
+            <summary>
+            Gets or sets the user message displayed in case of failure
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.ExpectedExceptionAttribute.MatchType">
+            <summary>
+             Gets or sets the type of match to be performed on the expected message
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.ExpectedExceptionAttribute.Handler">
+            <summary>
+             Gets the name of a method to be used as an exception handler
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.CollectionAssert">
+            <summary>
+            A set of Assert methods operationg on one or more collections
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.Equals(System.Object,System.Object)">
+            <summary>
+            The Equals method throws an AssertionException. This is done 
+            to make sure there is no mistake by calling this function.
+            </summary>
+            <param name="a"></param>
+            <param name="b"></param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.ReferenceEquals(System.Object,System.Object)">
+            <summary>
+            override the default ReferenceEquals to throw an AssertionException. This 
+            implementation makes sure there is no mistake in calling this function 
+            as part of Assert. 
+            </summary>
+            <param name="a"></param>
+            <param name="b"></param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AllItemsAreInstancesOfType(System.Collections.ICollection,System.Type)">
+            <summary>
+            Asserts that all items contained in collection are of the type specified by expectedType.
+            </summary>
+            <param name="collection">ICollection of objects to be considered</param>
+            <param name="expectedType">System.Type that all objects in collection must be instances of</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AllItemsAreInstancesOfType(System.Collections.ICollection,System.Type,System.String)">
+            <summary>
+            Asserts that all items contained in collection are of the type specified by expectedType.
+            </summary>
+            <param name="collection">ICollection of objects to be considered</param>
+            <param name="expectedType">System.Type that all objects in collection must be instances of</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AllItemsAreInstancesOfType(System.Collections.ICollection,System.Type,System.String,System.Object[])">
+            <summary>
+            Asserts that all items contained in collection are of the type specified by expectedType.
+            </summary>
+            <param name="collection">ICollection of objects to be considered</param>
+            <param name="expectedType">System.Type that all objects in collection must be instances of</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AllItemsAreNotNull(System.Collections.ICollection)">
+            <summary>
+            Asserts that all items contained in collection are not equal to null.
+            </summary>
+            <param name="collection">ICollection of objects to be considered</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AllItemsAreNotNull(System.Collections.ICollection,System.String)">
+            <summary>
+            Asserts that all items contained in collection are not equal to null.
+            </summary>
+            <param name="collection">ICollection of objects to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AllItemsAreNotNull(System.Collections.ICollection,System.String,System.Object[])">
+            <summary>
+            Asserts that all items contained in collection are not equal to null.
+            </summary>
+            <param name="collection">ICollection of objects to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AllItemsAreUnique(System.Collections.ICollection)">
+            <summary>
+            Ensures that every object contained in collection exists within the collection
+            once and only once.
+            </summary>
+            <param name="collection">ICollection of objects to be considered</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AllItemsAreUnique(System.Collections.ICollection,System.String)">
+            <summary>
+            Ensures that every object contained in collection exists within the collection
+            once and only once.
+            </summary>
+            <param name="collection">ICollection of objects to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AllItemsAreUnique(System.Collections.ICollection,System.String,System.Object[])">
+            <summary>
+            Ensures that every object contained in collection exists within the collection
+            once and only once.
+            </summary>
+            <param name="collection">ICollection of objects to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreEqual(System.Collections.ICollection,System.Collections.ICollection)">
+            <summary>
+            Asserts that expected and actual are exactly equal.  The collections must have the same count, 
+            and contain the exact same objects in the same order.
+            </summary>
+            <param name="expected">The first ICollection of objects to be considered</param>
+            <param name="actual">The second ICollection of objects to be considered</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreEqual(System.Collections.ICollection,System.Collections.ICollection,System.Collections.IComparer)">
+            <summary>
+            Asserts that expected and actual are exactly equal.  The collections must have the same count, 
+            and contain the exact same objects in the same order.
+            If comparer is not null then it will be used to compare the objects.
+            </summary>
+            <param name="expected">The first ICollection of objects to be considered</param>
+            <param name="actual">The second ICollection of objects to be considered</param>
+            <param name="comparer">The IComparer to use in comparing objects from each ICollection</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreEqual(System.Collections.ICollection,System.Collections.ICollection,System.String)">
+            <summary>
+            Asserts that expected and actual are exactly equal.  The collections must have the same count, 
+            and contain the exact same objects in the same order.
+            </summary>
+            <param name="expected">The first ICollection of objects to be considered</param>
+            <param name="actual">The second ICollection of objects to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreEqual(System.Collections.ICollection,System.Collections.ICollection,System.Collections.IComparer,System.String)">
+            <summary>
+            Asserts that expected and actual are exactly equal.  The collections must have the same count, 
+            and contain the exact same objects in the same order.
+            If comparer is not null then it will be used to compare the objects.
+            </summary>
+            <param name="expected">The first ICollection of objects to be considered</param>
+            <param name="actual">The second ICollection of objects to be considered</param>
+            <param name="comparer">The IComparer to use in comparing objects from each ICollection</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreEqual(System.Collections.ICollection,System.Collections.ICollection,System.String,System.Object[])">
+            <summary>
+            Asserts that expected and actual are exactly equal.  The collections must have the same count, 
+            and contain the exact same objects in the same order.
+            </summary>
+            <param name="expected">The first ICollection of objects to be considered</param>
+            <param name="actual">The second ICollection of objects to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreEqual(System.Collections.ICollection,System.Collections.ICollection,System.Collections.IComparer,System.String,System.Object[])">
+            <summary>
+            Asserts that expected and actual are exactly equal.  The collections must have the same count, 
+            and contain the exact same objects in the same order.
+            If comparer is not null then it will be used to compare the objects.
+            </summary>
+            <param name="expected">The first ICollection of objects to be considered</param>
+            <param name="actual">The second ICollection of objects to be considered</param>
+            <param name="comparer">The IComparer to use in comparing objects from each ICollection</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreEquivalent(System.Collections.ICollection,System.Collections.ICollection)">
+            <summary>
+            Asserts that expected and actual are equivalent, containing the same objects but the match may be in any order.
+            </summary>
+            <param name="expected">The first ICollection of objects to be considered</param>
+            <param name="actual">The second ICollection of objects to be considered</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreEquivalent(System.Collections.ICollection,System.Collections.ICollection,System.String)">
+            <summary>
+            Asserts that expected and actual are equivalent, containing the same objects but the match may be in any order.
+            </summary>
+            <param name="expected">The first ICollection of objects to be considered</param>
+            <param name="actual">The second ICollection of objects to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreEquivalent(System.Collections.ICollection,System.Collections.ICollection,System.String,System.Object[])">
+            <summary>
+            Asserts that expected and actual are equivalent, containing the same objects but the match may be in any order.
+            </summary>
+            <param name="expected">The first ICollection of objects to be considered</param>
+            <param name="actual">The second ICollection of objects to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreNotEqual(System.Collections.ICollection,System.Collections.ICollection)">
+            <summary>
+            Asserts that expected and actual are not exactly equal.
+            </summary>
+            <param name="expected">The first ICollection of objects to be considered</param>
+            <param name="actual">The second ICollection of objects to be considered</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreNotEqual(System.Collections.ICollection,System.Collections.ICollection,System.Collections.IComparer)">
+            <summary>
+            Asserts that expected and actual are not exactly equal.
+            If comparer is not null then it will be used to compare the objects.
+            </summary>
+            <param name="expected">The first ICollection of objects to be considered</param>
+            <param name="actual">The second ICollection of objects to be considered</param>
+            <param name="comparer">The IComparer to use in comparing objects from each ICollection</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreNotEqual(System.Collections.ICollection,System.Collections.ICollection,System.String)">
+            <summary>
+            Asserts that expected and actual are not exactly equal.
+            </summary>
+            <param name="expected">The first ICollection of objects to be considered</param>
+            <param name="actual">The second ICollection of objects to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreNotEqual(System.Collections.ICollection,System.Collections.ICollection,System.Collections.IComparer,System.String)">
+            <summary>
+            Asserts that expected and actual are not exactly equal.
+            If comparer is not null then it will be used to compare the objects.
+            </summary>
+            <param name="expected">The first ICollection of objects to be considered</param>
+            <param name="actual">The second ICollection of objects to be considered</param>
+            <param name="comparer">The IComparer to use in comparing objects from each ICollection</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreNotEqual(System.Collections.ICollection,System.Collections.ICollection,System.String,System.Object[])">
+            <summary>
+            Asserts that expected and actual are not exactly equal.
+            </summary>
+            <param name="expected">The first ICollection of objects to be considered</param>
+            <param name="actual">The second ICollection of objects to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreNotEqual(System.Collections.ICollection,System.Collections.ICollection,System.Collections.IComparer,System.String,System.Object[])">
+            <summary>
+            Asserts that expected and actual are not exactly equal.
+            If comparer is not null then it will be used to compare the objects.
+            </summary>
+            <param name="expected">The first ICollection of objects to be considered</param>
+            <param name="actual">The second ICollection of objects to be considered</param>
+            <param name="comparer">The IComparer to use in comparing objects from each ICollection</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreNotEquivalent(System.Collections.ICollection,System.Collections.ICollection)">
+            <summary>
+            Asserts that expected and actual are not equivalent.
+            </summary>
+            <param name="expected">The first ICollection of objects to be considered</param>
+            <param name="actual">The second ICollection of objects to be considered</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreNotEquivalent(System.Collections.ICollection,System.Collections.ICollection,System.String)">
+            <summary>
+            Asserts that expected and actual are not equivalent.
+            </summary>
+            <param name="expected">The first ICollection of objects to be considered</param>
+            <param name="actual">The second ICollection of objects to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreNotEquivalent(System.Collections.ICollection,System.Collections.ICollection,System.String,System.Object[])">
+            <summary>
+            Asserts that expected and actual are not equivalent.
+            </summary>
+            <param name="expected">The first ICollection of objects to be considered</param>
+            <param name="actual">The second ICollection of objects to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.Contains(System.Collections.ICollection,System.Object)">
+            <summary>
+            Asserts that collection contains actual as an item.
+            </summary>
+            <param name="collection">ICollection of objects to be considered</param>
+            <param name="actual">Object to be found within collection</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.Contains(System.Collections.ICollection,System.Object,System.String)">
+            <summary>
+            Asserts that collection contains actual as an item.
+            </summary>
+            <param name="collection">ICollection of objects to be considered</param>
+            <param name="actual">Object to be found within collection</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.Contains(System.Collections.ICollection,System.Object,System.String,System.Object[])">
+            <summary>
+            Asserts that collection contains actual as an item.
+            </summary>
+            <param name="collection">ICollection of objects to be considered</param>
+            <param name="actual">Object to be found within collection</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.DoesNotContain(System.Collections.ICollection,System.Object)">
+            <summary>
+            Asserts that collection does not contain actual as an item.
+            </summary>
+            <param name="collection">ICollection of objects to be considered</param>
+            <param name="actual">Object that cannot exist within collection</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.DoesNotContain(System.Collections.ICollection,System.Object,System.String)">
+            <summary>
+            Asserts that collection does not contain actual as an item.
+            </summary>
+            <param name="collection">ICollection of objects to be considered</param>
+            <param name="actual">Object that cannot exist within collection</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.DoesNotContain(System.Collections.ICollection,System.Object,System.String,System.Object[])">
+            <summary>
+            Asserts that collection does not contain actual as an item.
+            </summary>
+            <param name="collection">ICollection of objects to be considered</param>
+            <param name="actual">Object that cannot exist within collection</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.IsNotSubsetOf(System.Collections.ICollection,System.Collections.ICollection)">
+            <summary>
+            Asserts that superset is not a subject of subset.
+            </summary>
+            <param name="subset">The ICollection superset to be considered</param>
+            <param name="superset">The ICollection subset to be considered</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.IsNotSubsetOf(System.Collections.ICollection,System.Collections.ICollection,System.String)">
+            <summary>
+            Asserts that superset is not a subject of subset.
+            </summary>
+            <param name="subset">The ICollection superset to be considered</param>
+            <param name="superset">The ICollection subset to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.IsNotSubsetOf(System.Collections.ICollection,System.Collections.ICollection,System.String,System.Object[])">
+            <summary>
+            Asserts that superset is not a subject of subset.
+            </summary>
+            <param name="subset">The ICollection superset to be considered</param>
+            <param name="superset">The ICollection subset to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.IsSubsetOf(System.Collections.ICollection,System.Collections.ICollection)">
+            <summary>
+            Asserts that superset is a subset of subset.
+            </summary>
+            <param name="subset">The ICollection superset to be considered</param>
+            <param name="superset">The ICollection subset to be considered</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.IsSubsetOf(System.Collections.ICollection,System.Collections.ICollection,System.String)">
+            <summary>
+            Asserts that superset is a subset of subset.
+            </summary>
+            <param name="subset">The ICollection superset to be considered</param>
+            <param name="superset">The ICollection subset to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.IsSubsetOf(System.Collections.ICollection,System.Collections.ICollection,System.String,System.Object[])">
+            <summary>
+            Asserts that superset is a subset of subset.
+            </summary>
+            <param name="subset">The ICollection superset to be considered</param>
+            <param name="superset">The ICollection subset to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.IsEmpty(System.Collections.ICollection,System.String,System.Object[])">
+            <summary>
+            Assert that an array, list or other collection is empty
+            </summary>
+            <param name="collection">An array, list or other collection implementing ICollection</param>
+            <param name="message">The message to be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.IsEmpty(System.Collections.ICollection,System.String)">
+            <summary>
+            Assert that an array, list or other collection is empty
+            </summary>
+            <param name="collection">An array, list or other collection implementing ICollection</param>
+            <param name="message">The message to be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.IsEmpty(System.Collections.ICollection)">
+            <summary>
+            Assert that an array,list or other collection is empty
+            </summary>
+            <param name="collection">An array, list or other collection implementing ICollection</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.IsNotEmpty(System.Collections.ICollection,System.String,System.Object[])">
+            <summary>
+            Assert that an array, list or other collection is empty
+            </summary>
+            <param name="collection">An array, list or other collection implementing ICollection</param>
+            <param name="message">The message to be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.IsNotEmpty(System.Collections.ICollection,System.String)">
+            <summary>
+            Assert that an array, list or other collection is empty
+            </summary>
+            <param name="collection">An array, list or other collection implementing ICollection</param>
+            <param name="message">The message to be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.IsNotEmpty(System.Collections.ICollection)">
+            <summary>
+            Assert that an array,list or other collection is empty
+            </summary>
+            <param name="collection">An array, list or other collection implementing ICollection</param>
+        </member>
+        <member name="T:NUnit.Framework.AbstractAsserter">
+            <summary>
+            NOTE: The use of asserters for extending NUnit has
+            now been replaced by the use of constraints. This
+            class is marked obsolete.
+            
+            AbstractAsserter is the base class for all asserters.
+            Asserters encapsulate a condition test and generation 
+            of an AssertionException with a tailored message. They
+            are used by the Assert class as helper objects.
+            
+            User-defined asserters may be passed to the 
+            Assert.DoAssert method in order to implement 
+            extended asserts.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.IAsserter">
+            <summary>
+            NOTE: The use of asserters for extending NUnit has
+            now been replaced by the use of constraints. This
+            interface is marked obsolete.
+            
+            The interface implemented by an asserter. Asserters
+            encapsulate a condition test and generation of an
+            AssertionException with a tailored message. They
+            are used by the Assert class as helper objects.
+            
+            User-defined asserters may be passed to the
+            Assert.DoAssert method in order to implement
+            extended asserts.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.IAsserter.Test">
+            <summary>
+            Test the condition for the assertion.
+            </summary>
+            <returns>True if the test succeeds</returns>
+        </member>
+        <member name="P:NUnit.Framework.IAsserter.Message">
+            <summary>
+            Return the message giving the failure reason.
+            The return value is unspecified if no failure
+            has occured.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.AbstractAsserter.userMessage">
+            <summary>
+            The user-defined message for this asserter.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.AbstractAsserter.args">
+            <summary>
+            Arguments to use in formatting the user-defined message.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.AbstractAsserter.failureMessage">
+            <summary>
+            Our failure message object, initialized as needed
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.AbstractAsserter.#ctor(System.String,System.Object[])">
+            <summary>
+            Constructs an AbstractAsserter
+            </summary>
+            <param name="message">The message issued upon failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.AbstractAsserter.Test">
+            <summary>
+            Test method to be implemented by derived types.
+            Default always succeeds.
+            </summary>
+            <returns>True if the test succeeds</returns>
+        </member>
+        <member name="P:NUnit.Framework.AbstractAsserter.FailureMessage">
+            <summary>
+            AssertionFailureMessage object used internally
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.AbstractAsserter.Message">
+            <summary>
+            Message related to a failure. If no failure has
+            occured, the result is unspecified.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Assertion">
+            <summary>
+            The Assertion class is obsolete and has been
+            replaced by the Assert class.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Assertion.Assert(System.String,System.Boolean)">
+            <summary>
+            Asserts that a condition is true. If it isn't it throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>.
+            </summary>
+            <param name="message">The message to display is the condition
+            is false</param>
+            <param name="condition">The evaluated condition</param>
+        </member>
+        <member name="M:NUnit.Framework.Assertion.Assert(System.Boolean)">
+            <summary>
+            Asserts that a condition is true. If it isn't it throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>.
+            </summary>
+            <param name="condition">The evaluated condition</param>
+        </member>
+        <member name="M:NUnit.Framework.Assertion.AssertEquals(System.Double,System.Double,System.Double)">
+            <summary>
+            /// Asserts that two doubles are equal concerning a delta. If the
+            expected value is infinity then the delta value is ignored.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="delta">The maximum acceptable difference between the
+            the expected and the actual</param>
+        </member>
+        <member name="M:NUnit.Framework.Assertion.AssertEquals(System.Single,System.Single,System.Single)">
+            <summary>
+            /// Asserts that two singles are equal concerning a delta. If the
+            expected value is infinity then the delta value is ignored.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="delta">The maximum acceptable difference between the
+            the expected and the actual</param>
+        </member>
+        <member name="M:NUnit.Framework.Assertion.AssertEquals(System.Object,System.Object)">
+            <summary>Asserts that two objects are equal. If they are not
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.</summary>
+        </member>
+        <member name="M:NUnit.Framework.Assertion.AssertEquals(System.Int32,System.Int32)">
+            <summary>Asserts that two ints are equal. If they are not
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.</summary>
+        </member>
+        <member name="M:NUnit.Framework.Assertion.AssertEquals(System.String,System.Int32,System.Int32)">
+            <summary>Asserts that two ints are equal. If they are not
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.</summary>
+        </member>
+        <member name="M:NUnit.Framework.Assertion.AssertEquals(System.String,System.Double,System.Double,System.Double)">
+            <summary>Asserts that two doubles are equal concerning a delta.
+            If the expected value is infinity then the delta value is ignored.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Assertion.AssertEquals(System.String,System.Single,System.Single,System.Single)">
+            <summary>Asserts that two floats are equal concerning a delta.
+            If the expected value is infinity then the delta value is ignored.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Assertion.AssertEquals(System.String,System.Object,System.Object)">
+            <summary>
+            Asserts that two objects are equal.  Two objects are considered
+            equal if both are null, or if both have the same value.  Numeric
+            types are compared via string comparision on their contents to
+            avoid problems comparing values between different types.  All
+            non-numeric types are compared by using the <c>Equals</c> method.
+            If they are not equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Assertion.AssertNotNull(System.Object)">
+            <summary>Asserts that an object isn't null.</summary>
+        </member>
+        <member name="M:NUnit.Framework.Assertion.AssertNotNull(System.String,System.Object)">
+            <summary>Asserts that an object isn't null.</summary>
+        </member>
+        <member name="M:NUnit.Framework.Assertion.AssertNull(System.Object)">
+            <summary>Asserts that an object is null.</summary>
+        </member>
+        <member name="M:NUnit.Framework.Assertion.AssertNull(System.String,System.Object)">
+            <summary>Asserts that an object is null.</summary>
+        </member>
+        <member name="M:NUnit.Framework.Assertion.AssertSame(System.Object,System.Object)">
+            <summary>Asserts that two objects refer to the same object. If they
+            are not the same an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Assertion.AssertSame(System.String,System.Object,System.Object)">
+            <summary>Asserts that two objects refer to the same object. 
+            If they are not an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Assertion.Fail">
+            <summary>Fails a test with no message.</summary>
+        </member>
+        <member name="M:NUnit.Framework.Assertion.Fail(System.String)">
+            <summary>Fails a test with the given message.</summary>
+        </member>
+        <member name="T:NUnit.Framework.AssertionException">
+            <summary>
+            Thrown when an assertion failed.
+            </summary>
+            
+        </member>
+        <member name="M:NUnit.Framework.AssertionException.#ctor(System.String)">
+            <param name="message">The error message that explains 
+            the reason for the exception</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionException.#ctor(System.String,System.Exception)">
+            <param name="message">The error message that explains 
+            the reason for the exception</param>
+            <param name="inner">The exception that caused the 
+            current exception</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionException.#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)">
+            <summary>
+            Serialization Constructor
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.AssertionFailureMessage">
+            <summary>
+            AssertionFailureMessage encapsulates a failure message
+            issued as a result of an Assert failure.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.AssertionFailureMessage.PreClipLength">
+            <summary>
+            Number of characters before a highlighted position before
+            clipping will occur.  Clipped text is replaced with an
+            elipsis "..."
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.AssertionFailureMessage.PostClipLength">
+            <summary>
+            Number of characters after a highlighted position before
+            clipping will occur.  Clipped text is replaced with an
+            elipsis "..."
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.AssertionFailureMessage.expectedPrefix">
+            <summary>
+            Prefix used to start an expected value line.
+            Must be same length as actualPrefix.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.AssertionFailureMessage.actualPrefix">
+            <summary>
+            Prefix used to start an actual value line.
+            Must be same length as expectedPrefix.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.AssertionFailureMessage.#ctor(System.String,System.Object[])">
+            <summary>
+            Construct an AssertionFailureMessage with a message
+            and optional arguments.
+            </summary>
+            <param name="message"></param>
+            <param name="args"></param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionFailureMessage.#ctor">
+            <summary>
+            Construct an empty AssertionFailureMessage
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.AssertionFailureMessage.WriteExpectedLine(System.String)">
+            <summary>
+            Add an expected value line to the message containing
+            the text provided as an argument.
+            </summary>
+            <param name="text">Text describing what was expected.</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionFailureMessage.WriteActualLine(System.String)">
+            <summary>
+            Add an actual value line to the message containing
+            the text provided as an argument.
+            </summary>
+            <param name="text">Text describing the actual value.</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionFailureMessage.DisplayExpectedValue(System.Object)">
+            <summary>
+            Add an expected value line to the message containing
+            a string representation of the object provided.
+            </summary>
+            <param name="expected">An object representing the expected value</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionFailureMessage.DisplayExpectedValue(System.Double,System.Double)">
+            <summary>
+            Add an expected value line to the message containing a double
+            and the tolerance used in making the comparison.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="tolerance">The tolerance specified in the Assert</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionFailureMessage.DisplayActualValue(System.Object)">
+            <summary>
+            Add an actual value line to the message containing
+            a string representation of the object provided.
+            </summary>
+            <param name="actual">An object representing what was actually found</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionFailureMessage.DisplayExpectedAndActual(System.Object,System.Object)">
+            <summary>
+            Display two lines that communicate the expected value, and the actual value
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value found</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionFailureMessage.DisplayExpectedAndActual(System.Double,System.Double,System.Double)">
+            <summary>
+            Display two lines that communicate the expected value, the actual value and
+            the tolerance used in comparing two doubles.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value found</param>
+            <param name="tolerance">The tolerance specified in the Assert</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionFailureMessage.DisplayPositionMarker(System.Int32)">
+            <summary>
+            Draws a marker under the expected/actual strings that highlights
+            where in the string a mismatch occurred.
+            </summary>
+            <param name="iPosition">The position of the mismatch</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionFailureMessage.BuildStringLengthReport(System.String,System.String)">
+            <summary>
+            Reports whether the string lengths are the same or different, and
+            what the string lengths are.
+            </summary>
+            <param name="sExpected">The expected string</param>
+            <param name="sActual">The actual string value</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionFailureMessage.DisplayDifferences(System.Object,System.Object,System.Boolean)">
+            <summary>
+            Called to create additional message lines when two objects have been 
+            found to be unequal.  If the inputs are strings, a special message is
+            rendered that can help track down where the strings are different,
+            based on differences in length, or differences in content.
+            
+            If the inputs are not strings, the ToString method of the objects
+            is used to show what is different about them.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="caseInsensitive">True if a case-insensitive comparison is being performed</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionFailureMessage.DisplayDifferencesWithTolerance(System.Double,System.Double,System.Double)">
+            <summary>
+            Called to create additional message lines when two doubles have been 
+            found to be unequal, within the specified tolerance.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.AssertionFailureMessage.DisplayStringDifferences(System.String,System.String,System.Boolean)">
+            <summary>
+            Constructs a message that can be displayed when the content of two
+            strings are different, but the string lengths are the same.  The
+            message will clip the strings to a reasonable length, centered
+            around the first position where they are mismatched, and draw 
+            a line marking the position of the difference to make comparison
+            quicker.
+            </summary>
+            <param name="sExpected">The expected string value</param>
+            <param name="sActual">The actual string value</param>
+            <param name="caseInsensitive">True if a case-insensitive comparison is being performed</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionFailureMessage.DisplayArrayDifferences(System.Array,System.Array,System.Int32)">
+            <summary>
+            Display a standard message showing the differences found between 
+            two arrays that were expected to be equal.
+            </summary>
+            <param name="expected">The expected array value</param>
+            <param name="actual">The actual array value</param>
+            <param name="index">The index at which a difference was found</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionFailureMessage.DisplayCollectionDifferences(System.Collections.ICollection,System.Collections.ICollection,System.Int32)">
+            <summary>
+            Display a standard message showing the differences found between 
+            two collections that were expected to be equal.
+            </summary>
+            <param name="expected">The expected collection value</param>
+            <param name="actual">The actual collection value</param>
+            <param name="index">The index at which a difference was found</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionFailureMessage.GetArrayIndicesFromCollectionIndex(System.Collections.ICollection,System.Int32)">
+            <summary>
+            Get an array of indices representing the point in a collection or
+            array corresponding to a single int index into the collection.
+            </summary>
+            <param name="collection">The collection to which the indices apply</param>
+            <param name="index">Index in the collection</param>
+            <returns>Array of indices</returns>
+        </member>
+        <member name="M:NUnit.Framework.AssertionFailureMessage.DisplayListElements(System.String,System.Collections.IList,System.Int32,System.Int32)">
+            <summary>
+            Displays elements from a list on a line
+            </summary>
+            <param name="label">Text to prefix the line with</param>
+            <param name="list">The list of items to display</param>
+            <param name="index">The index in the list of the first element to display</param>
+            <param name="max">The maximum number of elements to display</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionFailureMessage.FormatObjectForDisplay(System.Object)">
+            <summary>
+            Formats an object for display in a message line
+            </summary>
+            <param name="obj">The object to be displayed</param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.AssertionFailureMessage.InputsAreStrings(System.Object,System.Object)">
+            <summary>
+            Tests two objects to determine if they are strings.
+            </summary>
+            <param name="expected"></param>
+            <param name="actual"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.AssertionFailureMessage.ClipAroundPosition(System.String,System.Int32)">
+            <summary>
+            Renders up to M characters before, and up to N characters after
+            the specified index position.  If leading or trailing text is
+            clipped, and elipses "..." is added where the missing text would
+            be.
+            
+            Clips strings to limit previous or post newline characters,
+            since these mess up the comparison
+            </summary>
+            <param name="sString"></param>
+            <param name="iPosition"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.AssertionFailureMessage.FindMismatchPosition(System.String,System.String,System.Int32)">
+            <summary>
+            Shows the position two strings start to differ.  Comparison 
+            starts at the start index.
+            </summary>
+            <param name="sExpected"></param>
+            <param name="sActual"></param>
+            <param name="iStart"></param>
+            <returns>-1 if no mismatch found, or the index where mismatch found</returns>
+        </member>
+        <member name="M:NUnit.Framework.AssertionFailureMessage.ConvertWhitespace(System.String)">
+            <summary>
+            Turns CR, LF, or TAB into visual indicator to preserve visual marker 
+            position.   This is done by replacing the '\r' into '\\' and 'r' 
+            characters, and the '\n' into '\\' and 'n' characters, and '\t' into
+            '\\' and 't' characters.  
+            
+            Thus the single character becomes two characters for display.
+            </summary>
+            <param name="sInput"></param>
+            <returns></returns>
+        </member>
+        <member name="T:NUnit.Framework.CategoryAttribute">
+            <summary>
+            Attribute used to apply a category to a test
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.CategoryAttribute.categoryName">
+            <summary>
+            The name of the category
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.CategoryAttribute.#ctor(System.String)">
+            <summary>
+            Construct attribute for a given category
+            </summary>
+            <param name="name">The name of the category</param>
+        </member>
+        <member name="M:NUnit.Framework.CategoryAttribute.#ctor">
+            <summary>
+            Protected constructor uses the Type name as the name
+            of the category.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.CategoryAttribute.Name">
+            <summary>
+            The name of the category
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.IncludeExcludeAttribute">
+            <summary>
+            Abstract base for Attributes that are used to include tests
+            in the test run based on environmental settings.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.IncludeExcludeAttribute.#ctor">
+            <summary>
+            Constructor with no included items specified, for use
+            with named property syntax.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.IncludeExcludeAttribute.#ctor(System.String)">
+            <summary>
+            Constructor taking one or more included items
+            </summary>
+            <param name="include">Comma-delimited list of included items</param>
+        </member>
+        <member name="P:NUnit.Framework.IncludeExcludeAttribute.Include">
+            <summary>
+            Name of the item that is needed in order for
+            a test to run. Multiple itemss may be given,
+            separated by a comma.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.IncludeExcludeAttribute.Exclude">
+            <summary>
+            Name of the item to be excluded. Multiple items
+            may be given, separated by a comma.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.IncludeExcludeAttribute.Reason">
+            <summary>
+            The reason for including or excluding the test
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.PlatformAttribute">
+            <summary>
+            PlatformAttribute is used to mark a test fixture or an
+            individual method as applying to a particular platform only.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.PlatformAttribute.#ctor">
+            <summary>
+            Constructor with no platforms specified, for use
+            with named property syntax.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.PlatformAttribute.#ctor(System.String)">
+            <summary>
+            Constructor taking one or more platforms
+            </summary>
+            <param name="platforms">Comma-deliminted list of platforms</param>
+        </member>
+        <member name="T:NUnit.Framework.CultureAttribute">
+            <summary>
+            CultureAttribute is used to mark a test fixture or an
+            individual method as applying to a particular Culture only.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.CultureAttribute.#ctor">
+            <summary>
+            Constructor with no cultures specified, for use
+            with named property syntax.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.CultureAttribute.#ctor(System.String)">
+            <summary>
+            Constructor taking one or more cultures
+            </summary>
+            <param name="cultures">Comma-deliminted list of cultures</param>
+        </member>
+        <member name="T:NUnit.Framework.MessageWriter">
+            <summary>
+            MessageWriter is the abstract base for classes that write
+            constraint descriptions and messages in some form. The
+            class has separate methods for writing various components
+            of a message, allowing implementations to tailor the
+            presentation as needed.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.MessageWriter.#ctor">
+            <summary>
+            Construct a MessageWriter given a culture
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.MessageWriter.WriteMessageLine(System.String,System.Object[])">
+            <summary>
+            Method to write single line  message with optional args, usually
+            written to precede the general failure message.
+            </summary>
+            <param name="message">The message to be written</param>
+            <param name="args">Any arguments used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.MessageWriter.WriteMessageLine(System.Int32,System.String,System.Object[])">
+            <summary>
+            Method to write single line  message with optional args, usually
+            written to precede the general failure message, at a givel 
+            indentation level.
+            </summary>
+            <param name="level">The indentation level of the message</param>
+            <param name="message">The message to be written</param>
+            <param name="args">Any arguments used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.MessageWriter.DisplayDifferences(NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Display Expected and Actual lines for a constraint. This
+            is called by MessageWriter's default implementation of 
+            WriteMessageTo and provides the generic two-line display. 
+            </summary>
+            <param name="constraint">The constraint that failed</param>
+        </member>
+        <member name="M:NUnit.Framework.MessageWriter.DisplayDifferences(System.Object,System.Object)">
+            <summary>
+            Display Expected and Actual lines for given values. This
+            method may be called by constraints that need more control over
+            the display of actual and expected values than is provided
+            by the default implementation.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value causing the failure</param>
+        </member>
+        <member name="M:NUnit.Framework.MessageWriter.DisplayDifferences(System.Object,System.Object,System.Object)">
+            <summary>
+            Display Expected and Actual lines for given values, including
+            a tolerance value on the Expected line.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value causing the failure</param>
+            <param name="tolerance">The tolerance within which the test was made</param>
+        </member>
+        <member name="M:NUnit.Framework.MessageWriter.DisplayStringDifferences(System.String,System.String,System.Int32,System.Boolean)">
+            <summary>
+            Display the expected and actual string values on separate lines.
+            If the mismatch parameter is >=0, an additional line is displayed
+            line containing a caret that points to the mismatch point.
+            </summary>
+            <param name="expected">The expected string value</param>
+            <param name="actual">The actual string value</param>
+            <param name="mismatch">The point at which the strings don't match or -1</param>
+            <param name="ignoreCase">If true, case is ignored in locating the point where the strings differ</param>
+        </member>
+        <member name="M:NUnit.Framework.MessageWriter.WriteConnector(System.String)">
+            <summary>
+            Writes the text for a connector.
+            </summary>
+            <param name="connector">The connector.</param>
+        </member>
+        <member name="M:NUnit.Framework.MessageWriter.WritePredicate(System.String)">
+            <summary>
+            Writes the text for a predicate.
+            </summary>
+            <param name="predicate">The predicate.</param>
+        </member>
+        <member name="M:NUnit.Framework.MessageWriter.WriteExpectedValue(System.Object)">
+            <summary>
+            Writes the text for an expected value.
+            </summary>
+            <param name="expected">The expected value.</param>
+        </member>
+        <member name="M:NUnit.Framework.MessageWriter.WriteModifier(System.String)">
+            <summary>
+            Writes the text for a modifier
+            </summary>
+            <param name="modifier">The modifier.</param>
+        </member>
+        <member name="M:NUnit.Framework.MessageWriter.WriteActualValue(System.Object)">
+            <summary>
+            Writes the text for an actual value.
+            </summary>
+            <param name="actual">The actual value.</param>
+        </member>
+        <member name="M:NUnit.Framework.MessageWriter.WriteValue(System.Object)">
+            <summary>
+            Writes the text for a generalized value.
+            </summary>
+            <param name="val">The value.</param>
+        </member>
+        <member name="M:NUnit.Framework.MessageWriter.WriteCollectionElements(System.Collections.ICollection,System.Int32,System.Int32)">
+            <summary>
+            Writes the text for a collection value,
+            starting at a particular point, to a max length
+            </summary>
+            <param name="collection">The collection containing elements to write.</param>
+            <param name="start">The starting point of the elements to write</param>
+            <param name="max">The maximum number of elements to write</param>
+        </member>
+        <member name="P:NUnit.Framework.MessageWriter.MaxLineLength">
+            <summary>
+            Abstract method to get the max line length
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.SetCultureAttribute">
+            <summary>
+            Summary description for SetCultureAttribute.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.PropertyAttribute">
+            <summary>
+            PropertyAttribute is used to attach information to a test as a name/value pair..
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.PropertyAttribute.propertyName">
+            <summary>
+            The property name
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.PropertyAttribute.propertyValue">
+            <summary>
+            The property value
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.PropertyAttribute.#ctor(System.String,System.Object)">
+            <summary>
+            Construct a PropertyAttribute with a name and value
+            </summary>
+            <param name="propertyName">The name of the property</param>
+            <param name="propertyValue">The property value</param>
+        </member>
+        <member name="M:NUnit.Framework.PropertyAttribute.#ctor(System.Object)">
+            <summary>
+            Constructor for use by inherited classes that use the
+            name of the type as the property name.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.PropertyAttribute.Name">
+            <summary>
+            Gets the property name
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.PropertyAttribute.Value">
+            <summary>
+            Gets the property value
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.SetCultureAttribute.#ctor(System.String)">
+            <summary>
+            Construct given the name of a culture
+            </summary>
+            <param name="culture"></param>
+        </member>
+        <member name="T:NUnit.Framework.TextMessageWriter">
+            <summary>
+            TextMessageWriter writes constraint descriptions and messages
+            in displayable form as a text stream. It tailors the display
+            of individual message components to form the standard message
+            format of NUnit assertion failure messages.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.TextMessageWriter.Pfx_Expected">
+            <summary>
+            Prefix used for the expected value line of a message
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.TextMessageWriter.Pfx_Actual">
+            <summary>
+            Prefix used for the actual value line of a message
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.TextMessageWriter.PrefixLength">
+            <summary>
+            Length of a message prefix
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.#ctor">
+            <summary>
+            Construct a TextMessageWriter
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.#ctor(System.String,System.Object[])">
+            <summary>
+            Construct a TextMessageWriter, specifying a user message
+            and optional formatting arguments.
+            </summary>
+            <param name="userMessage"></param>
+            <param name="args"></param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.WriteMessageLine(System.Int32,System.String,System.Object[])">
+            <summary>
+            Method to write single line  message with optional args, usually
+            written to precede the general failure message, at a givel 
+            indentation level.
+            </summary>
+            <param name="level">The indentation level of the message</param>
+            <param name="message">The message to be written</param>
+            <param name="args">Any arguments used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.DisplayDifferences(NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Display Expected and Actual lines for a constraint. This
+            is called by MessageWriter's default implementation of 
+            WriteMessageTo and provides the generic two-line display. 
+            </summary>
+            <param name="constraint">The constraint that failed</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.DisplayDifferences(System.Object,System.Object)">
+            <summary>
+            Display Expected and Actual lines for given values. This
+            method may be called by constraints that need more control over
+            the display of actual and expected values than is provided
+            by the default implementation.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value causing the failure</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.DisplayDifferences(System.Object,System.Object,System.Object)">
+            <summary>
+            Display Expected and Actual lines for given values, including
+            a tolerance value on the expected line.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value causing the failure</param>
+            <param name="tolerance">The tolerance within which the test was made</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.DisplayStringDifferences(System.String,System.String,System.Int32,System.Boolean)">
+            <summary>
+            Display the expected and actual string values on separate lines.
+            If the mismatch parameter is >=0, an additional line is displayed
+            line containing a caret that points to the mismatch point.
+            </summary>
+            <param name="expected">The expected string value</param>
+            <param name="actual">The actual string value</param>
+            <param name="mismatch">The point at which the strings don't match or -1</param>
+            <param name="ignoreCase">If true, case is ignored in string comparisons</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.WriteConnector(System.String)">
+            <summary>
+            Writes the text for a connector.
+            </summary>
+            <param name="connector">The connector.</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.WritePredicate(System.String)">
+            <summary>
+            Writes the text for a predicate.
+            </summary>
+            <param name="predicate">The predicate.</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.WriteModifier(System.String)">
+            <summary>
+            Write the text for a modifier.
+            </summary>
+            <param name="modifier">The modifier.</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.WriteExpectedValue(System.Object)">
+            <summary>
+            Writes the text for an expected value.
+            </summary>
+            <param name="expected">The expected value.</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.WriteActualValue(System.Object)">
+            <summary>
+            Writes the text for an actual value.
+            </summary>
+            <param name="actual">The actual value.</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.WriteValue(System.Object)">
+            <summary>
+            Writes the text for a generalized value.
+            </summary>
+            <param name="val">The value.</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.WriteCollectionElements(System.Collections.ICollection,System.Int32,System.Int32)">
+            <summary>
+            Writes the text for a collection value,
+            starting at a particular point, to a max length
+            </summary>
+            <param name="collection">The collection containing elements to write.</param>
+            <param name="start">The starting point of the elements to write</param>
+            <param name="max">The maximum number of elements to write</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.WriteExpectedLine(NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Write the generic 'Expected' line for a constraint
+            </summary>
+            <param name="constraint">The constraint that failed</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.WriteExpectedLine(System.Object)">
+            <summary>
+            Write the generic 'Expected' line for a given value
+            </summary>
+            <param name="expected">The expected value</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.WriteExpectedLine(System.Object,System.Object)">
+            <summary>
+            Write the generic 'Expected' line for a given value
+            and tolerance.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="tolerance">The tolerance within which the test was made</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.WriteActualLine(NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Write the generic 'Actual' line for a constraint
+            </summary>
+            <param name="constraint">The constraint for which the actual value is to be written</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.WriteActualLine(System.Object)">
+            <summary>
+            Write the generic 'Actual' line for a given value
+            </summary>
+            <param name="actual">The actual value causing a failure</param>
+        </member>
+        <member name="P:NUnit.Framework.TextMessageWriter.MaxLineLength">
+            <summary>
+            Gets the maximum line length for this writer
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.StringAssert">
+            <summary>
+            Basic Asserts on strings.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.Equals(System.Object,System.Object)">
+            <summary>
+            The Equals method throws an AssertionException. This is done 
+            to make sure there is no mistake by calling this function.
+            </summary>
+            <param name="a"></param>
+            <param name="b"></param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.ReferenceEquals(System.Object,System.Object)">
+            <summary>
+            override the default ReferenceEquals to throw an AssertionException. This 
+            implementation makes sure there is no mistake in calling this function 
+            as part of Assert. 
+            </summary>
+            <param name="a"></param>
+            <param name="b"></param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.Contains(System.String,System.String,System.String,System.Object[])">
+            <summary>
+            Asserts that a string is found within another string.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The string to be examined</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Arguments used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.Contains(System.String,System.String,System.String)">
+            <summary>
+            Asserts that a string is found within another string.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The string to be examined</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.Contains(System.String,System.String)">
+            <summary>
+            Asserts that a string is found within another string.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The string to be examined</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.StartsWith(System.String,System.String,System.String,System.Object[])">
+            <summary>
+            Asserts that a string starts with another string.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The string to be examined</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Arguments used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.StartsWith(System.String,System.String,System.String)">
+            <summary>
+            Asserts that a string starts with another string.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The string to be examined</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.StartsWith(System.String,System.String)">
+            <summary>
+            Asserts that a string starts with another string.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The string to be examined</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.EndsWith(System.String,System.String,System.String,System.Object[])">
+            <summary>
+            Asserts that a string ends with another string.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The string to be examined</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Arguments used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.EndsWith(System.String,System.String,System.String)">
+            <summary>
+            Asserts that a string ends with another string.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The string to be examined</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.EndsWith(System.String,System.String)">
+            <summary>
+            Asserts that a string ends with another string.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The string to be examined</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.AreEqualIgnoringCase(System.String,System.String,System.String,System.Object[])">
+            <summary>
+            Asserts that two strings are equal, without regard to case.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The actual string</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Arguments used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.AreEqualIgnoringCase(System.String,System.String,System.String)">
+            <summary>
+            Asserts that two strings are equal, without regard to case.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The actual string</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.AreEqualIgnoringCase(System.String,System.String)">
+            <summary>
+            Asserts that two strings are equal, without regard to case.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The actual string</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.IsMatch(System.String,System.String,System.String,System.Object[])">
+            <summary>
+            Asserts that a string matches an expected regular expression pattern.
+            </summary>
+            <param name="expected">The expected expression</param>
+            <param name="actual">The actual string</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Arguments used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.IsMatch(System.String,System.String,System.String)">
+            <summary>
+            Asserts that a string matches an expected regular expression pattern.
+            </summary>
+            <param name="expected">The expected expression</param>
+            <param name="actual">The actual string</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.IsMatch(System.String,System.String)">
+            <summary>
+            Asserts that a string matches an expected regular expression pattern.
+            </summary>
+            <param name="expected">The expected expression</param>
+            <param name="actual">The actual string</param>
+        </member>
+        <member name="T:NUnit.Framework.MsgUtils">
+            <summary>
+            Static methods used in creating messages
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.MsgUtils.GetTypeRepresentation(System.Object)">
+            <summary>
+            Returns the representation of a type as used in NUnitLite.
+            This is the same as Type.ToString() except for arrays,
+            which are displayed with their declared sizes.
+            </summary>
+            <param name="obj"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.MsgUtils.ConvertWhitespace(System.String)">
+            <summary>
+            Converts any control characters in a string 
+            to their escaped representation.
+            </summary>
+            <param name="s">The string to be converted</param>
+            <returns>The converted string</returns>
+        </member>
+        <member name="M:NUnit.Framework.MsgUtils.GetArrayIndicesAsString(System.Int32[])">
+            <summary>
+            Return the a string representation for a set of indices into an array
+            </summary>
+            <param name="indices">Array of indices for which a string is needed</param>
+        </member>
+        <member name="M:NUnit.Framework.MsgUtils.GetArrayIndicesFromCollectionIndex(System.Collections.ICollection,System.Int32)">
+            <summary>
+            Get an array of indices representing the point in a collection or
+            array corresponding to a single int index into the collection.
+            </summary>
+            <param name="collection">The collection to which the indices apply</param>
+            <param name="index">Index in the collection</param>
+            <returns>Array of indices</returns>
+        </member>
+        <member name="M:NUnit.Framework.MsgUtils.ClipString(System.String,System.Int32,System.Int32)">
+            <summary>
+            Clip a string around a particular point, returning the clipped
+            string with ellipses representing the removed parts
+            </summary>
+            <param name="s">The string to be clipped</param>
+            <param name="maxStringLength">The maximum permitted length of the result string</param>
+            <param name="mismatch">The point around which clipping is to occur</param>
+            <returns>The clipped string</returns>
+        </member>
+        <member name="M:NUnit.Framework.MsgUtils.FindMismatchPosition(System.String,System.String,System.Int32,System.Boolean)">
+            <summary>
+            Shows the position two strings start to differ.  Comparison 
+            starts at the start index.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The actual string</param>
+            <param name="istart">The index in the strings at which comparison should start</param>
+            <param name="ignoreCase">Boolean indicating whether case should be ignored</param>
+            <returns>-1 if no mismatch found, or the index where mismatch found</returns>
+        </member>
+        <member name="T:NUnit.Framework.AssertionHelper">
+            <summary>
+            AssertionHelper is an optional base class for user tests,
+            allowing the use of shorter names for constraints and
+            asserts and avoiding conflict with the definition of 
+            <see cref="T:NUnit.Framework.SyntaxHelpers.Is"/>, from which it inherits much of its
+            behavior, in certain mock object frameworks.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.AssertionHelper.Expect(System.Object,NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Apply a constraint to an actual value, succeeding if the constraint
+            is satisfied and throwing an assertion exception on failure. Works
+            identically to <see cref="M:NUnit.Framework.Assert.That(System.Object,NUnit.Framework.Constraints.Constraint)"/>
+            </summary>
+            <param name="constraint">A Constraint to be applied</param>
+            <param name="actual">The actual value to test</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionHelper.Expect(System.Object,NUnit.Framework.Constraints.Constraint,System.String)">
+            <summary>
+            Apply a constraint to an actual value, succeeding if the constraint
+            is satisfied and throwing an assertion exception on failure. Works
+            identically to <see cref="M:NUnit.Framework.Assert.That(System.Object,NUnit.Framework.Constraints.Constraint,System.String)"/>
+            </summary>
+            <param name="constraint">A Constraint to be applied</param>
+            <param name="actual">The actual value to test</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionHelper.Expect(System.Object,NUnit.Framework.Constraints.Constraint,System.String,System.Object[])">
+            <summary>
+            Apply a constraint to an actual value, succeeding if the constraint
+            is satisfied and throwing an assertion exception on failure. Works
+            identically to <see cref="M:NUnit.Framework.Assert.That(System.Object,NUnit.Framework.Constraints.Constraint,System.String,System.Object[])"/>
+            </summary>
+            <param name="constraint">A Constraint to be applied</param>
+            <param name="actual">The actual value to test</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionHelper.Expect(System.Boolean,System.String,System.Object[])">
+            <summary>
+            Asserts that a condition is true. If the condition is false the method throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>. Works Identically to 
+            <see cref="M:NUnit.Framework.Assert.That(System.Boolean,System.String,System.Object[])"/>.
+            </summary> 
+            <param name="condition">The evaluated condition</param>
+            <param name="message">The message to display if the condition is false</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionHelper.Expect(System.Boolean,System.String)">
+            <summary>
+            Asserts that a condition is true. If the condition is false the method throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>. Works Identically to 
+            <see cref="M:NUnit.Framework.Assert.That(System.Boolean,System.String)"/>.
+            </summary>
+            <param name="condition">The evaluated condition</param>
+            <param name="message">The message to display if the condition is false</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionHelper.Expect(System.Boolean)">
+            <summary>
+            Asserts that a condition is true. If the condition is false the method throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>. Works Identically to <see cref="M:NUnit.Framework.Assert.That(System.Boolean)"/>.
+            </summary>
+            <param name="condition">The evaluated condition</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionHelper.Map(System.Collections.ICollection)">
+            <summary>
+            Returns a ListMapper based on a collection.
+            </summary>
+            <param name="original">The original collection</param>
+            <returns></returns>
+        </member>
+        <member name="T:NUnit.Framework.FileAssert">
+            <summary>
+            Summary description for FileAssert.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.Equals(System.Object,System.Object)">
+            <summary>
+            The Equals method throws an AssertionException. This is done 
+            to make sure there is no mistake by calling this function.
+            </summary>
+            <param name="a"></param>
+            <param name="b"></param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.ReferenceEquals(System.Object,System.Object)">
+            <summary>
+            override the default ReferenceEquals to throw an AssertionException. This 
+            implementation makes sure there is no mistake in calling this function 
+            as part of Assert. 
+            </summary>
+            <param name="a"></param>
+            <param name="b"></param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.#ctor">
+            <summary>
+            We don't actually want any instances of this object, but some people
+            like to inherit from it to add other static methods. Hence, the
+            protected constructor disallows any instances of this object. 
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreEqual(System.IO.Stream,System.IO.Stream,System.String,System.Object[])">
+            <summary>
+            Verifies that two Streams are equal.  Two Streams are considered
+            equal if both are null, or if both have the same value byte for byte.
+            If they are not equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected Stream</param>
+            <param name="actual">The actual Stream</param>
+            <param name="message">The message to display if Streams are not equal</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreEqual(System.IO.Stream,System.IO.Stream,System.String)">
+            <summary>
+            Verifies that two Streams are equal.  Two Streams are considered
+            equal if both are null, or if both have the same value byte for byte.
+            If they are not equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected Stream</param>
+            <param name="actual">The actual Stream</param>
+            <param name="message">The message to display if objects are not equal</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreEqual(System.IO.Stream,System.IO.Stream)">
+            <summary>
+            Verifies that two Streams are equal.  Two Streams are considered
+            equal if both are null, or if both have the same value byte for byte.
+            If they are not equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected Stream</param>
+            <param name="actual">The actual Stream</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreEqual(System.IO.FileInfo,System.IO.FileInfo,System.String,System.Object[])">
+            <summary>
+            Verifies that two files are equal.  Two files are considered
+            equal if both are null, or if both have the same value byte for byte.
+            If they are not equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">A file containing the value that is expected</param>
+            <param name="actual">A file containing the actual value</param>
+            <param name="message">The message to display if Streams are not equal</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreEqual(System.IO.FileInfo,System.IO.FileInfo,System.String)">
+            <summary>
+            Verifies that two files are equal.  Two files are considered
+            equal if both are null, or if both have the same value byte for byte.
+            If they are not equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">A file containing the value that is expected</param>
+            <param name="actual">A file containing the actual value</param>
+            <param name="message">The message to display if objects are not equal</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreEqual(System.IO.FileInfo,System.IO.FileInfo)">
+            <summary>
+            Verifies that two files are equal.  Two files are considered
+            equal if both are null, or if both have the same value byte for byte.
+            If they are not equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">A file containing the value that is expected</param>
+            <param name="actual">A file containing the actual value</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreEqual(System.String,System.String,System.String,System.Object[])">
+            <summary>
+            Verifies that two files are equal.  Two files are considered
+            equal if both are null, or if both have the same value byte for byte.
+            If they are not equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The path to a file containing the value that is expected</param>
+            <param name="actual">The path to a file containing the actual value</param>
+            <param name="message">The message to display if Streams are not equal</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreEqual(System.String,System.String,System.String)">
+            <summary>
+            Verifies that two files are equal.  Two files are considered
+            equal if both are null, or if both have the same value byte for byte.
+            If they are not equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The path to a file containing the value that is expected</param>
+            <param name="actual">The path to a file containing the actual value</param>
+            <param name="message">The message to display if objects are not equal</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreEqual(System.String,System.String)">
+            <summary>
+            Verifies that two files are equal.  Two files are considered
+            equal if both are null, or if both have the same value byte for byte.
+            If they are not equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The path to a file containing the value that is expected</param>
+            <param name="actual">The path to a file containing the actual value</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreNotEqual(System.IO.Stream,System.IO.Stream,System.String,System.Object[])">
+            <summary>
+            Asserts that two Streams are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected Stream</param>
+            <param name="actual">The actual Stream</param>
+            <param name="message">The message to be displayed when the two Stream are the same.</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreNotEqual(System.IO.Stream,System.IO.Stream,System.String)">
+            <summary>
+            Asserts that two Streams are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected Stream</param>
+            <param name="actual">The actual Stream</param>
+            <param name="message">The message to be displayed when the Streams are the same.</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreNotEqual(System.IO.Stream,System.IO.Stream)">
+            <summary>
+            Asserts that two Streams are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected Stream</param>
+            <param name="actual">The actual Stream</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreNotEqual(System.IO.FileInfo,System.IO.FileInfo,System.String,System.Object[])">
+            <summary>
+            Asserts that two files are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">A file containing the value that is expected</param>
+            <param name="actual">A file containing the actual value</param>
+            <param name="message">The message to display if Streams are not equal</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreNotEqual(System.IO.FileInfo,System.IO.FileInfo,System.String)">
+            <summary>
+            Asserts that two files are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">A file containing the value that is expected</param>
+            <param name="actual">A file containing the actual value</param>
+            <param name="message">The message to display if objects are not equal</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreNotEqual(System.IO.FileInfo,System.IO.FileInfo)">
+            <summary>
+            Asserts that two files are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">A file containing the value that is expected</param>
+            <param name="actual">A file containing the actual value</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreNotEqual(System.String,System.String,System.String,System.Object[])">
+            <summary>
+            Asserts that two files are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The path to a file containing the value that is expected</param>
+            <param name="actual">The path to a file containing the actual value</param>
+            <param name="message">The message to display if Streams are not equal</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreNotEqual(System.String,System.String,System.String)">
+            <summary>
+            Asserts that two files are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The path to a file containing the value that is expected</param>
+            <param name="actual">The path to a file containing the actual value</param>
+            <param name="message">The message to display if objects are not equal</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreNotEqual(System.String,System.String)">
+            <summary>
+            Asserts that two files are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The path to a file containing the value that is expected</param>
+            <param name="actual">The path to a file containing the actual value</param>
+        </member>
+        <member name="T:NUnit.Framework.IgnoreException">
+            <summary>
+            Thrown when an assertion failed.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.IgnoreException.#ctor(System.String)">
+            <param name="message"></param>
+        </member>
+        <member name="M:NUnit.Framework.IgnoreException.#ctor(System.String,System.Exception)">
+            <param name="message">The error message that explains 
+            the reason for the exception</param>
+            <param name="inner">The exception that caused the 
+            current exception</param>
+        </member>
+        <member name="M:NUnit.Framework.IgnoreException.#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)">
+            <summary>
+            Serialization Constructor
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.TestCase">
+            <summary>
+            Obsolete class, formerly used to identify tests through
+            inheritance. Avoid using this class for new tests.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.TestCase.SetUp">
+            <summary>
+            Method called immediately before running the test.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.TestCase.TearDown">
+            <summary>
+            Method Called immediately after running the test. It is
+            guaranteed to be called, even if an exception is thrown. 
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.SetUpAttribute">
+            <summary>
+            Attribute used to mark a class that contains one-time SetUp 
+            and/or TearDown methods that apply to all the tests in a
+            namespace or an assembly.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.SetUpFixtureAttribute">
+            <summary>
+            SetUpFixtureAttribute is used to identify a SetUpFixture
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.SuiteAttribute">
+            <summary>
+            Attribute used to mark a static (shared in VB) property
+            that returns a list of tests.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.TearDownAttribute">
+            <summary>
+            Attribute used to identify a method that is called 
+            immediately after each test is run. The method is 
+            guaranteed to be called, even if an exception is thrown.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.TestAttribute">
+            <summary>
+            Adding this attribute to a method within a <seealso cref="T:NUnit.Framework.TestFixtureAttribute"/> 
+            class makes the method callable from the NUnit test runner. There is a property 
+            called Description which is optional which you can provide a more detailed test
+            description. This class cannot be inherited.
+            </summary>
+            
+            <example>
+            [TestFixture]
+            public class Fixture
+            {
+              [Test]
+              public void MethodToTest()
+              {}
+              
+              [Test(Description = "more detailed description")]
+              publc void TestDescriptionMethod()
+              {}
+            }
+            </example>
+            
+        </member>
+        <member name="P:NUnit.Framework.TestAttribute.Description">
+            <summary>
+            Descriptive text for this test
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.TestFixtureAttribute">
+            <example>
+            [TestFixture]
+            public class ExampleClass 
+            {}
+            </example>
+        </member>
+        <member name="P:NUnit.Framework.TestFixtureAttribute.Description">
+            <summary>
+            Descriptive text for this fixture
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.TestFixtureSetUpAttribute">
+            <summary>
+            Attribute used to identify a method that is 
+            called before any tests in a fixture are run.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.TestFixtureTearDownAttribute">
+            <summary>
+            Attribute used to identify a method that is called after
+            all the tests in a fixture have run. The method is 
+            guaranteed to be called, even if an exception is thrown.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.IgnoreAttribute">
+            <summary>
+            Attribute used to mark a test that is to be ignored.
+            Ignored tests result in a warning message when the
+            tests are run.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.IgnoreAttribute.#ctor">
+            <summary>
+            Constructs the attribute without giving a reason 
+            for ignoring the test.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.IgnoreAttribute.#ctor(System.String)">
+            <summary>
+            Constructs the attribute giving a reason for ignoring the test
+            </summary>
+            <param name="reason">The reason for ignoring the test</param>
+        </member>
+        <member name="P:NUnit.Framework.IgnoreAttribute.Reason">
+            <summary>
+            The reason for ignoring a test
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.ExplicitAttribute">
+            <summary>
+            ExplicitAttribute marks a test or test fixture so that it will
+            only be run if explicitly executed from the gui or command line
+            or if it is included by use of a filter. The test will not be
+            run simply because an enclosing suite is run.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.ExplicitAttribute.#ctor">
+            <summary>
+            Default constructor
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.ExplicitAttribute.#ctor(System.String)">
+            <summary>
+            Constructor with a reason
+            </summary>
+            <param name="reason">The reason test is marked explicit</param>
+        </member>
+        <member name="P:NUnit.Framework.ExplicitAttribute.Reason">
+            <summary>
+            The reason test is marked explicit
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.DescriptionAttribute">
+            <summary>
+            Attribute used to provide descriptive text about a 
+            test case or fixture.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.DescriptionAttribute.#ctor(System.String)">
+            <summary>
+            Construct the attribute
+            </summary>
+            <param name="description">Text describing the test</param>
+        </member>
+        <member name="P:NUnit.Framework.DescriptionAttribute.Description">
+            <summary>
+            Gets the test description
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.IExpectException">
+            <summary>
+            Interface implemented by a user fixture in order to
+            validate any expected exceptions. It is only called
+            for test methods marked with the ExpectedException
+            attribute.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.IExpectException.HandleException(System.Exception)">
+            <summary>
+            Method to handle an expected exception
+            </summary>
+            <param name="ex">The exception to be handled</param>
+        </member>
+    </members>
+</doc>
diff --git a/trunk/Libraries/Json40r2/Source/Src/Lib/NUnit/Silverlight/nunit.framework.dll b/trunk/Libraries/Json40r2/Source/Src/Lib/NUnit/Silverlight/nunit.framework.dll
new file mode 100644 (file)
index 0000000..d4e0b72
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Src/Lib/NUnit/Silverlight/nunit.framework.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Net20.sln b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Net20.sln
new file mode 100644 (file)
index 0000000..eaaa295
--- /dev/null
@@ -0,0 +1,33 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Lib", "Lib", "{620042D9-2753-48F5-BEDE-3905248781D2}"
+       ProjectSection(SolutionItems) = preProject
+               Lib\LinqBridge.dll = Lib\LinqBridge.dll
+               Lib\NUnit\DotNet\nunit.framework.dll = Lib\NUnit\DotNet\nunit.framework.dll
+               Lib\NUnit\DotNet\nunit.framework.xml = Lib\NUnit\DotNet\nunit.framework.xml
+       EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Newtonsoft.Json.Net20", "Newtonsoft.Json\Newtonsoft.Json.Net20.csproj", "{A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Newtonsoft.Json.Tests.Net20", "Newtonsoft.Json.Tests\Newtonsoft.Json.Tests.Net20.csproj", "{3E6E2335-B079-4B5B-A65A-9D586914BCBB}"
+EndProject
+Global
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Debug|Any CPU = Debug|Any CPU
+               Release|Any CPU = Release|Any CPU
+       EndGlobalSection
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Release|Any CPU.Build.0 = Release|Any CPU
+               {3E6E2335-B079-4B5B-A65A-9D586914BCBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {3E6E2335-B079-4B5B-A65A-9D586914BCBB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {3E6E2335-B079-4B5B-A65A-9D586914BCBB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {3E6E2335-B079-4B5B-A65A-9D586914BCBB}.Release|Any CPU.Build.0 = Release|Any CPU
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+EndGlobal
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Net35.sln b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Net35.sln
new file mode 100644 (file)
index 0000000..2f1bc6e
--- /dev/null
@@ -0,0 +1,26 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Newtonsoft.Json.Net35", "Newtonsoft.Json\Newtonsoft.Json.Net35.csproj", "{A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Newtonsoft.Json.Tests.Net35", "Newtonsoft.Json.Tests\Newtonsoft.Json.Tests.Net35.csproj", "{3E6E2335-B079-4B5B-A65A-9D586914BCBB}"
+EndProject
+Global
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Debug|Any CPU = Debug|Any CPU
+               Release|Any CPU = Release|Any CPU
+       EndGlobalSection
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Release|Any CPU.Build.0 = Release|Any CPU
+               {3E6E2335-B079-4B5B-A65A-9D586914BCBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {3E6E2335-B079-4B5B-A65A-9D586914BCBB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {3E6E2335-B079-4B5B-A65A-9D586914BCBB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {3E6E2335-B079-4B5B-A65A-9D586914BCBB}.Release|Any CPU.Build.0 = Release|Any CPU
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+EndGlobal
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Silverlight.sln b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Silverlight.sln
new file mode 100644 (file)
index 0000000..75720f1
--- /dev/null
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Lib", "Lib", "{F69285DD-24FB-4A60-AE8B-4C2744285D0F}"
+       ProjectSection(SolutionItems) = preProject
+               Lib\NUnit\Silverlight\nunit.framework.dll = Lib\NUnit\Silverlight\nunit.framework.dll
+       EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Newtonsoft.Json.Silverlight", "Newtonsoft.Json\Newtonsoft.Json.Silverlight.csproj", "{DC3C6F3D-2CA1-4278-9B79-63770FB3EA2D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Newtonsoft.Json.Tests.Silverlight", "Newtonsoft.Json.Tests\Newtonsoft.Json.Tests.Silverlight.csproj", "{0D8C3C2E-62C6-4C93-9377-6F74DD6BFD93}"
+EndProject
+Global
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Debug|Any CPU = Debug|Any CPU
+               Release|Any CPU = Release|Any CPU
+       EndGlobalSection
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {DC3C6F3D-2CA1-4278-9B79-63770FB3EA2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {DC3C6F3D-2CA1-4278-9B79-63770FB3EA2D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {DC3C6F3D-2CA1-4278-9B79-63770FB3EA2D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {DC3C6F3D-2CA1-4278-9B79-63770FB3EA2D}.Release|Any CPU.Build.0 = Release|Any CPU
+               {0D8C3C2E-62C6-4C93-9377-6F74DD6BFD93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {0D8C3C2E-62C6-4C93-9377-6F74DD6BFD93}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {0D8C3C2E-62C6-4C93-9377-6F74DD6BFD93}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {0D8C3C2E-62C6-4C93-9377-6F74DD6BFD93}.Release|Any CPU.Build.0 = Release|Any CPU
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+EndGlobal
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Bson/BsonReaderTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Bson/BsonReaderTests.cs
new file mode 100644 (file)
index 0000000..8ba4351
--- /dev/null
@@ -0,0 +1,1121 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using Newtonsoft.Json.Bson;
+using System.IO;
+using Newtonsoft.Json.Utilities;
+using Newtonsoft.Json.Linq;
+
+namespace Newtonsoft.Json.Tests.Bson
+{
+  public class BsonReaderTests : TestFixtureBase
+  {
+    private const char Euro = '\u20ac';
+
+    [Test]
+    public void CloseInput()
+    {
+      MemoryStream ms = new MemoryStream();
+      BsonReader reader = new BsonReader(ms);
+
+      Assert.IsTrue(ms.CanRead);
+      reader.Close();
+      Assert.IsFalse(ms.CanRead);
+
+      ms = new MemoryStream();
+      reader = new BsonReader(ms) { CloseInput = false };
+
+      Assert.IsTrue(ms.CanRead);
+      reader.Close();
+      Assert.IsTrue(ms.CanRead);
+    }
+
+    [Test]
+    public void ReadSingleObject()
+    {
+      byte[] data = MiscellaneousUtils.HexToBytes("0F-00-00-00-10-42-6C-61-68-00-01-00-00-00-00");
+      MemoryStream ms = new MemoryStream(data);
+      BsonReader reader = new BsonReader(ms);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("Blah", reader.Value);
+      Assert.AreEqual(typeof(string), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Integer, reader.TokenType);
+      Assert.AreEqual(1, reader.Value);
+      Assert.AreEqual(typeof(long), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      Assert.IsFalse(reader.Read());
+    }
+
+    [Test]
+    public void WriteValues()
+    {
+      byte[] data = MiscellaneousUtils.HexToBytes("8C-00-00-00-12-30-00-FF-FF-FF-FF-FF-FF-FF-7F-12-31-00-FF-FF-FF-FF-FF-FF-FF-7F-10-32-00-FF-FF-FF-7F-10-33-00-FF-FF-FF-7F-10-34-00-FF-00-00-00-10-35-00-7F-00-00-00-02-36-00-02-00-00-00-61-00-01-37-00-00-00-00-00-00-00-F0-45-01-38-00-FF-FF-FF-FF-FF-FF-EF-7F-01-39-00-00-00-00-E0-FF-FF-EF-47-08-31-30-00-01-05-31-31-00-05-00-00-00-02-00-01-02-03-04-09-31-32-00-40-C5-E2-BA-E3-00-00-00-09-31-33-00-40-C5-E2-BA-E3-00-00-00-00");
+      MemoryStream ms = new MemoryStream(data);
+      BsonReader reader = new BsonReader(ms);
+      reader.JsonNet35BinaryCompatibility = true;
+      reader.ReadRootValueAsArray = true;
+      reader.DateTimeKindHandling = DateTimeKind.Utc;
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Integer, reader.TokenType);
+      Assert.AreEqual(long.MaxValue, reader.Value);
+      Assert.AreEqual(typeof(long), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Integer, reader.TokenType);
+      Assert.AreEqual(long.MaxValue, reader.Value);
+      Assert.AreEqual(typeof(long), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Integer, reader.TokenType);
+      Assert.AreEqual(int.MaxValue, reader.Value);
+      Assert.AreEqual(typeof(long), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Integer, reader.TokenType);
+      Assert.AreEqual(int.MaxValue, reader.Value);
+      Assert.AreEqual(typeof(long), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Integer, reader.TokenType);
+      Assert.AreEqual(byte.MaxValue, reader.Value);
+      Assert.AreEqual(typeof(long), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Integer, reader.TokenType);
+      Assert.AreEqual(sbyte.MaxValue, reader.Value);
+      Assert.AreEqual(typeof(long), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("a", reader.Value);
+      Assert.AreEqual(typeof(string), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Float, reader.TokenType);
+      Assert.AreEqual(decimal.MaxValue, reader.Value);
+      Assert.AreEqual(typeof(double), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Float, reader.TokenType);
+      Assert.AreEqual(double.MaxValue, reader.Value);
+      Assert.AreEqual(typeof(double), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Float, reader.TokenType);
+      Assert.AreEqual(float.MaxValue, reader.Value);
+      Assert.AreEqual(typeof(double), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Boolean, reader.TokenType);
+      Assert.AreEqual(true, reader.Value);
+      Assert.AreEqual(typeof(bool), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Bytes, reader.TokenType);
+      Assert.AreEqual(new byte[] { 0, 1, 2, 3, 4 }, reader.Value);
+      Assert.AreEqual(typeof(byte[]), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Date, reader.TokenType);
+      Assert.AreEqual(new DateTime(2000, 12, 29, 12, 30, 0, DateTimeKind.Utc), reader.Value);
+      Assert.AreEqual(typeof(DateTime), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Date, reader.TokenType);
+      Assert.AreEqual(new DateTime(2000, 12, 29, 12, 30, 0, DateTimeKind.Utc), reader.Value);
+      Assert.AreEqual(typeof(DateTime), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
+
+      Assert.IsFalse(reader.Read());
+    }
+
+
+    [Test]
+    public void ReadObjectBsonFromSite()
+    {
+      byte[] data = MiscellaneousUtils.HexToBytes("20-00-00-00-02-30-00-02-00-00-00-61-00-02-31-00-02-00-00-00-62-00-02-32-00-02-00-00-00-63-00-00");
+
+      MemoryStream ms = new MemoryStream(data);
+      BsonReader reader = new BsonReader(ms);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("0", reader.Value);
+      Assert.AreEqual(typeof(string), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("a", reader.Value);
+      Assert.AreEqual(typeof(string), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("1", reader.Value);
+      Assert.AreEqual(typeof(string), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("b", reader.Value);
+      Assert.AreEqual(typeof(string), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("2", reader.Value);
+      Assert.AreEqual(typeof(string), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("c", reader.Value);
+      Assert.AreEqual(typeof(string), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      Assert.IsFalse(reader.Read());
+    }
+
+    [Test]
+    public void ReadArrayBsonFromSite()
+    {
+      byte[] data = MiscellaneousUtils.HexToBytes("20-00-00-00-02-30-00-02-00-00-00-61-00-02-31-00-02-00-00-00-62-00-02-32-00-02-00-00-00-63-00-00");
+
+      MemoryStream ms = new MemoryStream(data);
+      BsonReader reader = new BsonReader(ms);
+
+      Assert.AreEqual(false, reader.ReadRootValueAsArray);
+      Assert.AreEqual(DateTimeKind.Local, reader.DateTimeKindHandling);
+
+      reader.ReadRootValueAsArray = true;
+      reader.DateTimeKindHandling = DateTimeKind.Utc;
+
+      Assert.AreEqual(true, reader.ReadRootValueAsArray);
+      Assert.AreEqual(DateTimeKind.Utc, reader.DateTimeKindHandling);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("a", reader.Value);
+      Assert.AreEqual(typeof(string), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("b", reader.Value);
+      Assert.AreEqual(typeof(string), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("c", reader.Value);
+      Assert.AreEqual(typeof(string), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
+
+      Assert.IsFalse(reader.Read());
+    }
+
+    [Test]
+    public void ReadBytes()
+    {
+      byte[] data = MiscellaneousUtils.HexToBytes("2B-00-00-00-02-30-00-02-00-00-00-61-00-02-31-00-02-00-00-00-62-00-05-32-00-0C-00-00-00-02-48-65-6C-6C-6F-20-77-6F-72-6C-64-21-00");
+
+      MemoryStream ms = new MemoryStream(data);
+      BsonReader reader = new BsonReader(ms, true, DateTimeKind.Utc);
+      reader.JsonNet35BinaryCompatibility = true;
+
+      Assert.AreEqual(true, reader.ReadRootValueAsArray);
+      Assert.AreEqual(DateTimeKind.Utc, reader.DateTimeKindHandling);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("a", reader.Value);
+      Assert.AreEqual(typeof(string), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("b", reader.Value);
+      Assert.AreEqual(typeof(string), reader.ValueType);
+
+      byte[] encodedStringData = reader.ReadAsBytes();
+      Assert.IsNotNull(encodedStringData);
+      Assert.AreEqual(JsonToken.Bytes, reader.TokenType);
+      Assert.AreEqual(encodedStringData, reader.Value);
+      Assert.AreEqual(typeof(byte[]), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
+
+      Assert.IsFalse(reader.Read());
+
+      string decodedString = Encoding.UTF8.GetString(encodedStringData, 0, encodedStringData.Length);
+      Assert.AreEqual("Hello world!", decodedString);
+    }
+
+    [Test]
+    public void ReadOid()
+    {
+      byte[] data = MiscellaneousUtils.HexToBytes("29000000075F6964004ABBED9D1D8B0F02180000010274657374000900000031323334C2A335360000");
+
+      MemoryStream ms = new MemoryStream(data);
+      BsonReader reader = new BsonReader(ms);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("_id", reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Bytes, reader.TokenType);
+      Assert.AreEqual(MiscellaneousUtils.HexToBytes("4ABBED9D1D8B0F0218000001"), reader.Value);
+      Assert.AreEqual(typeof(byte[]), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("test", reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("1234£56", reader.Value);
+      Assert.AreEqual(typeof(string), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      Assert.IsFalse(reader.Read());
+    }
+
+    [Test]
+    public void ReadNestedArray()
+    {
+      string hexdoc = "82-00-00-00-07-5F-69-64-00-4A-78-93-79-17-22-00-00-00-00-61-CF-04-61-00-5D-00-00-00-01-30-00-00-00-00-00-00-00-F0-3F-01-31-00-00-00-00-00-00-00-00-40-01-32-00-00-00-00-00-00-00-08-40-01-33-00-00-00-00-00-00-00-10-40-01-34-00-00-00-00-00-00-00-14-50-01-35-00-00-00-00-00-00-00-18-40-01-36-00-00-00-00-00-00-00-1C-40-01-37-00-00-00-00-00-00-00-20-40-00-02-62-00-05-00-00-00-74-65-73-74-00-00";
+
+      byte[] data = MiscellaneousUtils.HexToBytes(hexdoc);
+
+      MemoryStream ms = new MemoryStream(data);
+      BsonReader reader = new BsonReader(ms);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("_id", reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Bytes, reader.TokenType);
+      Assert.AreEqual(MiscellaneousUtils.HexToBytes("4A-78-93-79-17-22-00-00-00-00-61-CF"), reader.Value);
+      Assert.AreEqual(typeof(byte[]), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("a", reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
+
+      for (int i = 1; i <= 8; i++)
+      {
+        Assert.IsTrue(reader.Read());
+        Assert.AreEqual(JsonToken.Float, reader.TokenType);
+
+        double value = (i != 5)
+                         ? Convert.ToDouble(i)
+                         : 5.78960446186581E+77d;
+
+        Assert.AreEqual(value, reader.Value);
+      }
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("b", reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("test", reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      Assert.IsFalse(reader.Read());
+    }
+
+    [Test]
+    public void ReadNestedArrayIntoLinq()
+    {
+      string hexdoc = "87-00-00-00-05-5F-69-64-00-0C-00-00-00-00-4A-78-93-79-17-22-00-00-00-00-61-CF-04-61-00-5D-00-00-00-01-30-00-00-00-00-00-00-00-F0-3F-01-31-00-00-00-00-00-00-00-00-40-01-32-00-00-00-00-00-00-00-08-40-01-33-00-00-00-00-00-00-00-10-40-01-34-00-00-00-00-00-00-00-14-50-01-35-00-00-00-00-00-00-00-18-40-01-36-00-00-00-00-00-00-00-1C-40-01-37-00-00-00-00-00-00-00-20-40-00-02-62-00-05-00-00-00-74-65-73-74-00-00";
+
+      byte[] data = MiscellaneousUtils.HexToBytes(hexdoc);
+
+      BsonReader reader = new BsonReader(new MemoryStream(data));
+      reader.JsonNet35BinaryCompatibility = true;
+
+      JObject o = (JObject)JToken.ReadFrom(reader);
+      Assert.AreEqual(3, o.Count);
+
+      MemoryStream ms = new MemoryStream();
+      BsonWriter writer = new BsonWriter(ms);
+      o.WriteTo(writer);
+      writer.Flush();
+
+      string bson = MiscellaneousUtils.BytesToHex(ms.ToArray());
+      Assert.AreEqual(hexdoc, bson);
+    }
+
+    [Test]
+    public void OidAndBytesAreEqual()
+    {
+      byte[] data1 = MiscellaneousUtils.HexToBytes(
+        "82-00-00-00-07-5F-69-64-00-4A-78-93-79-17-22-00-00-00-00-61-CF-04-61-00-5D-00-00-00-01-30-00-00-00-00-00-00-00-F0-3F-01-31-00-00-00-00-00-00-00-00-40-01-32-00-00-00-00-00-00-00-08-40-01-33-00-00-00-00-00-00-00-10-40-01-34-00-00-00-00-00-00-00-14-50-01-35-00-00-00-00-00-00-00-18-40-01-36-00-00-00-00-00-00-00-1C-40-01-37-00-00-00-00-00-00-00-20-40-00-02-62-00-05-00-00-00-74-65-73-74-00-00");
+
+      BsonReader reader1 = new BsonReader(new MemoryStream(data1));
+      reader1.JsonNet35BinaryCompatibility = true;
+
+      // oid
+      JObject o1 = (JObject)JToken.ReadFrom(reader1);
+
+      byte[] data2 = MiscellaneousUtils.HexToBytes(
+        "87-00-00-00-05-5F-69-64-00-0C-00-00-00-02-4A-78-93-79-17-22-00-00-00-00-61-CF-04-61-00-5D-00-00-00-01-30-00-00-00-00-00-00-00-F0-3F-01-31-00-00-00-00-00-00-00-00-40-01-32-00-00-00-00-00-00-00-08-40-01-33-00-00-00-00-00-00-00-10-40-01-34-00-00-00-00-00-00-00-14-50-01-35-00-00-00-00-00-00-00-18-40-01-36-00-00-00-00-00-00-00-1C-40-01-37-00-00-00-00-00-00-00-20-40-00-02-62-00-05-00-00-00-74-65-73-74-00-00");
+
+      BsonReader reader2 = new BsonReader(new MemoryStream(data2));
+      reader2.JsonNet35BinaryCompatibility = true;
+
+      // bytes
+      JObject o2 = (JObject)JToken.ReadFrom(reader2);
+
+      Assert.IsTrue(o1.DeepEquals(o2));
+    }
+
+    [Test]
+    public void ReadRegex()
+    {
+      string hexdoc = "15-00-00-00-0B-72-65-67-65-78-00-74-65-73-74-00-67-69-6D-00-00";
+
+      byte[] data = MiscellaneousUtils.HexToBytes(hexdoc);
+
+      MemoryStream ms = new MemoryStream(data);
+      BsonReader reader = new BsonReader(ms);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("regex", reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual(@"/test/gim", reader.Value);
+      Assert.AreEqual(typeof(string), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      Assert.IsFalse(reader.Read());
+    }
+
+    [Test]
+    public void ReadCode()
+    {
+      string hexdoc = "1A-00-00-00-0D-63-6F-64-65-00-0B-00-00-00-49-20-61-6D-20-63-6F-64-65-21-00-00";
+
+      byte[] data = MiscellaneousUtils.HexToBytes(hexdoc);
+
+      MemoryStream ms = new MemoryStream(data);
+      BsonReader reader = new BsonReader(ms);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("code", reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual(@"I am code!", reader.Value);
+      Assert.AreEqual(typeof(string), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      Assert.IsFalse(reader.Read());
+    }
+
+    [Test]
+    public void ReadUndefined()
+    {
+      string hexdoc = "10-00-00-00-06-75-6E-64-65-66-69-6E-65-64-00-00";
+
+      byte[] data = MiscellaneousUtils.HexToBytes(hexdoc);
+
+      MemoryStream ms = new MemoryStream(data);
+      BsonReader reader = new BsonReader(ms);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("undefined", reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Undefined, reader.TokenType);
+      Assert.AreEqual(null, reader.Value);
+      Assert.AreEqual(null, reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      Assert.IsFalse(reader.Read());
+    }
+
+    [Test]
+    public void ReadLong()
+    {
+      string hexdoc = "13-00-00-00-12-6C-6F-6E-67-00-FF-FF-FF-FF-FF-FF-FF-7F-00";
+
+      byte[] data = MiscellaneousUtils.HexToBytes(hexdoc);
+
+      MemoryStream ms = new MemoryStream(data);
+      BsonReader reader = new BsonReader(ms);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("long", reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Integer, reader.TokenType);
+      Assert.AreEqual(long.MaxValue, reader.Value);
+      Assert.AreEqual(typeof(long), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      Assert.IsFalse(reader.Read());
+    }
+
+    [Test]
+    public void ReadReference()
+    {
+      string hexdoc = "1E-00-00-00-0C-6F-69-64-00-04-00-00-00-6F-69-64-00-01-02-03-04-05-06-07-08-09-0A-0B-0C-00";
+
+      byte[] data = MiscellaneousUtils.HexToBytes(hexdoc);
+
+      MemoryStream ms = new MemoryStream(data);
+      BsonReader reader = new BsonReader(ms);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("oid", reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("$ref", reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("oid", reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("$id", reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Bytes, reader.TokenType);
+      Assert.AreEqual(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }, reader.Value);
+      Assert.AreEqual(typeof(byte[]), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      Assert.IsFalse(reader.Read());
+    }
+
+    [Test]
+    public void ReadCodeWScope()
+    {
+      string hexdoc = "75-00-00-00-0F-63-6F-64-65-57-69-74-68-53-63-6F-70-65-00-61-00-00-00-35-00-00-00-66-6F-72-20-28-69-6E-74-20-69-20-3D-20-30-3B-20-69-20-3C-20-31-30-30-30-3B-20-69-2B-2B-29-0D-0A-7B-0D-0A-20-20-61-6C-65-72-74-28-61-72-67-31-29-3B-0D-0A-7D-00-24-00-00-00-02-61-72-67-31-00-15-00-00-00-4A-73-6F-6E-2E-4E-45-54-20-69-73-20-61-77-65-73-6F-6D-65-2E-00-00-00";
+
+      byte[] data = MiscellaneousUtils.HexToBytes(hexdoc);
+
+      MemoryStream ms = new MemoryStream(data);
+      BsonReader reader = new BsonReader(ms);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("codeWithScope", reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("$code", reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual(@"for (int i = 0; i < 1000; i++)
+{
+  alert(arg1);
+}", reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("$scope", reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("arg1", reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("Json.NET is awesome.", reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      Assert.IsFalse(reader.Read());
+    }
+
+    [Test]
+    public void ReadEndOfStream()
+    {
+      BsonReader reader = new BsonReader(new MemoryStream());
+      Assert.IsFalse(reader.Read());
+    }
+
+    [Test]
+    public void ReadLargeStrings()
+    {
+      string bson =
+        "4E-02-00-00-02-30-2D-31-2D-32-2D-33-2D-34-2D-35-2D-36-2D-37-2D-38-2D-39-2D-31-30-2D-31-31-2D-31-32-2D-31-33-2D-31-34-2D-31-35-2D-31-36-2D-31-37-2D-31-38-2D-31-39-2D-32-30-2D-32-31-2D-32-32-2D-32-33-2D-32-34-2D-32-35-2D-32-36-2D-32-37-2D-32-38-2D-32-39-2D-33-30-2D-33-31-2D-33-32-2D-33-33-2D-33-34-2D-33-35-2D-33-36-2D-33-37-2D-33-38-2D-33-39-2D-34-30-2D-34-31-2D-34-32-2D-34-33-2D-34-34-2D-34-35-2D-34-36-2D-34-37-2D-34-38-2D-34-39-2D-35-30-2D-35-31-2D-35-32-2D-35-33-2D-35-34-2D-35-35-2D-35-36-2D-35-37-2D-35-38-2D-35-39-2D-36-30-2D-36-31-2D-36-32-2D-36-33-2D-36-34-2D-36-35-2D-36-36-2D-36-37-2D-36-38-2D-36-39-2D-37-30-2D-37-31-2D-37-32-2D-37-33-2D-37-34-2D-37-35-2D-37-36-2D-37-37-2D-37-38-2D-37-39-2D-38-30-2D-38-31-2D-38-32-2D-38-33-2D-38-34-2D-38-35-2D-38-36-2D-38-37-2D-38-38-2D-38-39-2D-39-30-2D-39-31-2D-39-32-2D-39-33-2D-39-34-2D-39-35-2D-39-36-2D-39-37-2D-39-38-2D-39-39-00-22-01-00-00-30-2D-31-2D-32-2D-33-2D-34-2D-35-2D-36-2D-37-2D-38-2D-39-2D-31-30-2D-31-31-2D-31-32-2D-31-33-2D-31-34-2D-31-35-2D-31-36-2D-31-37-2D-31-38-2D-31-39-2D-32-30-2D-32-31-2D-32-32-2D-32-33-2D-32-34-2D-32-35-2D-32-36-2D-32-37-2D-32-38-2D-32-39-2D-33-30-2D-33-31-2D-33-32-2D-33-33-2D-33-34-2D-33-35-2D-33-36-2D-33-37-2D-33-38-2D-33-39-2D-34-30-2D-34-31-2D-34-32-2D-34-33-2D-34-34-2D-34-35-2D-34-36-2D-34-37-2D-34-38-2D-34-39-2D-35-30-2D-35-31-2D-35-32-2D-35-33-2D-35-34-2D-35-35-2D-35-36-2D-35-37-2D-35-38-2D-35-39-2D-36-30-2D-36-31-2D-36-32-2D-36-33-2D-36-34-2D-36-35-2D-36-36-2D-36-37-2D-36-38-2D-36-39-2D-37-30-2D-37-31-2D-37-32-2D-37-33-2D-37-34-2D-37-35-2D-37-36-2D-37-37-2D-37-38-2D-37-39-2D-38-30-2D-38-31-2D-38-32-2D-38-33-2D-38-34-2D-38-35-2D-38-36-2D-38-37-2D-38-38-2D-38-39-2D-39-30-2D-39-31-2D-39-32-2D-39-33-2D-39-34-2D-39-35-2D-39-36-2D-39-37-2D-39-38-2D-39-39-00-00";
+
+      BsonReader reader = new BsonReader(new MemoryStream(MiscellaneousUtils.HexToBytes(bson)));
+
+      StringBuilder largeStringBuilder = new StringBuilder();
+      for (int i = 0; i < 100; i++)
+      {
+        if (i > 0)
+          largeStringBuilder.Append("-");
+
+        largeStringBuilder.Append(i.ToString(CultureInfo.InvariantCulture));
+      }
+      string largeString = largeStringBuilder.ToString();
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual(largeString, reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual(largeString, reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      Assert.IsFalse(reader.Read());
+    }
+
+    [Test]
+    public void ReadEmptyStrings()
+    {
+      string bson = "0C-00-00-00-02-00-01-00-00-00-00-00";
+
+      BsonReader reader = new BsonReader(new MemoryStream(MiscellaneousUtils.HexToBytes(bson)));
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("", reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("", reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      Assert.IsFalse(reader.Read());
+    }
+
+    [Test]
+    public void WriteAndReadEmptyListsAndDictionaries()
+    {
+      MemoryStream ms = new MemoryStream();
+      BsonWriter writer = new BsonWriter(ms);
+
+      writer.WriteStartObject();
+      writer.WritePropertyName("Arguments");
+      writer.WriteStartObject();
+      writer.WriteEndObject();
+      writer.WritePropertyName("List");
+      writer.WriteStartArray();
+      writer.WriteEndArray();
+      writer.WriteEndObject();
+
+      string bson = BitConverter.ToString(ms.ToArray());
+
+      Assert.AreEqual("20-00-00-00-03-41-72-67-75-6D-65-6E-74-73-00-05-00-00-00-00-04-4C-69-73-74-00-05-00-00-00-00-00", bson);
+
+      BsonReader reader = new BsonReader(new MemoryStream(MiscellaneousUtils.HexToBytes(bson)));
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("Arguments", reader.Value.ToString());
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("List", reader.Value.ToString());
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      Assert.IsFalse(reader.Read());
+    }
+
+    [Test]
+    public void DateTimeKindHandling()
+    {
+      DateTime value = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+
+      MemoryStream ms = new MemoryStream();
+      BsonWriter writer = new BsonWriter(ms);
+
+      writer.WriteStartObject();
+      writer.WritePropertyName("DateTime");
+      writer.WriteValue(value);
+      writer.WriteEndObject();
+
+      byte[] bson = ms.ToArray();
+
+      JObject o;
+      BsonReader reader;
+      
+      reader = new BsonReader(new MemoryStream(bson), false, DateTimeKind.Utc);
+      o = (JObject)JToken.ReadFrom(reader);
+      Assert.AreEqual(value, (DateTime)o["DateTime"]);
+
+      reader = new BsonReader(new MemoryStream(bson), false, DateTimeKind.Local);
+      o = (JObject)JToken.ReadFrom(reader);
+      Assert.AreEqual(value.ToLocalTime(), (DateTime)o["DateTime"]);
+
+      reader = new BsonReader(new MemoryStream(bson), false, DateTimeKind.Unspecified);
+      o = (JObject)JToken.ReadFrom(reader);
+      Assert.AreEqual(DateTime.SpecifyKind(value.ToLocalTime(), DateTimeKind.Unspecified), (DateTime)o["DateTime"]);
+    }
+
+    private string WriteAndReadStringValue(string val)
+    {
+      MemoryStream ms = new MemoryStream();
+      BsonWriter bs = new BsonWriter(ms);
+      bs.WriteStartObject();
+      bs.WritePropertyName("StringValue");
+      bs.WriteValue(val);
+      bs.WriteEnd();
+
+      ms.Seek(0, SeekOrigin.Begin);
+
+      BsonReader reader = new BsonReader(ms);
+      // object
+      reader.Read();
+      // property name
+      reader.Read();
+      // string
+      reader.Read();
+      return (string)reader.Value;
+    }
+
+    private string WriteAndReadStringPropertyName(string val)
+    {
+      MemoryStream ms = new MemoryStream();
+      BsonWriter bs = new BsonWriter(ms);
+      bs.WriteStartObject();
+      bs.WritePropertyName(val);
+      bs.WriteValue("Dummy");
+      bs.WriteEnd();
+
+      ms.Seek(0, SeekOrigin.Begin);
+
+      BsonReader reader = new BsonReader(ms);
+      // object
+      reader.Read();
+      // property name
+      reader.Read();
+      return (string)reader.Value;
+    }
+
+    [Test]
+    public void TestReadLenStringValueShortTripleByte()
+    {
+      StringBuilder sb = new StringBuilder();
+      //sb.Append('1',127); //first char of euro at the end of the boundry.
+      //sb.Append(euro, 5);
+      //sb.Append('1',128);
+      sb.Append(Euro);
+
+      string expected = sb.ToString();
+      Assert.AreEqual(expected, WriteAndReadStringValue(expected));
+    }
+
+    [Test]
+    public void TestReadLenStringValueTripleByteCharBufferBoundry0()
+    {
+      StringBuilder sb = new StringBuilder();
+      sb.Append('1', 127); //first char of euro at the end of the boundry.
+      sb.Append(Euro, 5);
+      sb.Append('1', 128);
+      sb.Append(Euro);
+
+      string expected = sb.ToString();
+      Assert.AreEqual(expected, WriteAndReadStringValue(expected));
+    }
+
+    [Test]
+    public void TestReadLenStringValueTripleByteCharBufferBoundry1()
+    {
+      StringBuilder sb = new StringBuilder();
+      sb.Append('1', 126);
+      sb.Append(Euro, 5); //middle char of euro at the end of the boundry.
+      sb.Append('1', 128);
+      sb.Append(Euro);
+
+      string expected = sb.ToString();
+      string result = WriteAndReadStringValue(expected);
+      Assert.AreEqual(expected, result);
+    }
+
+    [Test]
+    public void TestReadLenStringValueTripleByteCharOne()
+    {
+      StringBuilder sb = new StringBuilder();
+      sb.Append(Euro, 1); //Just one triple byte char in the string.
+
+      string expected = sb.ToString();
+      Assert.AreEqual(expected, WriteAndReadStringValue(expected));
+    }
+
+    [Test]
+    public void TestReadLenStringValueTripleByteCharBufferBoundry2()
+    {
+      StringBuilder sb = new StringBuilder();
+      sb.Append('1', 125);
+      sb.Append(Euro, 5); //last char of the eruo at the end of the boundry.
+      sb.Append('1', 128);
+      sb.Append(Euro);
+
+      string expected = sb.ToString();
+      Assert.AreEqual(expected, WriteAndReadStringValue(expected));
+    }
+
+    [Test]
+    public void TestReadStringValue()
+    {
+      string expected = "test";
+      Assert.AreEqual(expected, WriteAndReadStringValue(expected));
+    }
+
+    [Test]
+    public void TestReadStringValueLong()
+    {
+      StringBuilder sb = new StringBuilder();
+      sb.Append('t', 150);
+      string expected = sb.ToString();
+      Assert.AreEqual(expected, WriteAndReadStringValue(expected));
+    }
+
+    [Test]
+    public void TestReadStringPropertyNameShortTripleByte()
+    {
+      StringBuilder sb = new StringBuilder();
+      //sb.Append('1',127); //first char of euro at the end of the boundry.
+      //sb.Append(euro, 5);
+      //sb.Append('1',128);
+      sb.Append(Euro);
+
+      string expected = sb.ToString();
+      Assert.AreEqual(expected, WriteAndReadStringPropertyName(expected));
+    }
+
+    [Test]
+    public void TestReadStringPropertyNameTripleByteCharBufferBoundry0()
+    {
+      StringBuilder sb = new StringBuilder();
+      sb.Append('1', 127); //first char of euro at the end of the boundry.
+      sb.Append(Euro, 5);
+      sb.Append('1', 128);
+      sb.Append(Euro);
+
+      string expected = sb.ToString();
+      string result = WriteAndReadStringPropertyName(expected);
+      Assert.AreEqual(expected, result);
+    }
+
+    [Test]
+    public void TestReadStringPropertyNameTripleByteCharBufferBoundry1()
+    {
+      StringBuilder sb = new StringBuilder();
+      sb.Append('1', 126);
+      sb.Append(Euro, 5); //middle char of euro at the end of the boundry.
+      sb.Append('1', 128);
+      sb.Append(Euro);
+
+      string expected = sb.ToString();
+      Assert.AreEqual(expected, WriteAndReadStringPropertyName(expected));
+    }
+
+    [Test]
+    public void TestReadStringPropertyNameTripleByteCharOne()
+    {
+      StringBuilder sb = new StringBuilder();
+      sb.Append(Euro, 1); //Just one triple byte char in the string.
+
+      string expected = sb.ToString();
+      Assert.AreEqual(expected, WriteAndReadStringPropertyName(expected));
+    }
+
+    [Test]
+    public void TestReadStringPropertyNameTripleByteCharBufferBoundry2()
+    {
+      StringBuilder sb = new StringBuilder();
+      sb.Append('1', 125);
+      sb.Append(Euro, 5); //last char of the eruo at the end of the boundry.
+      sb.Append('1', 128);
+      sb.Append(Euro);
+
+      string expected = sb.ToString();
+      Assert.AreEqual(expected, WriteAndReadStringPropertyName(expected));
+    }
+
+    [Test]
+    public void TestReadStringPropertyName()
+    {
+      string expected = "test";
+      Assert.AreEqual(expected, WriteAndReadStringPropertyName(expected));
+    }
+
+    [Test]
+    public void TestReadStringPropertyNameLong()
+    {
+      StringBuilder sb = new StringBuilder();
+      sb.Append('t', 150);
+      string expected = sb.ToString();
+      Assert.AreEqual(expected, WriteAndReadStringPropertyName(expected));
+    }
+
+    [Test]
+    public void ReadRegexWithOptions()
+    {
+      string hexdoc = "1A-00-00-00-0B-72-65-67-65-78-00-61-62-63-00-69-00-0B-74-65-73-74-00-00-00-00";
+
+      byte[] data = MiscellaneousUtils.HexToBytes(hexdoc);
+
+      MemoryStream ms = new MemoryStream(data);
+      BsonReader reader = new BsonReader(ms);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("/abc/i", reader.Value);
+      Assert.AreEqual(typeof(string), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("//", reader.Value);
+      Assert.AreEqual(typeof(string), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      Assert.IsFalse(reader.Read());
+    }
+
+    [Test]
+    public void CanRoundTripStackOverflowData()
+    {
+      var doc =
+          @"{
+""AboutMe"": ""<p>I'm the Director for Research and Development for <a href=\""http://www.prophoenix.com\"" rel=\""nofollow\"">ProPhoenix</a>, a public safety software company.  This position allows me to investigate new and existing technologies and incorporate them into our product line, with the end goal being to help public safety agencies to do their jobs more effeciently and safely.</p>\r\n\r\n<p>I'm an advocate for PowerShell, as I believe it encourages administrative best practices and allows developers to provide additional access to their applications, without needing to explicity write code for each administrative feature.  Part of my advocacy for PowerShell includes <a href=\""http://blog.usepowershell.com\"" rel=\""nofollow\"">my blog</a>, appearances on various podcasts, and acting as a Community Director for <a href=\""http://powershellcommunity.org\"" rel=\""nofollow\"">PowerShellCommunity.Org</a></p>\r\n\r\n<p>I’m also a co-host of Mind of Root (a weekly audio podcast about systems administration, tech news, and topics).</p>\r\n"",
+""WebsiteUrl"": ""http://blog.usepowershell.com""
+}";
+      JObject parsed = JObject.Parse(doc);
+      var memoryStream = new MemoryStream();
+      var bsonWriter = new BsonWriter(memoryStream);
+      parsed.WriteTo(bsonWriter);
+      bsonWriter.Flush();
+      memoryStream.Position = 0;
+
+      BsonReader reader = new BsonReader(memoryStream);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("AboutMe", reader.Value);
+      Assert.AreEqual(typeof(string), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual(@"<p>I'm the Director for Research and Development for <a href=""http://www.prophoenix.com"" rel=""nofollow"">ProPhoenix</a>, a public safety software company.  This position allows me to investigate new and existing technologies and incorporate them into our product line, with the end goal being to help public safety agencies to do their jobs more effeciently and safely.</p>
+
+<p>I'm an advocate for PowerShell, as I believe it encourages administrative best practices and allows developers to provide additional access to their applications, without needing to explicity write code for each administrative feature.  Part of my advocacy for PowerShell includes <a href=""http://blog.usepowershell.com"" rel=""nofollow"">my blog</a>, appearances on various podcasts, and acting as a Community Director for <a href=""http://powershellcommunity.org"" rel=""nofollow"">PowerShellCommunity.Org</a></p>
+
+<p>I’m also a co-host of Mind of Root (a weekly audio podcast about systems administration, tech news, and topics).</p>
+", reader.Value);
+      Assert.AreEqual(typeof(string), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("WebsiteUrl", reader.Value);
+      Assert.AreEqual(typeof(string), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("http://blog.usepowershell.com", reader.Value);
+      Assert.AreEqual(typeof(string), reader.ValueType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      Assert.IsFalse(reader.Read());
+    }
+
+    [Test]
+    public void MultibyteCharacterPropertyNamesAndStrings()
+    {
+      string json = @"{
+  ""ΕΝΤΟΛΗ ΧΧΧ ΧΧΧΧΧΧΧΧΧ ΤΑ ΠΡΩΤΑΣΦΑΛΙΣΤΗΡΙΑ ΠΟΥ ΔΕΝ ΕΧΟΥΝ ΥΠΟΛΟΙΠΟ ΝΑ ΤΑ ΣΤΕΛΝΟΥΜΕ ΑΠΕΥΘΕΙΑΣ ΣΤΟΥΣ ΠΕΛΑΤΕΣ"": ""ΕΝΤΟΛΗ ΧΧΧ ΧΧΧΧΧΧΧΧΧ ΤΑ ΠΡΩΤΑΣΦΑΛΙΣΤΗΡΙΑ ΠΟΥ ΔΕΝ ΕΧΟΥΝ ΥΠΟΛΟΙΠΟ ΝΑ ΤΑ ΣΤΕΛΝΟΥΜΕ ΑΠΕΥΘΕΙΑΣ ΣΤΟΥΣ ΠΕΛΑΤΕΣ""
+}";
+      JObject parsed = JObject.Parse(json);
+      var memoryStream = new MemoryStream();
+      var bsonWriter = new BsonWriter(memoryStream);
+      parsed.WriteTo(bsonWriter);
+      bsonWriter.Flush();
+      memoryStream.Position = 0;
+
+      BsonReader reader = new BsonReader(memoryStream);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("ΕΝΤΟΛΗ ΧΧΧ ΧΧΧΧΧΧΧΧΧ ΤΑ ΠΡΩΤΑΣΦΑΛΙΣΤΗΡΙΑ ΠΟΥ ΔΕΝ ΕΧΟΥΝ ΥΠΟΛΟΙΠΟ ΝΑ ΤΑ ΣΤΕΛΝΟΥΜΕ ΑΠΕΥΘΕΙΑΣ ΣΤΟΥΣ ΠΕΛΑΤΕΣ", reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("ΕΝΤΟΛΗ ΧΧΧ ΧΧΧΧΧΧΧΧΧ ΤΑ ΠΡΩΤΑΣΦΑΛΙΣΤΗΡΙΑ ΠΟΥ ΔΕΝ ΕΧΟΥΝ ΥΠΟΛΟΙΠΟ ΝΑ ΤΑ ΣΤΕΛΝΟΥΜΕ ΑΠΕΥΘΕΙΑΣ ΣΤΟΥΣ ΠΕΛΑΤΕΣ", reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Bson/BsonWriterTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Bson/BsonWriterTests.cs
new file mode 100644 (file)
index 0000000..6b7d83c
--- /dev/null
@@ -0,0 +1,629 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using Newtonsoft.Json.Bson;
+using System.IO;
+using Newtonsoft.Json.Utilities;
+using Newtonsoft.Json.Tests.TestObjects;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Tests.Bson
+{
+  public class BsonWriterTests : TestFixtureBase
+  {
+    [Test]
+    public void CloseOutput()
+    {
+      MemoryStream ms = new MemoryStream();
+      BsonWriter writer = new BsonWriter(ms);
+
+      Assert.IsTrue(ms.CanRead);
+      writer.Close();
+      Assert.IsFalse(ms.CanRead);
+
+      ms = new MemoryStream();
+      writer = new BsonWriter(ms) { CloseOutput = false };
+
+      Assert.IsTrue(ms.CanRead);
+      writer.Close();
+      Assert.IsTrue(ms.CanRead);
+    }
+
+    [Test]
+    public void WriteSingleObject()
+    {
+      MemoryStream ms = new MemoryStream();
+      BsonWriter writer = new BsonWriter(ms);
+
+      writer.WriteStartObject();
+      writer.WritePropertyName("Blah");
+      writer.WriteValue(1);
+      writer.WriteEndObject();
+
+      string bson = MiscellaneousUtils.BytesToHex(ms.ToArray());
+      Assert.AreEqual("0F-00-00-00-10-42-6C-61-68-00-01-00-00-00-00", bson);
+    }
+
+#if !PocketPC && !NET20
+    [Test]
+    public void WriteValues()
+    {
+      MemoryStream ms = new MemoryStream();
+      BsonWriter writer = new BsonWriter(ms);
+
+      writer.WriteStartArray();
+      writer.WriteValue(long.MaxValue);
+      writer.WriteValue((ulong)long.MaxValue);
+      writer.WriteValue(int.MaxValue);
+      writer.WriteValue((uint)int.MaxValue);
+      writer.WriteValue(byte.MaxValue);
+      writer.WriteValue(sbyte.MaxValue);
+      writer.WriteValue('a');
+      writer.WriteValue(decimal.MaxValue);
+      writer.WriteValue(double.MaxValue);
+      writer.WriteValue(float.MaxValue);
+      writer.WriteValue(true);
+      writer.WriteValue(new byte[] { 0, 1, 2, 3, 4 });
+      writer.WriteValue(new DateTimeOffset(2000, 12, 29, 12, 30, 0, TimeSpan.Zero));
+      writer.WriteValue(new DateTime(2000, 12, 29, 12, 30, 0, DateTimeKind.Utc));
+      writer.WriteEnd();
+
+      string bson = MiscellaneousUtils.BytesToHex(ms.ToArray());
+      Assert.AreEqual("8C-00-00-00-12-30-00-FF-FF-FF-FF-FF-FF-FF-7F-12-31-00-FF-FF-FF-FF-FF-FF-FF-7F-10-32-00-FF-FF-FF-7F-10-33-00-FF-FF-FF-7F-10-34-00-FF-00-00-00-10-35-00-7F-00-00-00-02-36-00-02-00-00-00-61-00-01-37-00-00-00-00-00-00-00-F0-45-01-38-00-FF-FF-FF-FF-FF-FF-EF-7F-01-39-00-00-00-00-E0-FF-FF-EF-47-08-31-30-00-01-05-31-31-00-05-00-00-00-00-00-01-02-03-04-09-31-32-00-40-C5-E2-BA-E3-00-00-00-09-31-33-00-40-C5-E2-BA-E3-00-00-00-00", bson);
+    }
+#endif
+
+    [Test]
+    public void WriteArrayBsonFromSite()
+    {
+      MemoryStream ms = new MemoryStream();
+      BsonWriter writer = new BsonWriter(ms);
+      writer.WriteStartArray();
+      writer.WriteValue("a");
+      writer.WriteValue("b");
+      writer.WriteValue("c");
+      writer.WriteEndArray();
+      
+      writer.Flush();
+
+      ms.Seek(0, SeekOrigin.Begin);
+
+      string expected = "20-00-00-00-02-30-00-02-00-00-00-61-00-02-31-00-02-00-00-00-62-00-02-32-00-02-00-00-00-63-00-00";
+      string bson = MiscellaneousUtils.BytesToHex(ms.ToArray());
+
+      Assert.AreEqual(expected, bson);
+    }
+
+    [Test]
+    public void WriteBytes()
+    {
+      byte[] data = Encoding.UTF8.GetBytes("Hello world!");
+
+      MemoryStream ms = new MemoryStream();
+      BsonWriter writer = new BsonWriter(ms);
+      writer.WriteStartArray();
+      writer.WriteValue("a");
+      writer.WriteValue("b");
+      writer.WriteValue(data);
+      writer.WriteEndArray();
+
+      writer.Flush();
+
+      ms.Seek(0, SeekOrigin.Begin);
+
+      string expected = "2B-00-00-00-02-30-00-02-00-00-00-61-00-02-31-00-02-00-00-00-62-00-05-32-00-0C-00-00-00-00-48-65-6C-6C-6F-20-77-6F-72-6C-64-21-00";
+      string bson = MiscellaneousUtils.BytesToHex(ms.ToArray());
+
+      Assert.AreEqual(expected, bson);
+
+      BsonReader reader = new BsonReader(new MemoryStream(ms.ToArray()));
+      reader.ReadRootValueAsArray = true;
+      reader.Read();
+      reader.Read();
+      reader.Read();
+      reader.Read();
+      Assert.AreEqual(JsonToken.Bytes, reader.TokenType);
+      Assert.AreEqual(data, reader.Value);
+    }
+
+    [Test]
+    public void WriteNestedArray()
+    {
+      MemoryStream ms = new MemoryStream();
+      BsonWriter writer = new BsonWriter(ms);
+      writer.WriteStartObject();
+
+      writer.WritePropertyName("_id");
+      writer.WriteValue(MiscellaneousUtils.HexToBytes("4A-78-93-79-17-22-00-00-00-00-61-CF"));
+
+      writer.WritePropertyName("a");
+      writer.WriteStartArray();
+      for (int i = 1; i <= 8; i++)
+      {
+        double value = (i != 5)
+                         ? Convert.ToDouble(i)
+                         : 5.78960446186581E+77d;
+
+        writer.WriteValue(value);
+      }
+      writer.WriteEndArray();
+
+      writer.WritePropertyName("b");
+      writer.WriteValue("test");
+
+      writer.WriteEndObject();
+
+      writer.Flush();
+
+      ms.Seek(0, SeekOrigin.Begin);
+
+      string expected = "87-00-00-00-05-5F-69-64-00-0C-00-00-00-00-4A-78-93-79-17-22-00-00-00-00-61-CF-04-61-00-5D-00-00-00-01-30-00-00-00-00-00-00-00-F0-3F-01-31-00-00-00-00-00-00-00-00-40-01-32-00-00-00-00-00-00-00-08-40-01-33-00-00-00-00-00-00-00-10-40-01-34-00-00-00-00-00-00-00-14-50-01-35-00-00-00-00-00-00-00-18-40-01-36-00-00-00-00-00-00-00-1C-40-01-37-00-00-00-00-00-00-00-20-40-00-02-62-00-05-00-00-00-74-65-73-74-00-00";
+      string bson = MiscellaneousUtils.BytesToHex(ms.ToArray());
+
+      Assert.AreEqual(expected, bson);
+    }
+
+    [Test]
+    public void WriteSerializedStore()
+    {
+      MemoryStream ms = new MemoryStream();
+      BsonWriter writer = new BsonWriter(ms);
+
+      Store s1 = new Store();
+      s1.Color = StoreColor.White;
+      s1.Cost = 999.59m;
+      s1.Employees = int.MaxValue - 1;
+      s1.Open = true;
+      s1.product.Add(new Product
+                       {
+                         ExpiryDate = new DateTime(2000, 9, 28, 3, 59, 58, DateTimeKind.Local),
+                         Name = "BSON!",
+                         Price = -0.1m,
+                         Sizes = new [] { "First", "Second" }
+                       });
+      s1.Establised = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Local);
+
+      JsonSerializer serializer = new JsonSerializer();
+      serializer.Serialize(writer, s1);
+
+      ms.Seek(0, SeekOrigin.Begin);
+      BsonReader reader = new BsonReader(ms);
+      Store s2 = (Store)serializer.Deserialize(reader, typeof (Store));
+
+      Assert.AreNotEqual(s1, s2);
+      Assert.AreEqual(s1.Color, s2.Color);
+      Assert.AreEqual(s1.Cost, s2.Cost);
+      Assert.AreEqual(s1.Employees, s2.Employees);
+      Assert.AreEqual(s1.Escape, s2.Escape);
+      Assert.AreEqual(s1.Establised, s2.Establised);
+      Assert.AreEqual(s1.Mottos.Count, s2.Mottos.Count);
+      Assert.AreEqual(s1.Mottos.First(), s2.Mottos.First());
+      Assert.AreEqual(s1.Mottos.Last(), s2.Mottos.Last());
+      Assert.AreEqual(s1.Open, s2.Open);
+      Assert.AreEqual(s1.product.Count, s2.product.Count);
+      Assert.AreEqual(s1.RoomsPerFloor.Length, s2.RoomsPerFloor.Length);
+      Assert.AreEqual(s1.Symbol, s2.Symbol);
+      Assert.AreEqual(s1.Width, s2.Width);
+
+      MemoryStream ms1 = new MemoryStream();
+      BsonWriter writer1 = new BsonWriter(ms1);
+
+      serializer.Serialize(writer1, s1);
+
+      Assert.AreEqual(ms.ToArray(), ms1.ToArray());
+
+      string s = JsonConvert.SerializeObject(s1);
+      byte[] textData = Encoding.UTF8.GetBytes(s);
+
+      int l1 = textData.Length;
+      int l2 = ms.ToArray().Length;
+
+      Console.WriteLine(l1);
+      Console.WriteLine(l2);
+    }
+
+    [Test]
+    public void WriteLargeStrings()
+    {
+      MemoryStream ms = new MemoryStream();
+      BsonWriter writer = new BsonWriter(ms);
+
+      StringBuilder largeStringBuilder = new StringBuilder();
+      for (int i = 0; i < 100; i++)
+      {
+        if (i > 0)
+          largeStringBuilder.Append("-");
+
+        largeStringBuilder.Append(i.ToString(CultureInfo.InvariantCulture));
+      }
+      string largeString = largeStringBuilder.ToString();
+
+      writer.WriteStartObject();
+      writer.WritePropertyName(largeString);
+      writer.WriteValue(largeString);
+      writer.WriteEndObject();
+
+      string bson = MiscellaneousUtils.BytesToHex(ms.ToArray());
+      Assert.AreEqual("4E-02-00-00-02-30-2D-31-2D-32-2D-33-2D-34-2D-35-2D-36-2D-37-2D-38-2D-39-2D-31-30-2D-31-31-2D-31-32-2D-31-33-2D-31-34-2D-31-35-2D-31-36-2D-31-37-2D-31-38-2D-31-39-2D-32-30-2D-32-31-2D-32-32-2D-32-33-2D-32-34-2D-32-35-2D-32-36-2D-32-37-2D-32-38-2D-32-39-2D-33-30-2D-33-31-2D-33-32-2D-33-33-2D-33-34-2D-33-35-2D-33-36-2D-33-37-2D-33-38-2D-33-39-2D-34-30-2D-34-31-2D-34-32-2D-34-33-2D-34-34-2D-34-35-2D-34-36-2D-34-37-2D-34-38-2D-34-39-2D-35-30-2D-35-31-2D-35-32-2D-35-33-2D-35-34-2D-35-35-2D-35-36-2D-35-37-2D-35-38-2D-35-39-2D-36-30-2D-36-31-2D-36-32-2D-36-33-2D-36-34-2D-36-35-2D-36-36-2D-36-37-2D-36-38-2D-36-39-2D-37-30-2D-37-31-2D-37-32-2D-37-33-2D-37-34-2D-37-35-2D-37-36-2D-37-37-2D-37-38-2D-37-39-2D-38-30-2D-38-31-2D-38-32-2D-38-33-2D-38-34-2D-38-35-2D-38-36-2D-38-37-2D-38-38-2D-38-39-2D-39-30-2D-39-31-2D-39-32-2D-39-33-2D-39-34-2D-39-35-2D-39-36-2D-39-37-2D-39-38-2D-39-39-00-22-01-00-00-30-2D-31-2D-32-2D-33-2D-34-2D-35-2D-36-2D-37-2D-38-2D-39-2D-31-30-2D-31-31-2D-31-32-2D-31-33-2D-31-34-2D-31-35-2D-31-36-2D-31-37-2D-31-38-2D-31-39-2D-32-30-2D-32-31-2D-32-32-2D-32-33-2D-32-34-2D-32-35-2D-32-36-2D-32-37-2D-32-38-2D-32-39-2D-33-30-2D-33-31-2D-33-32-2D-33-33-2D-33-34-2D-33-35-2D-33-36-2D-33-37-2D-33-38-2D-33-39-2D-34-30-2D-34-31-2D-34-32-2D-34-33-2D-34-34-2D-34-35-2D-34-36-2D-34-37-2D-34-38-2D-34-39-2D-35-30-2D-35-31-2D-35-32-2D-35-33-2D-35-34-2D-35-35-2D-35-36-2D-35-37-2D-35-38-2D-35-39-2D-36-30-2D-36-31-2D-36-32-2D-36-33-2D-36-34-2D-36-35-2D-36-36-2D-36-37-2D-36-38-2D-36-39-2D-37-30-2D-37-31-2D-37-32-2D-37-33-2D-37-34-2D-37-35-2D-37-36-2D-37-37-2D-37-38-2D-37-39-2D-38-30-2D-38-31-2D-38-32-2D-38-33-2D-38-34-2D-38-35-2D-38-36-2D-38-37-2D-38-38-2D-38-39-2D-39-30-2D-39-31-2D-39-32-2D-39-33-2D-39-34-2D-39-35-2D-39-36-2D-39-37-2D-39-38-2D-39-39-00-00", bson);
+    }
+
+    [Test]
+    public void SerializeGoogleGeoCode()
+    {
+      string json = @"{
+  ""name"": ""1600 Amphitheatre Parkway, Mountain View, CA, USA"",
+  ""Status"": {
+    ""code"": 200,
+    ""request"": ""geocode""
+  },
+  ""Placemark"": [
+    {
+      ""address"": ""1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA"",
+      ""AddressDetails"": {
+        ""Country"": {
+          ""CountryNameCode"": ""US"",
+          ""AdministrativeArea"": {
+            ""AdministrativeAreaName"": ""CA"",
+            ""SubAdministrativeArea"": {
+              ""SubAdministrativeAreaName"": ""Santa Clara"",
+              ""Locality"": {
+                ""LocalityName"": ""Mountain View"",
+                ""Thoroughfare"": {
+                  ""ThoroughfareName"": ""1600 Amphitheatre Pkwy""
+                },
+                ""PostalCode"": {
+                  ""PostalCodeNumber"": ""94043""
+                }
+              }
+            }
+          }
+        },
+        ""Accuracy"": 8
+      },
+      ""Point"": {
+        ""coordinates"": [-122.083739, 37.423021, 0]
+      }
+    }
+  ]
+}";
+
+      GoogleMapGeocoderStructure jsonGoogleMapGeocoder = JsonConvert.DeserializeObject<GoogleMapGeocoderStructure>(json);
+
+      MemoryStream ms = new MemoryStream();
+      BsonWriter writer = new BsonWriter(ms);
+
+      JsonSerializer serializer = new JsonSerializer();
+      serializer.Serialize(writer, jsonGoogleMapGeocoder);
+
+      ms.Seek(0, SeekOrigin.Begin);
+      BsonReader reader = new BsonReader(ms);
+      GoogleMapGeocoderStructure bsonGoogleMapGeocoder = (GoogleMapGeocoderStructure)serializer.Deserialize(reader, typeof (GoogleMapGeocoderStructure));
+
+      Assert.IsNotNull(bsonGoogleMapGeocoder);
+      Assert.AreEqual("1600 Amphitheatre Parkway, Mountain View, CA, USA", bsonGoogleMapGeocoder.Name);
+      Assert.AreEqual("200", bsonGoogleMapGeocoder.Status.Code);
+      Assert.AreEqual("geocode", bsonGoogleMapGeocoder.Status.Request);
+
+      IList<Placemark> placemarks = bsonGoogleMapGeocoder.Placemark;
+      Assert.IsNotNull(placemarks);
+      Assert.AreEqual(1, placemarks.Count);
+
+      Placemark placemark = placemarks[0];
+      Assert.AreEqual("1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA", placemark.Address);
+      Assert.AreEqual(8, placemark.AddressDetails.Accuracy);
+      Assert.AreEqual("US", placemark.AddressDetails.Country.CountryNameCode);
+      Assert.AreEqual("CA", placemark.AddressDetails.Country.AdministrativeArea.AdministrativeAreaName);
+      Assert.AreEqual("Santa Clara", placemark.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.SubAdministrativeAreaName);
+      Assert.AreEqual("Mountain View", placemark.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName);
+      Assert.AreEqual("1600 Amphitheatre Pkwy", placemark.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.Thoroughfare.ThoroughfareName);
+      Assert.AreEqual("94043", placemark.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.PostalCode.PostalCodeNumber);
+      Assert.AreEqual(-122.083739m, placemark.Point.Coordinates[0]);
+      Assert.AreEqual(37.423021m, placemark.Point.Coordinates[1]);
+      Assert.AreEqual(0m, placemark.Point.Coordinates[2]);
+    }
+
+    [Test]
+    public void WriteEmptyStrings()
+    {
+      MemoryStream ms = new MemoryStream();
+      BsonWriter writer = new BsonWriter(ms);
+
+      writer.WriteStartObject();
+      writer.WritePropertyName("");
+      writer.WriteValue("");
+      writer.WriteEndObject();
+
+      string bson = MiscellaneousUtils.BytesToHex(ms.ToArray());
+      Assert.AreEqual("0C-00-00-00-02-00-01-00-00-00-00-00", bson);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonWriterException), ExpectedMessage = "Cannot write JSON comment as BSON.")]
+    public void WriteComment()
+    {
+      MemoryStream ms = new MemoryStream();
+      BsonWriter writer = new BsonWriter(ms);
+
+      writer.WriteStartArray();
+      writer.WriteComment("fail");
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonWriterException), ExpectedMessage = "Cannot write JSON constructor as BSON.")]
+    public void WriteConstructor()
+    {
+      MemoryStream ms = new MemoryStream();
+      BsonWriter writer = new BsonWriter(ms);
+
+      writer.WriteStartArray();
+      writer.WriteStartConstructor("fail");
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonWriterException), ExpectedMessage = "Cannot write raw JSON as BSON.")]
+    public void WriteRaw()
+    {
+      MemoryStream ms = new MemoryStream();
+      BsonWriter writer = new BsonWriter(ms);
+
+      writer.WriteStartArray();
+      writer.WriteRaw("fail");
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonWriterException), ExpectedMessage = "Cannot write raw JSON as BSON.")]
+    public void WriteRawValue()
+    {
+      MemoryStream ms = new MemoryStream();
+      BsonWriter writer = new BsonWriter(ms);
+
+      writer.WriteStartArray();
+      writer.WriteRawValue("fail");
+    }
+
+    [Test]
+    public void Example()
+    {
+      Product p = new Product();
+      p.ExpiryDate = DateTime.Parse("2009-04-05T14:45:00Z");
+      p.Name = "Carlos' Spicy Wieners";
+      p.Price = 9.95m;
+      p.Sizes = new[] { "Small", "Medium", "Large" };
+
+      MemoryStream ms = new MemoryStream();
+      JsonSerializer serializer = new JsonSerializer();
+
+      // serialize product to BSON
+      BsonWriter writer = new BsonWriter(ms);
+      serializer.Serialize(writer, p);
+
+      Console.WriteLine(BitConverter.ToString(ms.ToArray()));
+      // 7C-00-00-00-02-4E-61-6D-65-00-16-00-00-00-43-61-72-6C-
+      // 6F-73-27-20-53-70-69-63-79-20-57-69-65-6E-65-72-73-00-
+      // 09-45-78-70-69-72-79-44-61-74-65-00-E0-51-BD-76-20-01-
+      // 00-00-01-50-72-69-63-65-00-66-66-66-66-66-E6-23-40-04-
+      // 53-69-7A-65-73-00-2D-00-00-00-02-30-00-06-00-00-00-53-
+      // 6D-61-6C-6C-00-02-31-00-07-00-00-00-4D-65-64-69-75-6D-
+      // 00-02-32-00-06-00-00-00-4C-61-72-67-65-00-00-00
+
+
+      ms.Seek(0, SeekOrigin.Begin);
+
+      // deserialize product from BSON
+      BsonReader reader = new BsonReader(ms);
+      Product deserializedProduct = serializer.Deserialize<Product>(reader);
+
+      Console.WriteLine(deserializedProduct.Name);
+      // Carlos' Spicy Wieners
+
+
+      Assert.AreEqual("Carlos' Spicy Wieners", deserializedProduct.Name);
+      Assert.AreEqual(9.95m, deserializedProduct.Price);
+      Assert.AreEqual(3, deserializedProduct.Sizes.Length);
+    }
+
+    [Test]
+    public void WriteOid()
+    {
+      MemoryStream ms = new MemoryStream();
+      BsonWriter writer = new BsonWriter(ms);
+
+      byte[] oid = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
+
+      writer.WriteStartObject();
+      writer.WritePropertyName("_oid");
+      writer.WriteObjectId(oid);
+      writer.WriteEndObject();
+
+      string bson = MiscellaneousUtils.BytesToHex(ms.ToArray());
+      Assert.AreEqual("17-00-00-00-07-5F-6F-69-64-00-01-02-03-04-05-06-07-08-09-0A-0B-0C-00", bson);
+
+      ms.Seek(0, SeekOrigin.Begin);
+      BsonReader reader = new BsonReader(ms);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Bytes, reader.TokenType);
+      Assert.AreEqual(oid, reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+    }
+
+    [Test]
+    public void WriteOidPlusContent()
+    {
+      MemoryStream ms = new MemoryStream();
+      BsonWriter writer = new BsonWriter(ms);
+
+      writer.WriteStartObject();
+      writer.WritePropertyName("_id");
+      writer.WriteObjectId(MiscellaneousUtils.HexToBytes("4ABBED9D1D8B0F0218000001"));
+      writer.WritePropertyName("test");
+      writer.WriteValue("1234£56");
+      writer.WriteEndObject();
+
+      byte[] expected = MiscellaneousUtils.HexToBytes("29000000075F6964004ABBED9D1D8B0F02180000010274657374000900000031323334C2A335360000");
+
+      Assert.AreEqual(expected, ms.ToArray());
+    }
+
+    [Test]
+    public void WriteRegexPlusContent()
+    {
+      MemoryStream ms = new MemoryStream();
+      BsonWriter writer = new BsonWriter(ms);
+
+      writer.WriteStartObject();
+      writer.WritePropertyName("regex");
+      writer.WriteRegex("abc", "i");
+      writer.WritePropertyName("test");
+      writer.WriteRegex(string.Empty, null);
+      writer.WriteEndObject();
+
+      byte[] expected = MiscellaneousUtils.HexToBytes("1A-00-00-00-0B-72-65-67-65-78-00-61-62-63-00-69-00-0B-74-65-73-74-00-00-00-00");
+
+      Assert.AreEqual(expected, ms.ToArray());
+    }
+
+    [Test]
+    public void SerializeEmptyAndNullStrings()
+    {
+      Product p = new Product();
+      p.ExpiryDate = DateTime.Parse("2009-04-05T14:45:00Z");
+      p.Name = null;
+      p.Price = 9.95m;
+      p.Sizes = new[] { "Small", "", null };
+
+      MemoryStream ms = new MemoryStream();
+      JsonSerializer serializer = new JsonSerializer();
+
+      BsonWriter writer = new BsonWriter(ms);
+      serializer.Serialize(writer, p);
+
+      ms.Seek(0, SeekOrigin.Begin);
+
+      BsonReader reader = new BsonReader(ms);
+      Product deserializedProduct = serializer.Deserialize<Product>(reader);
+
+      Console.WriteLine(deserializedProduct.Name);
+
+      Assert.AreEqual(null, deserializedProduct.Name);
+      Assert.AreEqual(9.95m, deserializedProduct.Price);
+      Assert.AreEqual(3, deserializedProduct.Sizes.Length);
+      Assert.AreEqual("Small", deserializedProduct.Sizes[0]);
+      Assert.AreEqual("", deserializedProduct.Sizes[1]);
+      Assert.AreEqual(null, deserializedProduct.Sizes[2]);
+    }
+
+    [Test]
+    public void WriteReadEmptyAndNullStrings()
+    {
+      MemoryStream ms = new MemoryStream();
+      BsonWriter writer = new BsonWriter(ms);
+
+      writer.WriteStartArray();
+      writer.WriteValue("Content!");
+      writer.WriteValue("");
+      writer.WriteValue((string)null);
+      writer.WriteEndArray();
+
+      ms.Seek(0, SeekOrigin.Begin);
+
+      BsonReader reader = new BsonReader(ms);
+      reader.ReadRootValueAsArray = true;
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("Content!", reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("", reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Null, reader.TokenType);
+      Assert.AreEqual(null, reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
+
+      Assert.IsFalse(reader.Read());
+    }
+
+    [Test]
+    public void WriteDateTimes()
+    {
+      MemoryStream ms = new MemoryStream();
+      BsonWriter writer = new BsonWriter(ms);
+      writer.DateTimeKindHandling = DateTimeKind.Unspecified;
+
+      writer.WriteStartArray();
+      writer.WriteValue(new DateTime(2000, 10, 12, 20, 55, 0, DateTimeKind.Utc));
+      writer.WriteValue(new DateTime(2000, 10, 12, 20, 55, 0, DateTimeKind.Local));
+      writer.WriteValue(new DateTime(2000, 10, 12, 20, 55, 0, DateTimeKind.Unspecified));
+      writer.WriteEndArray();
+
+      ms.Seek(0, SeekOrigin.Begin);
+
+      BsonReader reader = new BsonReader(ms);
+      reader.ReadRootValueAsArray = true;
+      reader.DateTimeKindHandling = DateTimeKind.Utc;
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Date, reader.TokenType);
+      Assert.AreEqual(new DateTime(2000, 10, 12, 20, 55, 0, DateTimeKind.Utc), reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Date, reader.TokenType);
+      Assert.AreEqual(new DateTime(2000, 10, 12, 20, 55, 0, DateTimeKind.Utc), reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Date, reader.TokenType);
+      Assert.AreEqual(new DateTime(2000, 10, 12, 20, 55, 0, DateTimeKind.Utc), reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
+
+      Assert.IsFalse(reader.Read());
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/BinaryConverterTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/BinaryConverterTests.cs
new file mode 100644 (file)
index 0000000..0643c18
--- /dev/null
@@ -0,0 +1,136 @@
+using System;
+using System.Collections.Generic;
+#if !SILVERLIGHT && !PocketPC && !NET20
+using System.Data.Linq;
+#endif
+#if !SILVERLIGHT
+using System.Data.SqlTypes;
+#endif
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Converters;
+using NUnit.Framework;
+using Newtonsoft.Json.Tests.TestObjects;
+
+namespace Newtonsoft.Json.Tests.Converters
+{
+  public class BinaryConverterTests : TestFixtureBase
+  {
+    private static readonly byte[] TestData = Encoding.UTF8.GetBytes("This is some test data!!!");
+
+    public class ByteArrayClass
+    {
+      public byte[] ByteArray { get; set; }
+      public byte[] NullByteArray { get; set; }
+    }
+
+#if !SILVERLIGHT && !PocketPC && !NET20
+    [Test]
+    public void DeserializeBinaryClass()
+    {
+      string json = @"{
+  ""Binary"": ""VGhpcyBpcyBzb21lIHRlc3QgZGF0YSEhIQ=="",
+  ""NullBinary"": null
+}";
+
+      BinaryClass binaryClass = JsonConvert.DeserializeObject<BinaryClass>(json, new BinaryConverter());
+
+      Assert.AreEqual(new Binary(TestData), binaryClass.Binary);
+      Assert.AreEqual(null, binaryClass.NullBinary);
+    }
+
+    public class BinaryClass
+    {
+      public Binary Binary { get; set; }
+      public Binary NullBinary { get; set; }
+    }
+
+    [Test]
+    public void SerializeBinaryClass()
+    {
+      BinaryClass binaryClass = new BinaryClass();
+      binaryClass.Binary = new Binary(TestData);
+      binaryClass.NullBinary = null;
+
+      string json = JsonConvert.SerializeObject(binaryClass, Formatting.Indented, new BinaryConverter());
+
+      Assert.AreEqual(@"{
+  ""Binary"": ""VGhpcyBpcyBzb21lIHRlc3QgZGF0YSEhIQ=="",
+  ""NullBinary"": null
+}", json);
+    }
+#endif
+
+    [Test]
+    public void SerializeByteArrayClass()
+    {
+      ByteArrayClass byteArrayClass = new ByteArrayClass();
+      byteArrayClass.ByteArray = TestData;
+      byteArrayClass.NullByteArray = null;
+
+      string json = JsonConvert.SerializeObject(byteArrayClass, Formatting.Indented, new BinaryConverter());
+
+      Assert.AreEqual(@"{
+  ""ByteArray"": ""VGhpcyBpcyBzb21lIHRlc3QgZGF0YSEhIQ=="",
+  ""NullByteArray"": null
+}", json);
+    }
+
+#if !SILVERLIGHT
+    public class SqlBinaryClass
+    {
+      public SqlBinary SqlBinary { get; set; }
+      public SqlBinary? NullableSqlBinary1 { get; set; }
+      public SqlBinary? NullableSqlBinary2 { get; set; }
+    }
+
+    [Test]
+    public void SerializeSqlBinaryClass()
+    {
+      SqlBinaryClass sqlBinaryClass = new SqlBinaryClass();
+      sqlBinaryClass.SqlBinary = new SqlBinary(TestData);
+      sqlBinaryClass.NullableSqlBinary1 = new SqlBinary(TestData);
+      sqlBinaryClass.NullableSqlBinary2 = null;
+
+      string json = JsonConvert.SerializeObject(sqlBinaryClass, Formatting.Indented, new BinaryConverter());
+
+      Assert.AreEqual(@"{
+  ""SqlBinary"": ""VGhpcyBpcyBzb21lIHRlc3QgZGF0YSEhIQ=="",
+  ""NullableSqlBinary1"": ""VGhpcyBpcyBzb21lIHRlc3QgZGF0YSEhIQ=="",
+  ""NullableSqlBinary2"": null
+}", json);
+    }
+
+    [Test]
+    public void DeserializeSqlBinaryClass()
+    {
+      string json = @"{
+  ""SqlBinary"": ""VGhpcyBpcyBzb21lIHRlc3QgZGF0YSEhIQ=="",
+  ""NullableSqlBinary1"": ""VGhpcyBpcyBzb21lIHRlc3QgZGF0YSEhIQ=="",
+  ""NullableSqlBinary2"": null
+}";
+
+      SqlBinaryClass sqlBinaryClass = JsonConvert.DeserializeObject<SqlBinaryClass>(json, new BinaryConverter());
+
+      Assert.AreEqual(new SqlBinary(TestData), sqlBinaryClass.SqlBinary);
+      Assert.AreEqual(new SqlBinary(TestData), sqlBinaryClass.NullableSqlBinary1);
+      Assert.AreEqual(null, sqlBinaryClass.NullableSqlBinary2);
+    }
+#endif
+
+    [Test]
+    public void DeserializeByteArrayClass()
+    {
+      string json = @"{
+  ""ByteArray"": ""VGhpcyBpcyBzb21lIHRlc3QgZGF0YSEhIQ=="",
+  ""NullByteArray"": null
+}";
+
+      ByteArrayClass byteArrayClass = JsonConvert.DeserializeObject<ByteArrayClass>(json, new BinaryConverter());
+
+      Assert.AreEqual(TestData, byteArrayClass.ByteArray);
+      Assert.AreEqual(null, byteArrayClass.NullByteArray);
+    }
+
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/CustomCreationConverterTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/CustomCreationConverterTests.cs
new file mode 100644 (file)
index 0000000..d66ddf3
--- /dev/null
@@ -0,0 +1,230 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Converters;
+using NUnit.Framework;
+
+namespace Newtonsoft.Json.Tests.Converters
+{
+  public class CustomCreationConverterTests : TestFixtureBase
+  {
+    public interface IPerson
+    {
+      string FirstName { get; set; }
+      string LastName { get; set; }
+      DateTime BirthDate { get; set; }
+    }
+
+    public class Employee : IPerson
+    {
+      public string FirstName { get; set; }
+      public string LastName { get; set; }
+      public DateTime BirthDate { get; set; }
+
+      public string Department { get; set; }
+      public string JobTitle { get; set; }
+    }
+
+    public class PersonConverter : CustomCreationConverter<IPerson>
+    {
+      public override IPerson Create(Type objectType)
+      {
+        return new Employee();
+      }
+    }
+
+    public void DeserializeObject()
+    {
+      string json = JsonConvert.SerializeObject(new List<Employee>
+        {
+          new Employee
+            {
+              BirthDate = new DateTime(1977, 12, 30, 1, 1, 1, DateTimeKind.Utc),
+              FirstName = "Maurice",
+              LastName = "Moss",
+              Department = "IT",
+              JobTitle = "Support"
+            },
+          new Employee
+            {
+              BirthDate = new DateTime(1978, 3, 15, 1, 1, 1, DateTimeKind.Utc),
+              FirstName = "Jen",
+              LastName = "Barber",
+              Department = "IT",
+              JobTitle = "Manager"
+            }
+        }, Formatting.Indented);
+
+      //[
+      //  {
+      //    "FirstName": "Maurice",
+      //    "LastName": "Moss",
+      //    "BirthDate": "\/Date(252291661000)\/",
+      //    "Department": "IT",
+      //    "JobTitle": "Support"
+      //  },
+      //  {
+      //    "FirstName": "Jen",
+      //    "LastName": "Barber",
+      //    "BirthDate": "\/Date(258771661000)\/",
+      //    "Department": "IT",
+      //    "JobTitle": "Manager"
+      //  }
+      //]
+
+      List<IPerson> people = JsonConvert.DeserializeObject<List<IPerson>>(json, new PersonConverter());
+
+      IPerson person = people[0];
+
+      Console.WriteLine(person.GetType());
+      // Newtonsoft.Json.Tests.Employee
+
+      Console.WriteLine(person.FirstName);
+      // Maurice
+
+      Employee employee = (Employee)person;
+
+      Console.WriteLine(employee.JobTitle);
+      // Support
+    }
+
+    public class MyClass
+    {
+      public string Value { get; set; }
+
+      [JsonConverter(typeof(MyThingConverter))]
+      public IThing Thing { get; set; }
+    }
+
+    public interface IThing
+    {
+      int Number { get; }
+    }
+
+    public class MyThing : IThing
+    {
+      public int Number { get; set; }
+    }
+
+    public class MyThingConverter : CustomCreationConverter<IThing>
+    {
+      public override IThing Create(Type objectType)
+      {
+        return new MyThing();
+      }
+    }
+
+    [Test]
+    public void AssertDoesDeserialize()
+    {
+      const string json = @"{
+""Value"": ""A value"",
+""Thing"": {
+""Number"": 123
+}
+}
+";
+      MyClass myClass = JsonConvert.DeserializeObject<MyClass>(json);
+      Assert.IsNotNull(myClass);
+      Assert.AreEqual("A value", myClass.Value);
+      Assert.IsNotNull(myClass.Thing);
+      Assert.AreEqual(123, myClass.Thing.Number);
+    }
+
+    [Test]
+    public void AssertShouldSerializeTest()
+    {
+      MyClass myClass = new MyClass
+      {
+        Value = "Foo",
+        Thing = new MyThing { Number = 456, }
+      };
+      string json = JsonConvert.SerializeObject(myClass); // <-- Exception here
+
+      const string expected = @"{""Value"":""Foo"",""Thing"":{""Number"":456}}";
+      Assert.AreEqual(expected, json);
+    }
+
+    internal interface IRange<T>
+    {
+      T First { get; }
+      T Last { get; }
+    }
+
+    internal class Range<T> : IRange<T>
+    {
+      public T First { get; set; }
+      public T Last { get; set; }
+    }
+
+    internal class NullInterfaceTestClass
+    {
+      public virtual Guid Id { get; set; }
+      public virtual int? Year { get; set; }
+      public virtual string Company { get; set; }
+      public virtual IRange<decimal> DecimalRange { get; set; }
+      public virtual IRange<int> IntRange { get; set; }
+      public virtual IRange<decimal> NullDecimalRange { get; set; }
+    }
+
+    internal class DecimalRangeConverter : CustomCreationConverter<IRange<decimal>>
+    {
+      public override IRange<decimal> Create(Type objectType)
+      {
+        return new Range<decimal>();
+      }
+    }
+
+    internal class IntRangeConverter : CustomCreationConverter<IRange<int>>
+    {
+      public override IRange<int> Create(Type objectType)
+      {
+        return new Range<int>();
+      }
+    }
+
+    [Test]
+    public void DeserializeAndConvertNullValue()
+    {
+      NullInterfaceTestClass initial = new NullInterfaceTestClass
+      {
+        Company = "Company!",
+        DecimalRange = new Range<decimal> { First = 0, Last = 1 },
+        Id = new Guid(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11),
+        IntRange = new Range<int> { First = int.MinValue, Last = int.MaxValue },
+        Year = 2010,
+        NullDecimalRange = null
+      };
+
+      string json = JsonConvert.SerializeObject(initial, Formatting.Indented);
+
+      Assert.AreEqual(@"{
+  ""Id"": ""00000001-0002-0003-0405-060708090a0b"",
+  ""Year"": 2010,
+  ""Company"": ""Company!"",
+  ""DecimalRange"": {
+    ""First"": 0.0,
+    ""Last"": 1.0
+  },
+  ""IntRange"": {
+    ""First"": -2147483648,
+    ""Last"": 2147483647
+  },
+  ""NullDecimalRange"": null
+}", json);
+
+      NullInterfaceTestClass deserialized = JsonConvert.DeserializeObject<NullInterfaceTestClass>(
+        json, new IntRangeConverter(), new DecimalRangeConverter());
+
+      Assert.AreEqual("Company!", deserialized.Company);
+      Assert.AreEqual(new Guid(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), deserialized.Id);
+      Assert.AreEqual(0, deserialized.DecimalRange.First);
+      Assert.AreEqual(1, deserialized.DecimalRange.Last);
+      Assert.AreEqual(int.MinValue, deserialized.IntRange.First);
+      Assert.AreEqual(int.MaxValue, deserialized.IntRange.Last);
+      Assert.AreEqual(null, deserialized.NullDecimalRange);
+      Assert.AreEqual(2010, deserialized.Year);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/DataSetConverterTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/DataSetConverterTests.cs
new file mode 100644 (file)
index 0000000..eedfed4
--- /dev/null
@@ -0,0 +1,335 @@
+#if !SILVERLIGHT
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Converters;
+using NUnit.Framework;
+using Newtonsoft.Json.Tests.TestObjects;
+using System.Data;
+
+namespace Newtonsoft.Json.Tests.Converters
+{
+  public class DataSetConverterTests : TestFixtureBase
+  {
+    [Test]
+    public void SerializeAndDeserialize()
+    {
+      DataSet dataSet = new DataSet("dataSet");
+      dataSet.Namespace = "NetFrameWork";
+      DataTable table = new DataTable();
+      DataColumn idColumn = new DataColumn("id", typeof(int));
+      idColumn.AutoIncrement = true;
+
+      DataColumn itemColumn = new DataColumn("item");
+      table.Columns.Add(idColumn);
+      table.Columns.Add(itemColumn);
+      dataSet.Tables.Add(table);
+
+      for (int i = 0; i < 2; i++)
+      {
+        DataRow newRow = table.NewRow();
+        newRow["item"] = "item " + i;
+        table.Rows.Add(newRow);
+      }
+
+      dataSet.AcceptChanges();
+
+      string json = JsonConvert.SerializeObject(dataSet, Formatting.Indented);
+      
+      Assert.AreEqual(@"{
+  ""Table1"": [
+    {
+      ""id"": 0,
+      ""item"": ""item 0""
+    },
+    {
+      ""id"": 1,
+      ""item"": ""item 1""
+    }
+  ]
+}", json);
+
+      DataSet deserializedDataSet = JsonConvert.DeserializeObject<DataSet>(json);
+      Assert.IsNotNull(deserializedDataSet);
+
+      Assert.AreEqual(1, deserializedDataSet.Tables.Count);
+
+      DataTable dt = deserializedDataSet.Tables[0];
+
+      Assert.AreEqual("Table1", dt.TableName);
+      Assert.AreEqual(2, dt.Columns.Count);
+      Assert.AreEqual("id", dt.Columns[0].ColumnName);
+      Assert.AreEqual(typeof(long), dt.Columns[0].DataType);
+      Assert.AreEqual("item", dt.Columns[1].ColumnName);
+      Assert.AreEqual(typeof(string), dt.Columns[1].DataType);
+
+      Assert.AreEqual(2, dt.Rows.Count);
+    }
+
+    [Test]
+    public void SerializeMultiTableDataSet()
+    {
+      DataSet ds = new DataSet();
+      ds.Tables.Add(CreateDataTable("FirstTable", 2));
+      ds.Tables.Add(CreateDataTable("SecondTable", 1));
+
+      string json = JsonConvert.SerializeObject(ds, Formatting.Indented, new IsoDateTimeConverter());
+      // {
+      //   "FirstTable": [
+      //     {
+      //       "StringCol": "Item Name",
+      //       "Int32Col": 1,
+      //       "BooleanCol": true,
+      //       "TimeSpanCol": "10.22:10:15.1000000",
+      //       "DateTimeCol": "2000-12-29T00:00:00Z",
+      //       "DecimalCol": 64.0021
+      //     },
+      //     {
+      //       "StringCol": "Item Name",
+      //       "Int32Col": 2,
+      //       "BooleanCol": true,
+      //       "TimeSpanCol": "10.22:10:15.1000000",
+      //       "DateTimeCol": "2000-12-29T00:00:00Z",
+      //       "DecimalCol": 64.0021
+      //     }
+      //   ],
+      //   "SecondTable": [
+      //     {
+      //       "StringCol": "Item Name",
+      //       "Int32Col": 1,
+      //       "BooleanCol": true,
+      //       "TimeSpanCol": "10.22:10:15.1000000",
+      //       "DateTimeCol": "2000-12-29T00:00:00Z",
+      //       "DecimalCol": 64.0021
+      //     }
+      //   ]
+      // }
+
+      DataSet deserializedDs = JsonConvert.DeserializeObject<DataSet>(json, new IsoDateTimeConverter());
+
+      Assert.AreEqual(@"{
+  ""FirstTable"": [
+    {
+      ""StringCol"": ""Item Name"",
+      ""Int32Col"": 1,
+      ""BooleanCol"": true,
+      ""TimeSpanCol"": ""10.22:10:15.1000000"",
+      ""DateTimeCol"": ""2000-12-29T00:00:00Z"",
+      ""DecimalCol"": 64.0021
+    },
+    {
+      ""StringCol"": ""Item Name"",
+      ""Int32Col"": 2,
+      ""BooleanCol"": true,
+      ""TimeSpanCol"": ""10.22:10:15.1000000"",
+      ""DateTimeCol"": ""2000-12-29T00:00:00Z"",
+      ""DecimalCol"": 64.0021
+    }
+  ],
+  ""SecondTable"": [
+    {
+      ""StringCol"": ""Item Name"",
+      ""Int32Col"": 1,
+      ""BooleanCol"": true,
+      ""TimeSpanCol"": ""10.22:10:15.1000000"",
+      ""DateTimeCol"": ""2000-12-29T00:00:00Z"",
+      ""DecimalCol"": 64.0021
+    }
+  ]
+}", json);
+
+      Assert.IsNotNull(deserializedDs);
+
+    }
+
+    [Test]
+    public void DeserializeMultiTableDataSet()
+    {
+      string json = @"{
+  ""FirstTable"": [
+    {
+      ""StringCol"": ""Item Name"",
+      ""Int32Col"": 2147483647,
+      ""BooleanCol"": true,
+      ""TimeSpanCol"": ""10.22:10:15.1000000"",
+      ""DateTimeCol"": ""2000-12-29T00:00:00Z"",
+      ""DecimalCol"": 64.0021
+    }
+  ],
+  ""SecondTable"": [
+    {
+      ""StringCol"": ""Item Name"",
+      ""Int32Col"": 2147483647,
+      ""BooleanCol"": true,
+      ""TimeSpanCol"": ""10.22:10:15.1000000"",
+      ""DateTimeCol"": ""2000-12-29T00:00:00Z"",
+      ""DecimalCol"": 64.0021
+    }
+  ]
+}";
+
+      DataSet ds = JsonConvert.DeserializeObject<DataSet>(json, new IsoDateTimeConverter());
+      Assert.IsNotNull(ds);
+
+      Assert.AreEqual(2, ds.Tables.Count);
+      Assert.AreEqual("FirstTable", ds.Tables[0].TableName);
+      Assert.AreEqual("SecondTable", ds.Tables[1].TableName);
+
+      DataTable dt = ds.Tables[0];
+      Assert.AreEqual("StringCol", dt.Columns[0].ColumnName);
+      Assert.AreEqual(typeof(string), dt.Columns[0].DataType);
+      Assert.AreEqual("Int32Col", dt.Columns[1].ColumnName);
+      Assert.AreEqual(typeof(long), dt.Columns[1].DataType);
+      Assert.AreEqual("BooleanCol", dt.Columns[2].ColumnName);
+      Assert.AreEqual(typeof(bool), dt.Columns[2].DataType);
+      Assert.AreEqual("TimeSpanCol", dt.Columns[3].ColumnName);
+      Assert.AreEqual(typeof(string), dt.Columns[3].DataType);
+      Assert.AreEqual("DateTimeCol", dt.Columns[4].ColumnName);
+      Assert.AreEqual(typeof(string), dt.Columns[4].DataType);
+      Assert.AreEqual("DecimalCol", dt.Columns[5].ColumnName);
+      Assert.AreEqual(typeof(double), dt.Columns[5].DataType);
+
+      Assert.AreEqual(1, ds.Tables[0].Rows.Count);
+      Assert.AreEqual(1, ds.Tables[1].Rows.Count);
+    }
+
+    private DataTable CreateDataTable(string dataTableName, int rows)
+    {
+      // create a new DataTable.
+      DataTable myTable = new DataTable(dataTableName);
+
+      // create DataColumn objects of data types.
+      DataColumn colString = new DataColumn("StringCol");
+      colString.DataType = typeof(string);
+      myTable.Columns.Add(colString);
+
+      DataColumn colInt32 = new DataColumn("Int32Col");
+      colInt32.DataType = typeof(int);
+      myTable.Columns.Add(colInt32);
+
+      DataColumn colBoolean = new DataColumn("BooleanCol");
+      colBoolean.DataType = typeof(bool);
+      myTable.Columns.Add(colBoolean);
+
+      DataColumn colTimeSpan = new DataColumn("TimeSpanCol");
+      colTimeSpan.DataType = typeof(TimeSpan);
+      myTable.Columns.Add(colTimeSpan);
+
+      DataColumn colDateTime = new DataColumn("DateTimeCol");
+      colDateTime.DataType = typeof(DateTime);
+      colDateTime.DateTimeMode = DataSetDateTime.Utc;
+      myTable.Columns.Add(colDateTime);
+
+      DataColumn colDecimal = new DataColumn("DecimalCol");
+      colDecimal.DataType = typeof(decimal);
+      myTable.Columns.Add(colDecimal);
+
+      for (int i = 1; i <= rows; i++)
+      {
+        DataRow myNewRow = myTable.NewRow();
+
+        myNewRow["StringCol"] = "Item Name";
+        myNewRow["Int32Col"] = i;
+        myNewRow["BooleanCol"] = true;
+        myNewRow["TimeSpanCol"] = new TimeSpan(10, 22, 10, 15, 100);
+        myNewRow["DateTimeCol"] = new DateTime(2000, 12, 29, 0, 0, 0, DateTimeKind.Utc);
+        myNewRow["DecimalCol"] = 64.0021;
+        myTable.Rows.Add(myNewRow);
+      }
+
+      return myTable;
+    }
+
+    public class DataSetAndTableTestClass
+    {
+      public string Before { get; set; }
+      public DataSet Set { get; set; }
+      public string Middle { get; set; }
+      public DataTable Table { get; set; }
+      public string After { get; set; }
+    }
+
+    [Test]
+    public void Blah()
+    {
+      DataSet ds = new DataSet();
+      ds.Tables.Add(CreateDataTable("FirstTable", 2));
+      ds.Tables.Add(CreateDataTable("SecondTable", 1));
+
+      DataSetAndTableTestClass c = new DataSetAndTableTestClass
+        {
+          Before = "Before",
+          Set = ds,
+          Middle = "Middle",
+          Table = CreateDataTable("LoneTable", 2),
+          After = "After"
+        };
+
+      string json = JsonConvert.SerializeObject(c, Formatting.Indented, new IsoDateTimeConverter());
+
+      Assert.AreEqual(@"{
+  ""Before"": ""Before"",
+  ""Set"": {
+    ""FirstTable"": [
+      {
+        ""StringCol"": ""Item Name"",
+        ""Int32Col"": 1,
+        ""BooleanCol"": true,
+        ""TimeSpanCol"": ""10.22:10:15.1000000"",
+        ""DateTimeCol"": ""2000-12-29T00:00:00Z"",
+        ""DecimalCol"": 64.0021
+      },
+      {
+        ""StringCol"": ""Item Name"",
+        ""Int32Col"": 2,
+        ""BooleanCol"": true,
+        ""TimeSpanCol"": ""10.22:10:15.1000000"",
+        ""DateTimeCol"": ""2000-12-29T00:00:00Z"",
+        ""DecimalCol"": 64.0021
+      }
+    ],
+    ""SecondTable"": [
+      {
+        ""StringCol"": ""Item Name"",
+        ""Int32Col"": 1,
+        ""BooleanCol"": true,
+        ""TimeSpanCol"": ""10.22:10:15.1000000"",
+        ""DateTimeCol"": ""2000-12-29T00:00:00Z"",
+        ""DecimalCol"": 64.0021
+      }
+    ]
+  },
+  ""Middle"": ""Middle"",
+  ""Table"": [
+    {
+      ""StringCol"": ""Item Name"",
+      ""Int32Col"": 1,
+      ""BooleanCol"": true,
+      ""TimeSpanCol"": ""10.22:10:15.1000000"",
+      ""DateTimeCol"": ""2000-12-29T00:00:00Z"",
+      ""DecimalCol"": 64.0021
+    },
+    {
+      ""StringCol"": ""Item Name"",
+      ""Int32Col"": 2,
+      ""BooleanCol"": true,
+      ""TimeSpanCol"": ""10.22:10:15.1000000"",
+      ""DateTimeCol"": ""2000-12-29T00:00:00Z"",
+      ""DecimalCol"": 64.0021
+    }
+  ],
+  ""After"": ""After""
+}", json);
+
+      DataSetAndTableTestClass c2 = JsonConvert.DeserializeObject<DataSetAndTableTestClass>(json, new IsoDateTimeConverter());
+
+      Assert.AreEqual(c.Before, c2.Before);
+      Assert.AreEqual(c.Set.Tables.Count, c2.Set.Tables.Count);
+      Assert.AreEqual(c.Middle, c2.Middle);
+      Assert.AreEqual(c.Table.Rows.Count, c2.Table.Rows.Count);
+      Assert.AreEqual(c.After, c2.After);
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/DataTableConverterTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/DataTableConverterTests.cs
new file mode 100644 (file)
index 0000000..3b578b6
--- /dev/null
@@ -0,0 +1,141 @@
+#if !SILVERLIGHT
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Converters;
+using NUnit.Framework;
+using Newtonsoft.Json.Tests.TestObjects;
+using System.Data;
+
+namespace Newtonsoft.Json.Tests.Converters
+{
+  public class DataTableConverterTests : TestFixtureBase
+  {
+    [Test]
+    public void Deserialize()
+    {
+      string json = @"[
+  {
+    ""id"": 0,
+    ""item"": ""item 0""
+  },
+  {
+    ""id"": 1,
+    ""item"": ""item 1""
+  }
+]";
+
+      DataTable deserializedDataTable = JsonConvert.DeserializeObject<DataTable>(json);
+      Assert.IsNotNull(deserializedDataTable);
+
+      Assert.AreEqual(string.Empty, deserializedDataTable.TableName);
+      Assert.AreEqual(2, deserializedDataTable.Columns.Count);
+      Assert.AreEqual("id", deserializedDataTable.Columns[0].ColumnName);
+      Assert.AreEqual(typeof(long), deserializedDataTable.Columns[0].DataType);
+      Assert.AreEqual("item", deserializedDataTable.Columns[1].ColumnName);
+      Assert.AreEqual(typeof(string), deserializedDataTable.Columns[1].DataType);
+
+      Assert.AreEqual(2, deserializedDataTable.Rows.Count);
+
+      DataRow dr1 = deserializedDataTable.Rows[0];
+      Assert.AreEqual(0, dr1["id"]);
+      Assert.AreEqual("item 0", dr1["item"]);
+
+      DataRow dr2 = deserializedDataTable.Rows[1];
+      Assert.AreEqual(1, dr2["id"]);
+      Assert.AreEqual("item 1", dr2["item"]);
+    }
+
+    [Test]
+    public void Serialize()
+    {
+      // create a new DataTable.
+      DataTable myTable = new DataTable("blah");
+
+      // create DataColumn objects of data types.
+      DataColumn colString = new DataColumn("StringCol");
+      colString.DataType = typeof(string);
+      myTable.Columns.Add(colString);
+
+      DataColumn colInt32 = new DataColumn("Int32Col");
+      colInt32.DataType = typeof(int);
+      myTable.Columns.Add(colInt32);
+
+      DataColumn colBoolean = new DataColumn("BooleanCol");
+      colBoolean.DataType = typeof(bool);
+      myTable.Columns.Add(colBoolean);
+
+      DataColumn colTimeSpan = new DataColumn("TimeSpanCol");
+      colTimeSpan.DataType = typeof(TimeSpan);
+      myTable.Columns.Add(colTimeSpan);
+
+      DataColumn colDateTime = new DataColumn("DateTimeCol");
+      colDateTime.DataType = typeof(DateTime);
+      colDateTime.DateTimeMode = DataSetDateTime.Utc;
+      myTable.Columns.Add(colDateTime);
+
+      DataColumn colDecimal = new DataColumn("DecimalCol");
+      colDecimal.DataType = typeof(decimal);
+      myTable.Columns.Add(colDecimal);
+
+      // populate one row with values.
+      DataRow myNewRow = myTable.NewRow();
+
+      myNewRow["StringCol"] = "Item Name";
+      myNewRow["Int32Col"] = 2147483647;
+      myNewRow["BooleanCol"] = true;
+      myNewRow["TimeSpanCol"] = new TimeSpan(10, 22, 10, 15, 100);
+      myNewRow["DateTimeCol"] = new DateTime(2000, 12, 29, 0, 0, 0, DateTimeKind.Utc);
+      myNewRow["DecimalCol"] = 64.0021;
+      myTable.Rows.Add(myNewRow);
+
+      string json = JsonConvert.SerializeObject(myTable, Formatting.Indented);
+      Assert.AreEqual(@"[
+  {
+    ""StringCol"": ""Item Name"",
+    ""Int32Col"": 2147483647,
+    ""BooleanCol"": true,
+    ""TimeSpanCol"": ""10.22:10:15.1000000"",
+    ""DateTimeCol"": ""\/Date(978048000000)\/"",
+    ""DecimalCol"": 64.0021
+  }
+]", json);
+    }
+
+    public class TestDataTableConverter : JsonConverter
+    {
+      public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+      {
+        DataTable d = (DataTable) value;
+        writer.WriteValue(d.TableName);
+      }
+
+      public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+      {
+        //reader.Read();
+        DataTable d = new DataTable((string)reader.Value);
+
+        return d;
+      }
+
+      public override bool CanConvert(Type objectType)
+      {
+        return (objectType == typeof (DataTable));
+      }
+    }
+
+    [Test]
+    public void PassedInJsonConverterOverridesInternalConverter()
+    {
+      DataTable t1 = new DataTable("Custom");
+
+      string json = JsonConvert.SerializeObject(t1, Formatting.Indented, new TestDataTableConverter());
+      Assert.AreEqual(@"""Custom""", json);
+
+      DataTable t2 = JsonConvert.DeserializeObject<DataTable>(json, new TestDataTableConverter());
+      Assert.AreEqual(t1.TableName, t2.TableName);
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/ExpandoObjectConverterTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/ExpandoObjectConverterTests.cs
new file mode 100644 (file)
index 0000000..bcb82a2
--- /dev/null
@@ -0,0 +1,158 @@
+#if !(NET35 || NET20 || WINDOWS_PHONE)
+
+using System;
+using System.Collections.Generic;
+#if !SILVERLIGHT && !PocketPC && !NET20
+using System.Data.Linq;
+#endif
+#if !SILVERLIGHT
+using System.Data.SqlTypes;
+#endif
+using System.Dynamic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Converters;
+using NUnit.Framework;
+using Newtonsoft.Json.Tests.TestObjects;
+
+namespace Newtonsoft.Json.Tests.Converters
+{
+  public class ExpandoObjectConverterTests : TestFixtureBase
+  {
+    public class ExpandoContainer
+    {
+      public string Before { get; set; }
+      public ExpandoObject Expando { get; set; }
+      public string After { get; set; }
+    }
+
+    [Test]
+    public void SerializeExpandoObject()
+    {
+      ExpandoContainer d = new ExpandoContainer
+        {
+          Before = "Before!",
+          Expando = new ExpandoObject(),
+          After = "After!"
+        };
+
+      dynamic o = d.Expando;
+
+      o.String = "String!";
+      o.Integer = 234;
+      o.Float = 1.23d;
+      o.List = new List<string> {"First", "Second", "Third"};
+      o.Object = new Dictionary<string, object>
+        {
+          {"First", 1}
+        };
+
+      string json = JsonConvert.SerializeObject(d, Formatting.Indented);
+
+      Assert.AreEqual(@"{
+  ""Before"": ""Before!"",
+  ""Expando"": {
+    ""String"": ""String!"",
+    ""Integer"": 234,
+    ""Float"": 1.23,
+    ""List"": [
+      ""First"",
+      ""Second"",
+      ""Third""
+    ],
+    ""Object"": {
+      ""First"": 1
+    }
+  },
+  ""After"": ""After!""
+}", json);
+    }
+
+    [Test]
+    public void SerializeNullExpandoObject()
+    {
+      ExpandoContainer d = new ExpandoContainer();
+
+      string json = JsonConvert.SerializeObject(d, Formatting.Indented);
+
+      Assert.AreEqual(@"{
+  ""Before"": null,
+  ""Expando"": null,
+  ""After"": null
+}", json);
+    }
+
+    [Test]
+    public void DeserializeExpandoObject()
+    {
+      string json = @"{
+  ""Before"": ""Before!"",
+  ""Expando"": {
+    ""String"": ""String!"",
+    ""Integer"": 234,
+    ""Float"": 1.23,
+    ""List"": [
+      ""First"",
+      ""Second"",
+      ""Third""
+    ],
+    ""Object"": {
+      ""First"": 1
+    }
+  },
+  ""After"": ""After!""
+}";
+
+      ExpandoContainer o = JsonConvert.DeserializeObject<ExpandoContainer>(json);
+
+      Assert.AreEqual(o.Before, "Before!");
+      Assert.AreEqual(o.After, "After!");
+      Assert.IsNotNull(o.Expando);
+
+      dynamic d = o.Expando;
+      Assert.IsInstanceOfType(typeof(ExpandoObject), d);
+
+      Assert.AreEqual("String!", d.String);
+      Assert.IsInstanceOfType(typeof(string), d.String);
+
+      Assert.AreEqual(234, d.Integer);
+      Assert.IsInstanceOfType(typeof(long), d.Integer);
+
+      Assert.AreEqual(1.23, d.Float);
+      Assert.IsInstanceOfType(typeof(double), d.Float);
+
+      Assert.IsNotNull(d.List);
+      Assert.AreEqual(3, d.List.Count);
+      Assert.IsInstanceOfType(typeof(List<object>), d.List);
+
+      Assert.AreEqual("First", d.List[0]);
+      Assert.IsInstanceOfType(typeof(string), d.List[0]);
+
+      Assert.AreEqual("Second", d.List[1]);
+      Assert.AreEqual("Third", d.List[2]);
+
+      Assert.IsNotNull(d.Object);
+      Assert.IsInstanceOfType(typeof(ExpandoObject), d.Object);
+
+      Assert.AreEqual(1, d.Object.First);
+      Assert.IsInstanceOfType(typeof(long), d.Object.First);
+    }
+
+    [Test]
+    public void DeserializeNullExpandoObject()
+    {
+      string json = @"{
+  ""Before"": null,
+  ""Expando"": null,
+  ""After"": null
+}";
+
+      ExpandoContainer c = JsonConvert.DeserializeObject<ExpandoContainer>(json);
+
+      Assert.AreEqual(null, c.Expando);
+    }
+
+  }
+}
+
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/IsoDateTimeConverterTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/IsoDateTimeConverterTests.cs
new file mode 100644 (file)
index 0000000..98e0e04
--- /dev/null
@@ -0,0 +1,312 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Tests.TestObjects;
+using NUnit.Framework;
+using Newtonsoft.Json.Converters;
+using Newtonsoft.Json.Utilities;
+using System.Globalization;
+using System.Xml;
+
+namespace Newtonsoft.Json.Tests.Converters
+{
+  public class IsoDateTimeConverterTests : TestFixtureBase
+  {
+    [Test]
+    public void PropertiesShouldBeSet()
+    {
+      IsoDateTimeConverter converter = new IsoDateTimeConverter();
+      Assert.AreEqual(CultureInfo.CurrentCulture, converter.Culture);
+      Assert.AreEqual(string.Empty, converter.DateTimeFormat);
+      Assert.AreEqual(DateTimeStyles.RoundtripKind, converter.DateTimeStyles);
+
+      converter = new IsoDateTimeConverter()
+      {
+        DateTimeFormat = "F",
+        Culture = CultureInfo.InvariantCulture,
+        DateTimeStyles = DateTimeStyles.None
+      };
+
+      Assert.AreEqual(CultureInfo.InvariantCulture, converter.Culture);
+      Assert.AreEqual("F", converter.DateTimeFormat);
+      Assert.AreEqual(DateTimeStyles.None, converter.DateTimeStyles);
+    }
+
+    [Test]
+    public void SerializeDateTime()
+    {
+      IsoDateTimeConverter converter = new IsoDateTimeConverter();
+
+      DateTime d = new DateTime(2000, 12, 15, 22, 11, 3, 55, DateTimeKind.Utc);
+      string result;
+
+      result = JsonConvert.SerializeObject(d, converter);
+      Assert.AreEqual(@"""2000-12-15T22:11:03.055Z""", result);
+
+      Assert.AreEqual(d, JsonConvert.DeserializeObject<DateTime>(result, converter));
+
+      d = new DateTime(2000, 12, 15, 22, 11, 3, 55, DateTimeKind.Local);
+      result = JsonConvert.SerializeObject(d, converter);
+      Assert.AreEqual(@"""2000-12-15T22:11:03.055" + d.GetLocalOffset() + @"""", result);
+    }
+
+    [Test]
+    public void SerializeFormattedDateTimeInvariantCulture()
+    {
+      IsoDateTimeConverter converter = new IsoDateTimeConverter() { DateTimeFormat = "F", Culture = CultureInfo.InvariantCulture };
+
+      DateTime d = new DateTime(2000, 12, 15, 22, 11, 3, 0, DateTimeKind.Utc);
+      string result;
+
+      result = JsonConvert.SerializeObject(d, converter);
+      Assert.AreEqual(@"""Friday, 15 December 2000 22:11:03""", result);
+
+      Assert.AreEqual(d, JsonConvert.DeserializeObject<DateTime>(result, converter));
+
+      d = new DateTime(2000, 12, 15, 22, 11, 3, 0, DateTimeKind.Local);
+      result = JsonConvert.SerializeObject(d, converter);
+      Assert.AreEqual(@"""Friday, 15 December 2000 22:11:03""", result);
+    }
+
+    [Test]
+    public void SerializeCustomFormattedDateTime()
+    {
+      IsoDateTimeConverter converter = new IsoDateTimeConverter
+                                         {
+                                           DateTimeFormat = "dd/MM/yyyy",
+                                           Culture = CultureInfo.InvariantCulture
+                                         };
+
+      string json = @"""09/12/2006""";
+
+      DateTime d = JsonConvert.DeserializeObject<DateTime>(json, converter);
+
+      Assert.AreEqual(9, d.Day);
+      Assert.AreEqual(12, d.Month);
+      Assert.AreEqual(2006, d.Year);
+    }
+
+#if !SILVERLIGHT
+    [Test]
+    public void SerializeFormattedDateTimeNewZealandCulture()
+    {
+      IsoDateTimeConverter converter = new IsoDateTimeConverter() { DateTimeFormat = "F", Culture = CultureInfo.GetCultureInfo("en-NZ") };
+
+      DateTime d = new DateTime(2000, 12, 15, 22, 11, 3, 0, DateTimeKind.Utc);
+      string result;
+
+      result = JsonConvert.SerializeObject(d, converter);
+      Assert.AreEqual(@"""Friday, 15 December 2000 10:11:03 p.m.""", result);
+
+      Assert.AreEqual(d, JsonConvert.DeserializeObject<DateTime>(result, converter));
+
+      d = new DateTime(2000, 12, 15, 22, 11, 3, 0, DateTimeKind.Local);
+      result = JsonConvert.SerializeObject(d, converter);
+      Assert.AreEqual(@"""Friday, 15 December 2000 10:11:03 p.m.""", result);
+    }
+
+    [Test]
+    public void SerializeDateTimeCulture()
+    {
+      IsoDateTimeConverter converter = new IsoDateTimeConverter() { Culture = CultureInfo.GetCultureInfo("en-NZ") };
+
+      string json = @"""09/12/2006""";
+
+      DateTime d = JsonConvert.DeserializeObject<DateTime>(json, converter);
+
+      Assert.AreEqual(9, d.Day);
+      Assert.AreEqual(12, d.Month);
+      Assert.AreEqual(2006, d.Year);
+    }
+#endif
+
+#if !PocketPC && !NET20
+    [Test]
+    public void SerializeDateTimeOffset()
+    {
+      IsoDateTimeConverter converter = new IsoDateTimeConverter();
+
+      DateTimeOffset d = new DateTimeOffset(2000, 12, 15, 22, 11, 3, 55, TimeSpan.Zero);
+      string result;
+
+      result = JsonConvert.SerializeObject(d, converter);
+      Assert.AreEqual(@"""2000-12-15T22:11:03.055+00:00""", result);
+
+      Assert.AreEqual(d, JsonConvert.DeserializeObject<DateTimeOffset>(result, converter));
+    }
+
+    [Test]
+    public void SerializeUTC()
+    {
+      DateTimeTestClass c = new DateTimeTestClass();
+      c.DateTimeField = new DateTime(2008, 12, 12, 12, 12, 12, 0, DateTimeKind.Utc).ToLocalTime();
+      c.DateTimeOffsetField = new DateTime(2008, 12, 12, 12, 12, 12, 0, DateTimeKind.Utc).ToLocalTime();
+      c.PreField = "Pre";
+      c.PostField = "Post";
+      string json = JsonConvert.SerializeObject(c, new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal });
+      Assert.AreEqual(@"{""PreField"":""Pre"",""DateTimeField"":""2008-12-12T12:12:12Z"",""DateTimeOffsetField"":""2008-12-12T12:12:12+00:00"",""PostField"":""Post""}", json);
+
+      //test the other edge case too
+      c.DateTimeField = new DateTime(2008, 1, 1, 1, 1, 1, 0, DateTimeKind.Utc).ToLocalTime();
+      c.DateTimeOffsetField = new DateTime(2008, 1, 1, 1, 1, 1, 0, DateTimeKind.Utc).ToLocalTime();
+      c.PreField = "Pre";
+      c.PostField = "Post";
+      json = JsonConvert.SerializeObject(c, new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal });
+      Assert.AreEqual(@"{""PreField"":""Pre"",""DateTimeField"":""2008-01-01T01:01:01Z"",""DateTimeOffsetField"":""2008-01-01T01:01:01+00:00"",""PostField"":""Post""}", json);
+    }
+
+    [Test]
+    public void NullableSerializeUTC()
+    {
+      NullableDateTimeTestClass c = new NullableDateTimeTestClass();
+      c.DateTimeField = new DateTime(2008, 12, 12, 12, 12, 12, 0, DateTimeKind.Utc).ToLocalTime();
+      c.DateTimeOffsetField = new DateTime(2008, 12, 12, 12, 12, 12, 0, DateTimeKind.Utc).ToLocalTime();
+      c.PreField = "Pre";
+      c.PostField = "Post";
+      string json = JsonConvert.SerializeObject(c, new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal });
+      Assert.AreEqual(@"{""PreField"":""Pre"",""DateTimeField"":""2008-12-12T12:12:12Z"",""DateTimeOffsetField"":""2008-12-12T12:12:12+00:00"",""PostField"":""Post""}", json);
+
+      //test the other edge case too
+      c.DateTimeField = null;
+      c.DateTimeOffsetField = null;
+      c.PreField = "Pre";
+      c.PostField = "Post";
+      json = JsonConvert.SerializeObject(c, new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal });
+      Assert.AreEqual(@"{""PreField"":""Pre"",""DateTimeField"":null,""DateTimeOffsetField"":null,""PostField"":""Post""}", json);
+    }
+
+    [Test]
+    public void DeserializeUTC()
+    {
+      DateTimeTestClass c =
+        JsonConvert.DeserializeObject<DateTimeTestClass>(@"{""PreField"":""Pre"",""DateTimeField"":""2008-12-12T12:12:12Z"",""DateTimeOffsetField"":""2008-12-12T12:12:12Z"",""PostField"":""Post""}", new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal });
+
+      Assert.AreEqual(new DateTime(2008, 12, 12, 12, 12, 12, 0, DateTimeKind.Utc).ToLocalTime(), c.DateTimeField);
+      Assert.AreEqual(new DateTimeOffset(2008, 12, 12, 12, 12, 12, 0, TimeSpan.Zero), c.DateTimeOffsetField);
+      Assert.AreEqual("Pre", c.PreField);
+      Assert.AreEqual("Post", c.PostField);
+
+      DateTimeTestClass c2 =
+       JsonConvert.DeserializeObject<DateTimeTestClass>(@"{""PreField"":""Pre"",""DateTimeField"":""2008-01-01T01:01:01Z"",""DateTimeOffsetField"":""2008-01-01T01:01:01Z"",""PostField"":""Post""}", new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal });
+
+      Assert.AreEqual(new DateTime(2008, 1, 1, 1, 1, 1, 0, DateTimeKind.Utc).ToLocalTime(), c2.DateTimeField);
+      Assert.AreEqual(new DateTimeOffset(2008, 1, 1, 1, 1, 1, 0, TimeSpan.Zero), c2.DateTimeOffsetField);
+      Assert.AreEqual("Pre", c2.PreField);
+      Assert.AreEqual("Post", c2.PostField);
+    }
+
+    [Test]
+    public void NullableDeserializeUTC()
+    {
+      NullableDateTimeTestClass c =
+        JsonConvert.DeserializeObject<NullableDateTimeTestClass>(@"{""PreField"":""Pre"",""DateTimeField"":""2008-12-12T12:12:12Z"",""DateTimeOffsetField"":""2008-12-12T12:12:12Z"",""PostField"":""Post""}", new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal });
+
+      Assert.AreEqual(new DateTime(2008, 12, 12, 12, 12, 12, 0, DateTimeKind.Utc).ToLocalTime(), c.DateTimeField);
+      Assert.AreEqual(new DateTimeOffset(2008, 12, 12, 12, 12, 12, 0, TimeSpan.Zero), c.DateTimeOffsetField);
+      Assert.AreEqual("Pre", c.PreField);
+      Assert.AreEqual("Post", c.PostField);
+
+      NullableDateTimeTestClass c2 =
+       JsonConvert.DeserializeObject<NullableDateTimeTestClass>(@"{""PreField"":""Pre"",""DateTimeField"":null,""DateTimeOffsetField"":null,""PostField"":""Post""}", new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal });
+
+      Assert.AreEqual(null, c2.DateTimeField);
+      Assert.AreEqual(null, c2.DateTimeOffsetField);
+      Assert.AreEqual("Pre", c2.PreField);
+      Assert.AreEqual("Post", c2.PostField);
+    }
+
+    [Test]
+    public void NullableDeserializeEmptyString()
+    {
+      string json = @"{""DateTimeField"":""""}";
+
+      NullableDateTimeTestClass c = JsonConvert.DeserializeObject<NullableDateTimeTestClass>(json,
+        new JsonSerializerSettings { Converters = new [] {new IsoDateTimeConverter()}});
+      Assert.AreEqual(null, c.DateTimeField);
+    }
+
+    [Test]
+    [ExpectedException(typeof(Exception), ExpectedMessage = "Cannot convert null value to System.DateTime.")]
+    public void DeserializeNullToNonNullable()
+    {
+      DateTimeTestClass c2 =
+       JsonConvert.DeserializeObject<DateTimeTestClass>(@"{""PreField"":""Pre"",""DateTimeField"":null,""DateTimeOffsetField"":null,""PostField"":""Post""}", new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal });
+    }
+
+    [Test]
+    public void SerializeShouldChangeNonUTCDates()
+    {
+      DateTime localDateTime = new DateTime(2008, 1, 1, 1, 1, 1, 0, DateTimeKind.Local);
+
+      DateTimeTestClass c = new DateTimeTestClass();
+      c.DateTimeField = localDateTime;
+      c.PreField = "Pre";
+      c.PostField = "Post";
+      string json = JsonConvert.SerializeObject(c, new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal }); //note that this fails without the Utc converter...
+      c.DateTimeField = new DateTime(2008, 1, 1, 1, 1, 1, 0, DateTimeKind.Utc);
+      string json2 = JsonConvert.SerializeObject(c, new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal });
+
+      TimeSpan offset;
+
+#if SILVERLIGHT
+      offset = TimeZoneInfo.Local.GetUtcOffset(localDateTime);
+#else
+      offset = TimeZone.CurrentTimeZone.GetUtcOffset(localDateTime);
+#endif
+
+      // if the current timezone is utc then local already equals utc
+      if (offset == TimeSpan.Zero)
+        Assert.AreEqual(json, json2);
+      else
+        Assert.AreNotEqual(json, json2);
+    }
+#endif
+
+    [Test]
+    public void BlogCodeSample()
+    {
+      Person p = new Person
+                   {
+                     Name = "Keith",
+                     BirthDate = new DateTime(1980, 3, 8),
+                     LastModified = new DateTime(2009, 4, 12, 20, 44, 55),
+                   };
+
+      string jsonText = JsonConvert.SerializeObject(p, new IsoDateTimeConverter());
+      // {
+      //   "Name": "Keith",
+      //   "BirthDate": "1980-03-08T00:00:00",
+      //   "LastModified": "2009-04-12T20:44:55"
+      // }
+
+      Console.WriteLine(jsonText);
+
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/JavaScriptDateTimeConverterTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/JavaScriptDateTimeConverterTests.cs
new file mode 100644 (file)
index 0000000..15094fb
--- /dev/null
@@ -0,0 +1,126 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Tests.TestObjects;
+using NUnit.Framework;
+using Newtonsoft.Json.Converters;
+
+namespace Newtonsoft.Json.Tests.Converters
+{
+  public class JavaScriptDateTimeConverterTests : TestFixtureBase
+  {
+    [Test]
+    public void SerializeDateTime()
+    {
+      JavaScriptDateTimeConverter converter = new JavaScriptDateTimeConverter();
+
+      DateTime d = new DateTime(2000, 12, 15, 22, 11, 3, 55, DateTimeKind.Utc);
+      string result;
+
+      result = JsonConvert.SerializeObject(d, converter);
+      Assert.AreEqual("new Date(976918263055)", result);
+    }
+
+#if !PocketPC && !NET20
+    [Test]
+    public void SerializeDateTimeOffset()
+    {
+      JavaScriptDateTimeConverter converter = new JavaScriptDateTimeConverter();
+
+      DateTimeOffset now = new DateTimeOffset(2000, 12, 15, 22, 11, 3, 55, TimeSpan.Zero);
+      string result;
+
+      result = JsonConvert.SerializeObject(now, converter);
+      Assert.AreEqual("new Date(976918263055)", result);
+    }
+
+    [Test]
+    public void sdfs()
+    {
+      int i = Convert.ToInt32("+1");
+      Console.WriteLine(i);
+    }
+
+    [Test]
+    public void SerializeNullableDateTimeClass()
+    {
+      NullableDateTimeTestClass t = new NullableDateTimeTestClass()
+      {
+        DateTimeField = null,
+        DateTimeOffsetField = null
+      };
+
+      JavaScriptDateTimeConverter converter = new JavaScriptDateTimeConverter();
+
+      string result;
+
+      result = JsonConvert.SerializeObject(t, converter);
+      Assert.AreEqual(@"{""PreField"":null,""DateTimeField"":null,""DateTimeOffsetField"":null,""PostField"":null}", result);
+
+      t = new NullableDateTimeTestClass()
+      {
+        DateTimeField = new DateTime(2000, 12, 15, 22, 11, 3, 55, DateTimeKind.Utc),
+        DateTimeOffsetField = new DateTimeOffset(2000, 12, 15, 22, 11, 3, 55, TimeSpan.Zero)
+      };
+
+      result = JsonConvert.SerializeObject(t, converter);
+      Assert.AreEqual(@"{""PreField"":null,""DateTimeField"":new Date(976918263055),""DateTimeOffsetField"":new Date(976918263055),""PostField"":null}", result);
+    }
+
+    [Test]
+    [ExpectedException(typeof(Exception), ExpectedMessage = "Cannot convert null value to System.DateTime.")]
+    public void DeserializeNullToNonNullable()
+    {
+      DateTimeTestClass c2 =
+       JsonConvert.DeserializeObject<DateTimeTestClass>(@"{""PreField"":""Pre"",""DateTimeField"":null,""DateTimeOffsetField"":null,""PostField"":""Post""}", new JavaScriptDateTimeConverter());
+    }
+
+    [Test]
+    public void DeserializeDateTimeOffset()
+    {
+      JavaScriptDateTimeConverter converter = new JavaScriptDateTimeConverter();
+      DateTimeOffset start = new DateTimeOffset(2000, 12, 15, 22, 11, 3, 55, TimeSpan.Zero);
+
+      string json = JsonConvert.SerializeObject(start, converter);
+
+      DateTimeOffset result = JsonConvert.DeserializeObject<DateTimeOffset>(json, converter);
+      Assert.AreEqual(new DateTimeOffset(2000, 12, 15, 22, 11, 3, 55, TimeSpan.Zero), result);
+    }
+#endif
+
+    [Test]
+    public void DeserializeDateTime()
+    {
+      JavaScriptDateTimeConverter converter = new JavaScriptDateTimeConverter();
+
+      DateTime result = JsonConvert.DeserializeObject<DateTime>("new Date(976918263055)", converter);
+      Assert.AreEqual(new DateTime(2000, 12, 15, 22, 11, 3, 55, DateTimeKind.Utc), result);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/ObjectIdConverterTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/ObjectIdConverterTests.cs
new file mode 100644 (file)
index 0000000..ae4602d
--- /dev/null
@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Bson;
+using Newtonsoft.Json.Tests.TestObjects;
+using Newtonsoft.Json.Utilities;
+using NUnit.Framework;
+
+namespace Newtonsoft.Json.Tests.Converters
+{
+  public class ObjectIdConverterTests : TestFixtureBase
+  {
+    public class ObjectIdTestClass
+    {
+      [JsonProperty("_id")]
+      public BsonObjectId Id { get; set; }
+      [JsonProperty("test")]
+      public string Test { get; set; }
+    }
+
+    [Test]
+    public void Serialize()
+    {
+      ObjectIdTestClass c = new ObjectIdTestClass
+                              {
+                                Id = new BsonObjectId(MiscellaneousUtils.HexToBytes("4ABBED9D1D8B0F0218000001")),
+                                Test = "1234£56"
+                              };
+
+      MemoryStream ms = new MemoryStream();
+      JsonSerializer serializer = new JsonSerializer();
+
+      // serialize product to BSON
+      BsonWriter writer = new BsonWriter(ms);
+      serializer.Serialize(writer, c);
+
+      byte[] expected = MiscellaneousUtils.HexToBytes("29000000075F6964004ABBED9D1D8B0F02180000010274657374000900000031323334C2A335360000");
+
+      Assert.AreEqual(expected, ms.ToArray());
+    }
+
+    [Test]
+    public void Deserialize()
+    {
+      byte[] bson = MiscellaneousUtils.HexToBytes("29000000075F6964004ABBED9D1D8B0F02180000010274657374000900000031323334C2A335360000");
+
+      JsonSerializer serializer = new JsonSerializer();
+
+      BsonReader reader = new BsonReader(new MemoryStream(bson));
+      ObjectIdTestClass c = serializer.Deserialize<ObjectIdTestClass>(reader);
+
+      Assert.AreEqual(c.Id.Value, MiscellaneousUtils.HexToBytes("4ABBED9D1D8B0F0218000001"));
+      Assert.AreEqual(c.Test, "1234£56");
+    }
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/RegexConverterTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/RegexConverterTests.cs
new file mode 100644 (file)
index 0000000..d7d9314
--- /dev/null
@@ -0,0 +1,156 @@
+using System;
+using System.Collections.Generic;
+#if !SILVERLIGHT && !PocketPC && !NET20
+using System.Data.Linq;
+#endif
+#if !SILVERLIGHT
+using System.Data.SqlTypes;
+#endif
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using Newtonsoft.Json.Bson;
+using Newtonsoft.Json.Converters;
+using Newtonsoft.Json.Utilities;
+using NUnit.Framework;
+using Newtonsoft.Json.Tests.TestObjects;
+
+namespace Newtonsoft.Json.Tests.Converters
+{
+  public class RegexConverterTests : TestFixtureBase
+  {
+    public class RegexTestClass
+    {
+      public Regex Regex { get; set; }
+    }
+
+    [Test]
+    public void SerializeToText()
+    {
+      Regex regex = new Regex("abc", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
+
+      string json = JsonConvert.SerializeObject(regex, Formatting.Indented, new RegexConverter());
+
+      Assert.AreEqual(@"{
+  ""Pattern"": ""abc"",
+  ""Options"": 513
+}", json);
+    }
+
+    [Test]
+    public void SerializeToBson()
+    {
+      Regex regex = new Regex("abc", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
+
+      MemoryStream ms = new MemoryStream();
+      BsonWriter writer = new BsonWriter(ms);
+      JsonSerializer serializer = new JsonSerializer();
+      serializer.Converters.Add(new RegexConverter());
+
+      serializer.Serialize(writer, new RegexTestClass { Regex = regex });
+
+      string expected = "13-00-00-00-0B-52-65-67-65-78-00-61-62-63-00-69-75-00-00";
+      string bson = MiscellaneousUtils.BytesToHex(ms.ToArray());
+
+      Assert.AreEqual(expected, bson);
+    }
+
+    [Test]
+    public void DeserializeFromText()
+    {
+      string json = @"{
+  ""Pattern"": ""abc"",
+  ""Options"": 513
+}";
+
+      Regex newRegex = JsonConvert.DeserializeObject<Regex>(json, new RegexConverter());
+      Assert.AreEqual("abc", newRegex.ToString());
+      Assert.AreEqual(RegexOptions.IgnoreCase | RegexOptions.CultureInvariant, newRegex.Options);
+    }
+
+    [Test]
+    public void DeserializeFromBson()
+    {
+      MemoryStream ms = new MemoryStream(MiscellaneousUtils.HexToBytes("13-00-00-00-0B-52-65-67-65-78-00-61-62-63-00-69-75-00-00"));
+      BsonReader reader = new BsonReader(ms);
+      JsonSerializer serializer = new JsonSerializer();
+      serializer.Converters.Add(new RegexConverter());
+
+      RegexTestClass c = serializer.Deserialize<RegexTestClass>(reader);
+
+      Assert.AreEqual("abc", c.Regex.ToString());
+      Assert.AreEqual(RegexOptions.IgnoreCase, c.Regex.Options);
+    }
+
+    [Test]
+    public void ConvertEmptyRegexBson()
+    {
+      Regex regex = new Regex(string.Empty);
+
+      MemoryStream ms = new MemoryStream();
+      BsonWriter writer = new BsonWriter(ms);
+      JsonSerializer serializer = new JsonSerializer();
+      serializer.Converters.Add(new RegexConverter());
+
+      serializer.Serialize(writer, new RegexTestClass { Regex = regex });
+
+      ms.Seek(0, SeekOrigin.Begin);
+      BsonReader reader = new BsonReader(ms);
+      serializer.Converters.Add(new RegexConverter());
+
+      RegexTestClass c = serializer.Deserialize<RegexTestClass>(reader);
+
+      Assert.AreEqual("", c.Regex.ToString());
+      Assert.AreEqual(RegexOptions.None, c.Regex.Options);
+    }
+
+    [Test]
+    public void ConvertRegexWithAllOptionsBson()
+    {
+      Regex regex = new Regex(
+        "/",
+        RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Multiline | RegexOptions.ExplicitCapture);
+
+      MemoryStream ms = new MemoryStream();
+      BsonWriter writer = new BsonWriter(ms);
+      JsonSerializer serializer = new JsonSerializer();
+      serializer.Converters.Add(new RegexConverter());
+
+      serializer.Serialize(writer, new RegexTestClass { Regex = regex });
+
+      string expected = "14-00-00-00-0B-52-65-67-65-78-00-2F-00-69-6D-73-75-78-00-00";
+      string bson = MiscellaneousUtils.BytesToHex(ms.ToArray());
+
+      Assert.AreEqual(expected, bson);
+
+      ms.Seek(0, SeekOrigin.Begin);
+      BsonReader reader = new BsonReader(ms);
+      serializer.Converters.Add(new RegexConverter());
+
+      RegexTestClass c = serializer.Deserialize<RegexTestClass>(reader);
+
+      Assert.AreEqual("/", c.Regex.ToString());
+      Assert.AreEqual(RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Multiline | RegexOptions.ExplicitCapture, c.Regex.Options);
+    }
+
+    [Test]
+    public void ConvertEmptyRegexJson()
+    {
+      Regex regex = new Regex("");
+
+      string json = JsonConvert.SerializeObject(new RegexTestClass { Regex = regex }, Formatting.Indented, new RegexConverter());
+
+      Assert.AreEqual(@"{
+  ""Regex"": {
+    ""Pattern"": """",
+    ""Options"": 0
+  }
+}", json);
+
+      RegexTestClass newRegex = JsonConvert.DeserializeObject<RegexTestClass>(json, new RegexConverter());
+      Assert.AreEqual("", newRegex.Regex.ToString());
+      Assert.AreEqual(RegexOptions.None, newRegex.Regex.Options);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/StringEnumConverterTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/StringEnumConverterTests.cs
new file mode 100644 (file)
index 0000000..1a52421
--- /dev/null
@@ -0,0 +1,260 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.Serialization;
+using System.Text;
+using Newtonsoft.Json.Converters;
+using NUnit.Framework;
+using Newtonsoft.Json.Tests.TestObjects;
+
+namespace Newtonsoft.Json.Tests.Converters
+{
+  public class StringEnumConverterTests : TestFixtureBase
+  {
+    public class EnumClass
+    {
+      public StoreColor StoreColor { get; set; }
+      public StoreColor? NullableStoreColor1 { get; set; }
+      public StoreColor? NullableStoreColor2 { get; set; }
+    }
+
+    public class EnumContainer<T>
+    {
+      public T Enum { get; set; }
+    }
+
+    public enum NegativeEnum
+    {
+      Negative = -1,
+      Zero = 0,
+      Positive = 1
+    }
+
+#if !NET20
+    public enum NamedEnum
+    {
+      [EnumMember(Value = "@first")]
+      First,
+      [EnumMember(Value = "@second")]
+      Second,
+      Third
+    }
+
+    public enum NamedEnumDuplicate
+    {
+      [EnumMember(Value = "Third")]
+      First,
+      [EnumMember(Value = "@second")]
+      Second,
+      Third
+    }
+#endif
+
+    public class NegativeEnumClass
+    {
+      public NegativeEnum Value1 { get; set; }
+      public NegativeEnum Value2 { get; set; }
+    }
+
+#if !NET20
+    [Test]
+    [ExpectedException(typeof(Exception), ExpectedMessage = "Enum name 'Third' already exists on enum 'NamedEnumDuplicate'.")]
+    public void NamedEnumDuplicateTest()
+    {
+      EnumContainer<NamedEnumDuplicate> c = new EnumContainer<NamedEnumDuplicate>
+      {
+        Enum = NamedEnumDuplicate.First
+      };
+
+      JsonConvert.SerializeObject(c, Formatting.Indented, new StringEnumConverter());
+    }
+
+    [Test]
+    public void SerializeNameEnumTest()
+    {
+      EnumContainer<NamedEnum> c = new EnumContainer<NamedEnum>
+        {
+          Enum = NamedEnum.First
+        };
+
+      string json = JsonConvert.SerializeObject(c, Formatting.Indented, new StringEnumConverter());
+      Assert.AreEqual(@"{
+  ""Enum"": ""@first""
+}", json);
+
+      c = new EnumContainer<NamedEnum>
+      {
+        Enum = NamedEnum.Third
+      };
+
+      json = JsonConvert.SerializeObject(c, Formatting.Indented, new StringEnumConverter());
+      Assert.AreEqual(@"{
+  ""Enum"": ""Third""
+}", json);
+    }
+
+    [Test]
+    public void DeserializeNameEnumTest()
+    {
+      string json = @"{
+  ""Enum"": ""@first""
+}";
+
+      EnumContainer<NamedEnum> c = JsonConvert.DeserializeObject<EnumContainer<NamedEnum>>(json, new StringEnumConverter());
+      Assert.AreEqual(NamedEnum.First, c.Enum);
+
+      json = @"{
+  ""Enum"": ""Third""
+}";
+
+      c = JsonConvert.DeserializeObject<EnumContainer<NamedEnum>>(json, new StringEnumConverter());
+      Assert.AreEqual(NamedEnum.Third, c.Enum);
+    }
+#endif
+
+    [Test]
+    public void SerializeEnumClass()
+    {
+      EnumClass enumClass = new EnumClass();
+      enumClass.StoreColor = StoreColor.Red;
+      enumClass.NullableStoreColor1 = StoreColor.White;
+      enumClass.NullableStoreColor2 = null;
+
+      string json = JsonConvert.SerializeObject(enumClass, Formatting.Indented, new StringEnumConverter());
+
+      Assert.AreEqual(@"{
+  ""StoreColor"": ""Red"",
+  ""NullableStoreColor1"": ""White"",
+  ""NullableStoreColor2"": null
+}", json);
+    }
+
+    [Test]
+    public void SerializeEnumClassWithCamelCase()
+    {
+      EnumClass enumClass = new EnumClass();
+      enumClass.StoreColor = StoreColor.Red;
+      enumClass.NullableStoreColor1 = StoreColor.DarkGoldenrod;
+      enumClass.NullableStoreColor2 = null;
+
+      string json = JsonConvert.SerializeObject(enumClass, Formatting.Indented, new StringEnumConverter { CamelCaseText = true });
+
+      Assert.AreEqual(@"{
+  ""StoreColor"": ""red"",
+  ""NullableStoreColor1"": ""darkGoldenrod"",
+  ""NullableStoreColor2"": null
+}", json);
+    }
+
+    [Test]
+    public void SerializeEnumClassUndefined()
+    {
+      EnumClass enumClass = new EnumClass();
+      enumClass.StoreColor = (StoreColor)1000;
+      enumClass.NullableStoreColor1 = (StoreColor)1000;
+      enumClass.NullableStoreColor2 = null;
+
+      string json = JsonConvert.SerializeObject(enumClass, Formatting.Indented, new StringEnumConverter());
+
+      Assert.AreEqual(@"{
+  ""StoreColor"": 1000,
+  ""NullableStoreColor1"": 1000,
+  ""NullableStoreColor2"": null
+}", json);
+    }
+
+    [Test]
+    public void SerializeFlagEnum()
+    {
+      EnumClass enumClass = new EnumClass();
+      enumClass.StoreColor = StoreColor.Red | StoreColor.White;
+      enumClass.NullableStoreColor1 = StoreColor.White & StoreColor.Yellow;
+      enumClass.NullableStoreColor2 = StoreColor.Red | StoreColor.White | StoreColor.Black;
+
+      string json = JsonConvert.SerializeObject(enumClass, Formatting.Indented, new StringEnumConverter());
+
+      Assert.AreEqual(@"{
+  ""StoreColor"": ""Red, White"",
+  ""NullableStoreColor1"": 0,
+  ""NullableStoreColor2"": ""Black, Red, White""
+}", json);
+    }
+
+    [Test]
+    public void SerializeNegativeEnum()
+    {
+      NegativeEnumClass negativeEnumClass = new NegativeEnumClass();
+      negativeEnumClass.Value1 = NegativeEnum.Negative;
+      negativeEnumClass.Value2 = (NegativeEnum) int.MinValue;
+
+      string json = JsonConvert.SerializeObject(negativeEnumClass, Formatting.Indented, new StringEnumConverter());
+
+      Assert.AreEqual(@"{
+  ""Value1"": ""Negative"",
+  ""Value2"": -2147483648
+}", json);
+    }
+
+    [Test]
+    public void DeserializeNegativeEnum()
+    {
+      string json = @"{
+  ""Value1"": ""Negative"",
+  ""Value2"": -2147483648
+}";
+
+      NegativeEnumClass negativeEnumClass = JsonConvert.DeserializeObject<NegativeEnumClass>(json, new StringEnumConverter());
+
+      Assert.AreEqual(NegativeEnum.Negative, negativeEnumClass.Value1);
+      Assert.AreEqual((NegativeEnum)int.MinValue, negativeEnumClass.Value2);
+    }
+
+    [Test]
+    public void DeserializeFlagEnum()
+    {
+      string json = @"{
+  ""StoreColor"": ""Red, White"",
+  ""NullableStoreColor1"": 0,
+  ""NullableStoreColor2"": ""black, Red, White""
+}";
+
+      EnumClass enumClass = JsonConvert.DeserializeObject<EnumClass>(json, new StringEnumConverter());
+
+      Assert.AreEqual(StoreColor.Red | StoreColor.White, enumClass.StoreColor);
+      Assert.AreEqual((StoreColor)0, enumClass.NullableStoreColor1);
+      Assert.AreEqual(StoreColor.Red | StoreColor.White | StoreColor.Black, enumClass.NullableStoreColor2);
+    }
+
+    [Test]
+    public void DeserializeEnumClass()
+    {
+      string json = @"{
+  ""StoreColor"": ""Red"",
+  ""NullableStoreColor1"": ""White"",
+  ""NullableStoreColor2"": null
+}";
+
+      EnumClass enumClass = JsonConvert.DeserializeObject<EnumClass>(json, new StringEnumConverter());
+
+      Assert.AreEqual(StoreColor.Red, enumClass.StoreColor);
+      Assert.AreEqual(StoreColor.White, enumClass.NullableStoreColor1);
+      Assert.AreEqual(null, enumClass.NullableStoreColor2);
+    }
+
+    [Test]
+    public void DeserializeEnumClassUndefined()
+    {
+      string json = @"{
+  ""StoreColor"": 1000,
+  ""NullableStoreColor1"": 1000,
+  ""NullableStoreColor2"": null
+}";
+
+      EnumClass enumClass = JsonConvert.DeserializeObject<EnumClass>(json, new StringEnumConverter());
+
+      Assert.AreEqual((StoreColor)1000, enumClass.StoreColor);
+      Assert.AreEqual((StoreColor)1000, enumClass.NullableStoreColor1);
+      Assert.AreEqual(null, enumClass.NullableStoreColor2);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs
new file mode 100644 (file)
index 0000000..509a4e3
--- /dev/null
@@ -0,0 +1,1224 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+#if !SILVERLIGHT
+using System;
+using System.Collections.Generic;
+using Newtonsoft.Json.Tests.Serialization;
+using Newtonsoft.Json.Tests.TestObjects;
+using NUnit.Framework;
+using Newtonsoft.Json;
+using System.IO;
+using System.Xml;
+using Newtonsoft.Json.Converters;
+using Newtonsoft.Json.Utilities;
+using Newtonsoft.Json.Linq;
+#if !NET20
+using System.Xml.Linq;
+#endif
+
+namespace Newtonsoft.Json.Tests.Converters
+{
+  public class XmlNodeConverterTest : TestFixtureBase
+  {
+    private string SerializeXmlNode(XmlNode node)
+    {
+      string json = JsonConvert.SerializeXmlNode(node, Formatting.Indented);
+      XmlNodeReader reader = new XmlNodeReader(node);
+
+#if !NET20
+      XObject xNode;
+      if (node is XmlDocument)
+      {
+        xNode = XDocument.Load(reader);
+      }
+      else if (node is XmlAttribute)
+      {
+        XmlAttribute attribute = (XmlAttribute) node;
+        xNode = new XAttribute(XName.Get(attribute.LocalName, attribute.NamespaceURI), attribute.Value);
+      }
+      else
+      {
+        reader.MoveToContent();
+        xNode = XNode.ReadFrom(reader);
+      }
+
+      string linqJson = JsonConvert.SerializeXNode(xNode, Formatting.Indented);
+
+      Assert.AreEqual(json, linqJson);
+#endif
+
+      return json;
+    }
+
+    private XmlNode DeserializeXmlNode(string json)
+    {
+      return DeserializeXmlNode(json, null);
+    }
+
+    private XmlNode DeserializeXmlNode(string json, string deserializeRootElementName)
+    {
+      JsonTextReader reader;
+
+      reader = new JsonTextReader(new StringReader(json));
+      reader.Read();
+      XmlNodeConverter converter = new XmlNodeConverter();
+      if (deserializeRootElementName != null)
+        converter.DeserializeRootElementName = deserializeRootElementName;
+
+      XmlNode node = (XmlNode)converter.ReadJson(reader, typeof (XmlDocument), null, new JsonSerializer());
+
+#if !NET20
+     string xmlText = node.OuterXml;
+
+      reader = new JsonTextReader(new StringReader(json));
+      reader.Read();
+      XDocument d = (XDocument) converter.ReadJson(reader, typeof (XDocument), null, new JsonSerializer());
+
+      string linqXmlText = d.ToString(SaveOptions.DisableFormatting);
+      if (d.Declaration != null)
+        linqXmlText = d.Declaration + linqXmlText;
+
+      Assert.AreEqual(xmlText, linqXmlText);
+#endif
+
+      return node;
+    }
+
+    [Test]
+    public void DocumentSerializeIndented()
+    {
+      string xml = @"<?xml version=""1.0"" standalone=""no""?>
+<?xml-stylesheet href=""classic.xsl"" type=""text/xml""?>
+<span class=""vevent"">
+  <a class=""url"" href=""http://www.web2con.com/"">
+    <span class=""summary"">Web 2.0 Conference<![CDATA[my escaped text]]></span>
+    <abbr class=""dtstart"" title=""2005-10-05"">October 5</abbr>
+    <abbr class=""dtend"" title=""2005-10-08"">7</abbr>
+    <span class=""location"">Argent Hotel, San Francisco, CA</span>
+  </a>
+</span>";
+      XmlDocument doc = new XmlDocument();
+      doc.LoadXml(xml);
+
+      string jsonText = SerializeXmlNode(doc);
+      string expected = @"{
+  ""?xml"": {
+    ""@version"": ""1.0"",
+    ""@standalone"": ""no""
+  },
+  ""?xml-stylesheet"": ""href=\""classic.xsl\"" type=\""text/xml\"""",
+  ""span"": {
+    ""@class"": ""vevent"",
+    ""a"": {
+      ""@class"": ""url"",
+      ""@href"": ""http://www.web2con.com/"",
+      ""span"": [
+        {
+          ""@class"": ""summary"",
+          ""#text"": ""Web 2.0 Conference"",
+          ""#cdata-section"": ""my escaped text""
+        },
+        {
+          ""@class"": ""location"",
+          ""#text"": ""Argent Hotel, San Francisco, CA""
+        }
+      ],
+      ""abbr"": [
+        {
+          ""@class"": ""dtstart"",
+          ""@title"": ""2005-10-05"",
+          ""#text"": ""October 5""
+        },
+        {
+          ""@class"": ""dtend"",
+          ""@title"": ""2005-10-08"",
+          ""#text"": ""7""
+        }
+      ]
+    }
+  }
+}";
+
+      Assert.AreEqual(expected, jsonText);
+
+      Console.WriteLine("DocumentSerializeIndented");
+      Console.WriteLine(jsonText);
+      Console.WriteLine();
+    }
+
+    [Test]
+    public void SerializeNodeTypes()
+    {
+      XmlDocument doc = new XmlDocument();
+      string jsonText;
+
+      Console.WriteLine("SerializeNodeTypes");
+
+      string xml = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
+<xs:schema xs:id=""SomeID"" 
+       xmlns="""" 
+       xmlns:xs=""http://www.w3.org/2001/XMLSchema"" 
+       xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
+       <xs:element name=""MyDataSet"" msdata:IsDataSet=""true"">
+       </xs:element>
+</xs:schema>";
+
+      XmlDocument document = new XmlDocument();
+      document.LoadXml(xml);
+
+      // XmlAttribute
+      XmlAttribute attribute = document.DocumentElement.ChildNodes[0].Attributes["IsDataSet", "urn:schemas-microsoft-com:xml-msdata"];
+      attribute.Value = "true";
+
+      jsonText = JsonConvert.SerializeXmlNode(attribute);
+
+      Console.WriteLine(jsonText);
+      Assert.AreEqual(@"{""@msdata:IsDataSet"":""true""}", jsonText);
+
+#if !NET20
+      XDocument d = XDocument.Parse(xml);
+      XAttribute a = d.Root.Element("{http://www.w3.org/2001/XMLSchema}element").Attribute("{urn:schemas-microsoft-com:xml-msdata}IsDataSet");
+
+      jsonText = JsonConvert.SerializeXNode(a);
+
+      Assert.AreEqual(@"{""@msdata:IsDataSet"":""true""}", jsonText);
+#endif
+
+      // XmlProcessingInstruction
+      XmlProcessingInstruction instruction = doc.CreateProcessingInstruction("xml-stylesheet", @"href=""classic.xsl"" type=""text/xml""");
+
+      jsonText = JsonConvert.SerializeXmlNode(instruction);
+
+      Console.WriteLine(jsonText);
+      Assert.AreEqual(@"{""?xml-stylesheet"":""href=\""classic.xsl\"" type=\""text/xml\""""}", jsonText);
+
+
+      // XmlProcessingInstruction
+      XmlCDataSection cDataSection = doc.CreateCDataSection("<Kiwi>true</Kiwi>");
+
+      jsonText = JsonConvert.SerializeXmlNode(cDataSection);
+
+      Console.WriteLine(jsonText);
+      Assert.AreEqual(@"{""#cdata-section"":""<Kiwi>true</Kiwi>""}", jsonText);
+
+
+      // XmlElement
+      XmlElement element = doc.CreateElement("xs", "Choice", "http://www.w3.org/2001/XMLSchema");
+      element.SetAttributeNode(doc.CreateAttribute("msdata", "IsDataSet", "urn:schemas-microsoft-com:xml-msdata"));
+
+      XmlAttribute aa = doc.CreateAttribute(@"xmlns", "xs", "http://www.w3.org/2000/xmlns/");
+      aa.Value = "http://www.w3.org/2001/XMLSchema";
+      element.SetAttributeNode(aa);
+
+      aa = doc.CreateAttribute(@"xmlns", "msdata", "http://www.w3.org/2000/xmlns/");
+      aa.Value = "urn:schemas-microsoft-com:xml-msdata";
+      element.SetAttributeNode(aa);
+
+      element.AppendChild(instruction);
+      element.AppendChild(cDataSection);
+
+      doc.AppendChild(element);
+
+      jsonText = JsonConvert.SerializeXmlNode(element, Formatting.Indented);
+
+      Assert.AreEqual(@"{
+  ""xs:Choice"": {
+    ""@msdata:IsDataSet"": """",
+    ""@xmlns:xs"": ""http://www.w3.org/2001/XMLSchema"",
+    ""@xmlns:msdata"": ""urn:schemas-microsoft-com:xml-msdata"",
+    ""?xml-stylesheet"": ""href=\""classic.xsl\"" type=\""text/xml\"""",
+    ""#cdata-section"": ""<Kiwi>true</Kiwi>""
+  }
+}", jsonText);
+    }
+
+    [Test]
+    public void DocumentFragmentSerialize()
+    {
+      XmlDocument doc = new XmlDocument();
+
+      XmlDocumentFragment fragement = doc.CreateDocumentFragment();
+
+      fragement.InnerXml = "<Item>widget</Item><Item>widget</Item>";
+
+      string jsonText = JsonConvert.SerializeXmlNode(fragement);
+
+      string expected = @"{""Item"":[""widget"",""widget""]}";
+
+      Assert.AreEqual(expected, jsonText);
+
+      Console.WriteLine("DocumentFragmentSerialize");
+      Console.WriteLine(jsonText);
+      Console.WriteLine();
+    }
+
+    [Test]
+    public void NamespaceSerializeDeserialize()
+    {
+      string xml = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
+<xs:schema xs:id=""SomeID"" 
+       xmlns="""" 
+       xmlns:xs=""http://www.w3.org/2001/XMLSchema"" 
+       xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
+       <xs:element name=""MyDataSet"" msdata:IsDataSet=""true"">
+               <xs:complexType>
+                       <xs:choice maxOccurs=""unbounded"">
+                               <xs:element name=""customers"" >
+                                       <xs:complexType >
+                                               <xs:sequence>
+                                                       <xs:element name=""CustomerID"" type=""xs:integer"" 
+                                                                                minOccurs=""0"" />
+                                                       <xs:element name=""CompanyName"" type=""xs:string"" 
+                                                                                minOccurs=""0"" />
+                                                       <xs:element name=""Phone"" type=""xs:string"" />
+                                               </xs:sequence>
+                                       </xs:complexType>
+                               </xs:element>
+                       </xs:choice>
+               </xs:complexType>
+       </xs:element>
+</xs:schema>";
+
+      XmlDocument doc = new XmlDocument();
+      doc.LoadXml(xml);
+
+      string jsonText = SerializeXmlNode(doc);
+
+      string expected = @"{
+  ""?xml"": {
+    ""@version"": ""1.0"",
+    ""@encoding"": ""utf-8""
+  },
+  ""xs:schema"": {
+    ""@xs:id"": ""SomeID"",
+    ""@xmlns"": """",
+    ""@xmlns:xs"": ""http://www.w3.org/2001/XMLSchema"",
+    ""@xmlns:msdata"": ""urn:schemas-microsoft-com:xml-msdata"",
+    ""xs:element"": {
+      ""@name"": ""MyDataSet"",
+      ""@msdata:IsDataSet"": ""true"",
+      ""xs:complexType"": {
+        ""xs:choice"": {
+          ""@maxOccurs"": ""unbounded"",
+          ""xs:element"": {
+            ""@name"": ""customers"",
+            ""xs:complexType"": {
+              ""xs:sequence"": {
+                ""xs:element"": [
+                  {
+                    ""@name"": ""CustomerID"",
+                    ""@type"": ""xs:integer"",
+                    ""@minOccurs"": ""0""
+                  },
+                  {
+                    ""@name"": ""CompanyName"",
+                    ""@type"": ""xs:string"",
+                    ""@minOccurs"": ""0""
+                  },
+                  {
+                    ""@name"": ""Phone"",
+                    ""@type"": ""xs:string""
+                  }
+                ]
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}";
+
+      Assert.AreEqual(expected, jsonText);
+
+      XmlDocument deserializedDoc = (XmlDocument)DeserializeXmlNode(jsonText);
+
+      Assert.AreEqual(doc.InnerXml, deserializedDoc.InnerXml);
+
+      Console.WriteLine("NamespaceSerializeDeserialize");
+      Console.WriteLine(jsonText);
+      Console.WriteLine(deserializedDoc.InnerXml);
+      Console.WriteLine();
+    }
+
+    [Test]
+    public void DocumentDeserialize()
+    {
+      string jsonText = @"{
+  ""?xml"": {
+    ""@version"": ""1.0"",
+    ""@standalone"": ""no""
+  },
+  ""span"": {
+    ""@class"": ""vevent"",
+    ""a"": {
+      ""@class"": ""url"",
+      ""@href"": ""http://www.web2con.com/"",
+      ""span"": {
+        ""@class"": ""summary"",
+        ""#text"": ""Web 2.0 Conference"",
+        ""#cdata-section"": ""my escaped text""
+      }
+    }
+  }
+}";
+
+      XmlDocument doc = (XmlDocument)DeserializeXmlNode(jsonText);
+
+      string expected = @"<?xml version=""1.0"" standalone=""no""?>
+<span class=""vevent"">
+  <a class=""url"" href=""http://www.web2con.com/"">
+    <span class=""summary"">Web 2.0 Conference<![CDATA[my escaped text]]></span>
+  </a>
+</span>";
+
+      string formattedXml = GetIndentedInnerXml(doc);
+
+      Console.WriteLine("DocumentDeserialize");
+      Console.WriteLine(formattedXml);
+      Console.WriteLine();
+
+      Assert.AreEqual(expected, formattedXml);
+    }
+
+    private string GetIndentedInnerXml(XmlNode node)
+    {
+      XmlWriterSettings settings = new XmlWriterSettings();
+      settings.Indent = true;
+
+      StringWriter sw = new StringWriter();
+
+      using (XmlWriter writer = XmlWriter.Create(sw, settings))
+      {
+        node.WriteTo(writer);
+      }
+
+      return sw.ToString();
+    }
+
+    [Test]
+    public void SingleTextNode()
+    {
+      string xml = @"<?xml version=""1.0"" standalone=""no""?>
+                       <root>
+                         <person id=""1"">
+                               <name>Alan</name>
+                               <url>http://www.google.com</url>
+                         </person>
+                         <person id=""2"">
+                               <name>Louis</name>
+                                 <url>http://www.yahoo.com</url>
+                         </person>
+                       </root>";
+
+      XmlDocument doc = new XmlDocument();
+      doc.LoadXml(xml);
+
+      string jsonText = SerializeXmlNode(doc);
+
+      XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText);
+
+      Assert.AreEqual(doc.InnerXml, newDoc.InnerXml);
+    }
+
+    [Test]
+    public void EmptyNode()
+    {
+      string xml = @"<?xml version=""1.0"" standalone=""no""?>
+                       <root>
+                         <person id=""1"">
+                               <name>Alan</name>
+                               <url />
+                         </person>
+                         <person id=""2"">
+                               <name>Louis</name>
+                               <url>http://www.yahoo.com</url>
+                         </person>
+                       </root>";
+
+      XmlDocument doc = new XmlDocument();
+      doc.LoadXml(xml);
+
+      string jsonText = SerializeXmlNode(doc);
+
+      Console.WriteLine(jsonText);
+
+      XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText);
+
+      Assert.AreEqual(doc.InnerXml, newDoc.InnerXml);
+    }
+
+    [Test]
+    public void OtherElementDataTypes()
+    {
+      string jsonText = @"{""?xml"":{""@version"":""1.0"",""@standalone"":""no""},""root"":{""person"":[{""@id"":""1"",""Float"":2.5,""Integer"":99},{""@id"":""2"",""Boolean"":true,""date"":""\/Date(954374400000)\/""}]}}";
+
+      XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText);
+
+      string expected = @"<?xml version=""1.0"" standalone=""no""?><root><person id=""1""><Float>2.5</Float><Integer>99</Integer></person><person id=""2""><Boolean>true</Boolean><date>2000-03-30T00:00:00Z</date></person></root>";
+
+      Assert.AreEqual(expected, newDoc.InnerXml);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "XmlNodeConverter can only convert JSON that begins with an object.")]
+    public void NoRootObject()
+    {
+      XmlDocument newDoc = (XmlDocument)JsonConvert.DeserializeXmlNode(@"[1]");
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "JSON root object has multiple properties. The root object must have a single property in order to create a valid XML document. Consider specifing a DeserializeRootElementName.")]
+    public void RootObjectMultipleProperties()
+    {
+      XmlDocument newDoc = (XmlDocument)JsonConvert.DeserializeXmlNode(@"{Prop1:1,Prop2:2}");
+    }
+
+    [Test]
+    public void JavaScriptConstructor()
+    {
+      string jsonText = @"{root:{r:new Date(34343, 55)}}";
+
+      XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText);
+
+      string expected = @"<root><r><Date>34343</Date><Date>55</Date></r></root>";
+
+      Assert.AreEqual(expected, newDoc.InnerXml);
+
+      string json = SerializeXmlNode(newDoc);
+      expected = @"{
+  ""root"": {
+    ""r"": {
+      ""Date"": [
+        ""34343"",
+        ""55""
+      ]
+    }
+  }
+}";
+
+      Assert.AreEqual(expected, json);
+    }
+
+    [Test]
+    public void ForceJsonArray()
+    {
+      string arrayXml = @"<root xmlns:json=""http://james.newtonking.com/projects/json"">
+                         <person id=""1"">
+                                 <name>Alan</name>
+                                 <url>http://www.google.com</url>
+                                 <role json:Array=""true"">Admin</role>
+                         </person>
+                       </root>";
+
+      XmlDocument arrayDoc = new XmlDocument();
+      arrayDoc.LoadXml(arrayXml);
+
+      string arrayJsonText = SerializeXmlNode(arrayDoc);
+      string expected = @"{
+  ""root"": {
+    ""person"": {
+      ""@id"": ""1"",
+      ""name"": ""Alan"",
+      ""url"": ""http://www.google.com"",
+      ""role"": [
+        ""Admin""
+      ]
+    }
+  }
+}";
+      Assert.AreEqual(expected, arrayJsonText);
+
+      arrayXml = @"<root xmlns:json=""http://james.newtonking.com/projects/json"">
+                         <person id=""1"">
+                                 <name>Alan</name>
+                                 <url>http://www.google.com</url>
+                                 <role json:Array=""true"">Admin1</role>
+                                 <role json:Array=""true"">Admin2</role>
+                         </person>
+                       </root>";
+
+      arrayDoc = new XmlDocument();
+      arrayDoc.LoadXml(arrayXml);
+
+      arrayJsonText = SerializeXmlNode(arrayDoc);
+      expected = @"{
+  ""root"": {
+    ""person"": {
+      ""@id"": ""1"",
+      ""name"": ""Alan"",
+      ""url"": ""http://www.google.com"",
+      ""role"": [
+        ""Admin1"",
+        ""Admin2""
+      ]
+    }
+  }
+}";
+      Assert.AreEqual(expected, arrayJsonText);
+
+      arrayXml = @"<root xmlns:json=""http://james.newtonking.com/projects/json"">
+                         <person id=""1"">
+                                 <name>Alan</name>
+                                 <url>http://www.google.com</url>
+                                 <role json:Array=""false"">Admin1</role>
+                         </person>
+                       </root>";
+
+      arrayDoc = new XmlDocument();
+      arrayDoc.LoadXml(arrayXml);
+
+      arrayJsonText = SerializeXmlNode(arrayDoc);
+      expected = @"{
+  ""root"": {
+    ""person"": {
+      ""@id"": ""1"",
+      ""name"": ""Alan"",
+      ""url"": ""http://www.google.com"",
+      ""role"": ""Admin1""
+    }
+  }
+}";
+      Assert.AreEqual(expected, arrayJsonText);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "JSON root object has multiple properties. The root object must have a single property in order to create a valid XML document. Consider specifing a DeserializeRootElementName.")]
+    public void MultipleRootPropertiesXmlDocument()
+    {
+      string json = @"{""count"": 773840,""photos"": null}";
+
+      JsonConvert.DeserializeXmlNode(json);
+    }
+
+#if !NET20
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "JSON root object has multiple properties. The root object must have a single property in order to create a valid XML document. Consider specifing a DeserializeRootElementName.")]
+    public void MultipleRootPropertiesXDocument()
+    {
+      string json = @"{""count"": 773840,""photos"": null}";
+
+      JsonConvert.DeserializeXNode(json);
+    }
+#endif
+
+    [Test]
+    public void MultipleRootPropertiesAddRootElement()
+    {
+      string json = @"{""count"": 773840,""photos"": 773840}";
+
+      XmlDocument newDoc = JsonConvert.DeserializeXmlNode(json, "myRoot");
+
+      Assert.AreEqual(@"<myRoot><count>773840</count><photos>773840</photos></myRoot>", newDoc.InnerXml);
+
+#if !NET20
+     XDocument newXDoc = JsonConvert.DeserializeXNode(json, "myRoot");
+
+      Assert.AreEqual(@"<myRoot><count>773840</count><photos>773840</photos></myRoot>", newXDoc.ToString(SaveOptions.DisableFormatting));
+#endif
+    }
+
+    [Test]
+    public void NestedArrays()
+    {
+      string json = @"{
+  ""available_sizes"": [
+    [
+      ""assets/images/resized/0001/1070/11070v1-max-150x150.jpg"",
+      ""assets/images/resized/0001/1070/11070v1-max-150x150.jpg""
+    ],
+    [
+      ""assets/images/resized/0001/1070/11070v1-max-250x250.jpg"",
+      ""assets/images/resized/0001/1070/11070v1-max-250x250.jpg""
+    ],
+    [
+      ""assets/images/resized/0001/1070/11070v1-max-250x250.jpg""
+    ]
+  ]
+}";
+
+      XmlDocument newDoc = JsonConvert.DeserializeXmlNode(json, "myRoot");
+
+      string xml = IndentXml(newDoc.InnerXml);
+
+      Assert.AreEqual(@"<myRoot>
+  <available_sizes>
+    <available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes>
+    <available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes>
+  </available_sizes>
+  <available_sizes>
+    <available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
+    <available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
+  </available_sizes>
+  <available_sizes>
+    <available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
+  </available_sizes>
+</myRoot>", IndentXml(newDoc.InnerXml));
+
+#if !NET20
+      XDocument newXDoc = JsonConvert.DeserializeXNode(json, "myRoot");
+
+      Assert.AreEqual(@"<myRoot>
+  <available_sizes>
+    <available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes>
+    <available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes>
+  </available_sizes>
+  <available_sizes>
+    <available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
+    <available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
+  </available_sizes>
+  <available_sizes>
+    <available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
+  </available_sizes>
+</myRoot>", IndentXml(newXDoc.ToString(SaveOptions.DisableFormatting)));
+#endif
+
+      string newJson = JsonConvert.SerializeXmlNode(newDoc, Formatting.Indented);
+      Console.WriteLine(newJson);
+    }
+
+    [Test]
+    public void RoundTripNestedArrays()
+    {
+      string json = @"{
+  ""available_sizes"": [
+    [
+      ""assets/images/resized/0001/1070/11070v1-max-150x150.jpg"",
+      ""assets/images/resized/0001/1070/11070v1-max-150x150.jpg""
+    ],
+    [
+      ""assets/images/resized/0001/1070/11070v1-max-250x250.jpg"",
+      ""assets/images/resized/0001/1070/11070v1-max-250x250.jpg""
+    ],
+    [
+      ""assets/images/resized/0001/1070/11070v1-max-250x250.jpg""
+    ]
+  ]
+}";
+
+      XmlDocument newDoc = JsonConvert.DeserializeXmlNode(json, "myRoot", true);
+
+      Assert.AreEqual(@"<myRoot>
+  <available_sizes json:Array=""true"" xmlns:json=""http://james.newtonking.com/projects/json"">
+    <available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes>
+    <available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes>
+  </available_sizes>
+  <available_sizes json:Array=""true"" xmlns:json=""http://james.newtonking.com/projects/json"">
+    <available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
+    <available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
+  </available_sizes>
+  <available_sizes json:Array=""true"" xmlns:json=""http://james.newtonking.com/projects/json"">
+    <available_sizes json:Array=""true"">assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
+  </available_sizes>
+</myRoot>", IndentXml(newDoc.InnerXml));
+
+#if !NET20
+      XDocument newXDoc = JsonConvert.DeserializeXNode(json, "myRoot", true);
+
+      Console.WriteLine(IndentXml(newXDoc.ToString(SaveOptions.DisableFormatting)));
+
+      Assert.AreEqual(@"<myRoot>
+  <available_sizes json:Array=""true"" xmlns:json=""http://james.newtonking.com/projects/json"">
+    <available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes>
+    <available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes>
+  </available_sizes>
+  <available_sizes json:Array=""true"" xmlns:json=""http://james.newtonking.com/projects/json"">
+    <available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
+    <available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
+  </available_sizes>
+  <available_sizes json:Array=""true"" xmlns:json=""http://james.newtonking.com/projects/json"">
+    <available_sizes json:Array=""true"">assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes>
+  </available_sizes>
+</myRoot>", IndentXml(newXDoc.ToString(SaveOptions.DisableFormatting)));
+#endif
+
+      string newJson = JsonConvert.SerializeXmlNode(newDoc, Formatting.Indented, true);
+      Assert.AreEqual(json, newJson);
+    }
+
+    [Test]
+    public void MultipleNestedArraysToXml()
+    {
+      string json = @"{
+  ""available_sizes"": [
+    [
+      [113, 150],
+      ""assets/images/resized/0001/1070/11070v1-max-150x150.jpg""
+    ],
+    [
+      [189, 250],
+      ""assets/images/resized/0001/1070/11070v1-max-250x250.jpg""
+    ],
+    [
+      [341, 450],
+      ""assets/images/resized/0001/1070/11070v1-max-450x450.jpg""
+    ]
+  ]
+}";
+
+      XmlDocument newDoc = JsonConvert.DeserializeXmlNode(json, "myRoot");
+
+      Assert.AreEqual(@"<myRoot><available_sizes><available_sizes><available_sizes>113</available_sizes><available_sizes>150</available_sizes></available_sizes><available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes></available_sizes><available_sizes><available_sizes><available_sizes>189</available_sizes><available_sizes>250</available_sizes></available_sizes><available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes></available_sizes><available_sizes><available_sizes><available_sizes>341</available_sizes><available_sizes>450</available_sizes></available_sizes><available_sizes>assets/images/resized/0001/1070/11070v1-max-450x450.jpg</available_sizes></available_sizes></myRoot>", newDoc.InnerXml);
+
+#if !NET20
+      XDocument newXDoc = JsonConvert.DeserializeXNode(json, "myRoot");
+
+      Assert.AreEqual(@"<myRoot><available_sizes><available_sizes><available_sizes>113</available_sizes><available_sizes>150</available_sizes></available_sizes><available_sizes>assets/images/resized/0001/1070/11070v1-max-150x150.jpg</available_sizes></available_sizes><available_sizes><available_sizes><available_sizes>189</available_sizes><available_sizes>250</available_sizes></available_sizes><available_sizes>assets/images/resized/0001/1070/11070v1-max-250x250.jpg</available_sizes></available_sizes><available_sizes><available_sizes><available_sizes>341</available_sizes><available_sizes>450</available_sizes></available_sizes><available_sizes>assets/images/resized/0001/1070/11070v1-max-450x450.jpg</available_sizes></available_sizes></myRoot>", newXDoc.ToString(SaveOptions.DisableFormatting));
+#endif
+    }
+
+    [Test]
+    public void Encoding()
+    {
+      XmlDocument doc = new XmlDocument();
+
+      doc.LoadXml(@"<name>O""Connor</name>"); // i use "" so it will be easier to see the  problem
+
+      string json = SerializeXmlNode(doc);
+      Assert.AreEqual(@"{
+  ""name"": ""O\""Connor""
+}", json);
+    }
+
+    [Test]
+    public void SerializeComment()
+    {
+      string xml = @"<span class=""vevent"">
+  <a class=""url"" href=""http://www.web2con.com/"">Text</a><!-- Hi! -->
+</span>";
+      XmlDocument doc = new XmlDocument();
+      doc.LoadXml(xml);
+
+      string jsonText = SerializeXmlNode(doc);
+
+      string expected = @"{
+  ""span"": {
+    ""@class"": ""vevent"",
+    ""a"": {
+      ""@class"": ""url"",
+      ""@href"": ""http://www.web2con.com/"",
+      ""#text"": ""Text""
+    }/* Hi! */
+  }
+}";
+
+      Assert.AreEqual(expected, jsonText);
+
+      XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText);
+      Assert.AreEqual(@"<span class=""vevent""><a class=""url"" href=""http://www.web2con.com/"">Text</a><!-- Hi! --></span>", newDoc.InnerXml);
+    }
+
+    [Test]
+    public void SerializeExample()
+    {
+      string xml = @"<?xml version=""1.0"" standalone=""no""?>
+                       <root>
+                         <person id=""1"">
+                               <name>Alan</name>
+                               <url>http://www.google.com</url>
+                         </person>
+                         <person id=""2"">
+                               <name>Louis</name>
+                               <url>http://www.yahoo.com</url>
+                         </person>
+                       </root>";
+
+      XmlDocument doc = new XmlDocument();
+      doc.LoadXml(xml);
+
+      string jsonText = SerializeXmlNode(doc);
+      // {
+      //   "?xml": {
+      //     "@version": "1.0",
+      //     "@standalone": "no"
+      //   },
+      //   "root": {
+      //     "person": [
+      //       {
+      //         "@id": "1",
+      //         "name": "Alan",
+      //         "url": "http://www.google.com"
+      //       },
+      //       {
+      //         "@id": "2",
+      //         "name": "Louis",
+      //         "url": "http://www.yahoo.com"
+      //       }
+      //     ]
+      //   }
+      // }
+
+      // format
+      jsonText = JObject.Parse(jsonText).ToString();
+
+      Assert.AreEqual(@"{
+  ""?xml"": {
+    ""@version"": ""1.0"",
+    ""@standalone"": ""no""
+  },
+  ""root"": {
+    ""person"": [
+      {
+        ""@id"": ""1"",
+        ""name"": ""Alan"",
+        ""url"": ""http://www.google.com""
+      },
+      {
+        ""@id"": ""2"",
+        ""name"": ""Louis"",
+        ""url"": ""http://www.yahoo.com""
+      }
+    ]
+  }
+}", jsonText);
+
+      XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText);
+
+      Assert.AreEqual(doc.InnerXml, newDoc.InnerXml);
+    }
+
+    [Test]
+    public void DeserializeExample()
+    {
+      string json = @"{
+        ""?xml"": {
+          ""@version"": ""1.0"",
+          ""@standalone"": ""no""
+        },
+        ""root"": {
+          ""person"": [
+            {
+              ""@id"": ""1"",
+              ""name"": ""Alan"",
+              ""url"": ""http://www.google.com""
+            },
+            {
+              ""@id"": ""2"",
+              ""name"": ""Louis"",
+              ""url"": ""http://www.yahoo.com""
+            }
+          ]
+        }
+      }";
+
+      XmlDocument doc = (XmlDocument)DeserializeXmlNode(json);
+      // <?xml version="1.0" standalone="no"?>
+      // <root>
+      //   <person id="1">
+      //   <name>Alan</name>
+      //   <url>http://www.google.com</url>
+      //   </person>
+      //   <person id="2">
+      //   <name>Louis</name>
+      //   <url>http://www.yahoo.com</url>
+      //   </person>
+      // </root>
+
+      Assert.AreEqual(@"<?xml version=""1.0"" standalone=""no""?>
+<root>
+<person id=""1"">
+<name>Alan</name>
+<url>http://www.google.com</url>
+</person>
+<person id=""2"">
+<name>Louis</name>
+<url>http://www.yahoo.com</url>
+</person>
+</root>".Replace(Environment.NewLine, string.Empty), doc.InnerXml);
+    }
+
+    [Test]
+    public void SerializeDeserializeSpecialProperties()
+    {
+      PreserveReferencesHandlingTests.CircularDictionary circularDictionary = new PreserveReferencesHandlingTests.CircularDictionary();
+      circularDictionary.Add("other", new PreserveReferencesHandlingTests.CircularDictionary { { "blah", null } });
+      circularDictionary.Add("self", circularDictionary);
+
+      string json = JsonConvert.SerializeObject(circularDictionary, Formatting.Indented,
+        new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.All });
+
+      Assert.AreEqual(@"{
+  ""$id"": ""1"",
+  ""other"": {
+    ""$id"": ""2"",
+    ""blah"": null
+  },
+  ""self"": {
+    ""$ref"": ""1""
+  }
+}", json);
+
+      XmlNode node = DeserializeXmlNode(json, "root");
+      string xml = GetIndentedInnerXml(node);
+      string expected = @"<?xml version=""1.0"" encoding=""utf-16""?>
+<root xmlns:json=""http://james.newtonking.com/projects/json"" json:id=""1"">
+  <other json:id=""2"">
+    <blah />
+  </other>
+  <self json:ref=""1"" />
+</root>";
+
+      Assert.AreEqual(expected, xml);
+
+      string xmlJson = SerializeXmlNode(node);
+      string expectedXmlJson = @"{
+  ""root"": {
+    ""$id"": ""1"",
+    ""other"": {
+      ""$id"": ""2"",
+      ""blah"": null
+    },
+    ""self"": {
+      ""$ref"": ""1""
+    }
+  }
+}";
+
+      Assert.AreEqual(expectedXmlJson, xmlJson);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "XmlNodeConverter cannot convert JSON with an empty property name to XML.")]
+    public void EmptyPropertyName()
+    {
+      string json = @"{
+  ""8452309520V2"": {
+    """": {
+      ""CLIENT"": {
+        ""ID_EXPIRATION_1"": {
+          ""VALUE"": ""12/12/2000"",
+          ""DATATYPE"": ""D"",
+          ""MSG"": ""Missing Identification Exp. Date 1""
+        },
+        ""ID_ISSUEDATE_1"": {
+          ""VALUE"": """",
+          ""DATATYPE"": ""D"",
+          ""MSG"": ""Missing Identification Issue Date 1""
+        }
+      }
+    },
+    ""457463534534"": {
+      ""ACCOUNT"": {
+        ""FUNDING_SOURCE"": {
+          ""VALUE"": ""FS0"",
+          ""DATATYPE"": ""L"",
+          ""MSG"": ""Missing Source of Funds""
+        }
+      }
+    }
+  }
+}{
+  ""34534634535345"": {
+    """": {
+      ""CLIENT"": {
+        ""ID_NUMBER_1"": {
+          ""VALUE"": """",
+          ""DATATYPE"": ""S"",
+          ""MSG"": ""Missing Picture ID""
+        },
+        ""ID_EXPIRATION_1"": {
+          ""VALUE"": ""12/12/2000"",
+          ""DATATYPE"": ""D"",
+          ""MSG"": ""Missing Picture ID""
+        },
+        ""WALK_IN"": {
+          ""VALUE"": """",
+          ""DATATYPE"": ""L"",
+          ""MSG"": ""Missing Walk in""
+        },
+        ""PERSONAL_MEETING"": {
+          ""VALUE"": ""PM1"",
+          ""DATATYPE"": ""L"",
+          ""MSG"": ""Missing Met Client in Person""
+        },
+        ""ID_ISSUEDATE_1"": {
+          ""VALUE"": """",
+          ""DATATYPE"": ""D"",
+          ""MSG"": ""Missing Picture ID""
+        },
+        ""PHOTO_ID"": {
+          ""VALUE"": """",
+          ""DATATYPE"": ""L"",
+          ""MSG"": ""Missing Picture ID""
+        },
+        ""ID_TYPE_1"": {
+          ""VALUE"": """",
+          ""DATATYPE"": ""L"",
+          ""MSG"": ""Missing Picture ID""
+        }
+      }
+    },
+    ""45635624523"": {
+      ""ACCOUNT"": {
+        ""FUNDING_SOURCE"": {
+          ""VALUE"": ""FS1"",
+          ""DATATYPE"": ""L"",
+          ""MSG"": ""Missing Source of Funds""
+        }
+      }
+    }
+  }
+}";
+
+      DeserializeXmlNode(json);
+    }
+
+    [Test]
+    public void SingleItemArrayPropertySerialization()
+    {
+      Product product = new Product();
+
+      product.Name = "Apple";
+      product.ExpiryDate = new DateTime(2008, 12, 28, 0, 0, 0, DateTimeKind.Utc);
+      product.Price = 3.99M;
+      product.Sizes = new string[] { "Small" };
+
+      string output = JsonConvert.SerializeObject(product, new IsoDateTimeConverter());
+
+      XmlDocument xmlProduct = JsonConvert.DeserializeXmlNode(output, "product", true);
+
+      Assert.AreEqual(@"<product>
+  <Name>Apple</Name>
+  <ExpiryDate>2008-12-28T00:00:00Z</ExpiryDate>
+  <Price>3.99</Price>
+  <Sizes json:Array=""true"" xmlns:json=""http://james.newtonking.com/projects/json"">Small</Sizes>
+</product>", IndentXml(xmlProduct.InnerXml));
+
+      string output2 = JsonConvert.SerializeXmlNode(xmlProduct.DocumentElement, Formatting.Indented);
+
+      Assert.AreEqual(@"{
+  ""product"": {
+    ""Name"": ""Apple"",
+    ""ExpiryDate"": ""2008-12-28T00:00:00Z"",
+    ""Price"": ""3.99"",
+    ""Sizes"": [
+      ""Small""
+    ]
+  }
+}", output2);
+    }
+
+    public class TestComplexArrayClass
+    {
+      public string Name { get; set; }
+      public IList<Product> Products { get; set; }
+    }
+
+    [Test]
+    public void ComplexSingleItemArrayPropertySerialization()
+    {
+      TestComplexArrayClass o = new TestComplexArrayClass
+        {
+          Name = "Hi",
+          Products = new List<Product>
+            {
+              new Product { Name = "First" }
+            }
+        };
+
+      string output = JsonConvert.SerializeObject(o, new IsoDateTimeConverter());
+
+      XmlDocument xmlProduct = JsonConvert.DeserializeXmlNode(output, "test", true);
+
+      Assert.AreEqual(@"<test>
+  <Name>Hi</Name>
+  <Products json:Array=""true"" xmlns:json=""http://james.newtonking.com/projects/json"">
+    <Name>First</Name>
+    <ExpiryDate>2000-01-01T00:00:00Z</ExpiryDate>
+    <Price>0</Price>
+    <Sizes />
+  </Products>
+</test>", IndentXml(xmlProduct.InnerXml));
+
+      string output2 = JsonConvert.SerializeXmlNode(xmlProduct.DocumentElement, Formatting.Indented, true);
+
+      Assert.AreEqual(@"{
+  ""Name"": ""Hi"",
+  ""Products"": [
+    {
+      ""Name"": ""First"",
+      ""ExpiryDate"": ""2000-01-01T00:00:00Z"",
+      ""Price"": ""0"",
+      ""Sizes"": null
+    }
+  ]
+}", output2);
+    }
+
+    private string IndentXml(string xml)
+    {
+      XmlReader reader = XmlReader.Create(new StringReader(xml));
+
+      StringWriter sw = new StringWriter();
+      XmlWriter writer = XmlWriter.Create(sw, new XmlWriterSettings { Indent = true, OmitXmlDeclaration = true });
+
+      while (reader.Read())
+      {
+        writer.WriteNode(reader, false);
+      }
+
+      writer.Flush();
+
+      return sw.ToString();
+    }
+
+    [Test]
+    public void OmitRootObject()
+    {
+      string xml = @"<test>
+  <Name>Hi</Name>
+  <Name>Hi</Name>
+  <Products json:Array=""true"" xmlns:json=""http://james.newtonking.com/projects/json"">
+    <Name>First</Name>
+    <ExpiryDate>2000-01-01T00:00:00Z</ExpiryDate>
+    <Price>0</Price>
+    <Sizes />
+  </Products>
+</test>";
+
+      XmlDocument d = new XmlDocument();
+      d.LoadXml(xml);
+
+      string output = JsonConvert.SerializeXmlNode(d, Formatting.Indented, true);
+
+      Assert.AreEqual(@"{
+  ""Name"": [
+    ""Hi"",
+    ""Hi""
+  ],
+  ""Products"": [
+    {
+      ""Name"": ""First"",
+      ""ExpiryDate"": ""2000-01-01T00:00:00Z"",
+      ""Price"": ""0"",
+      ""Sizes"": null
+    }
+  ]
+}", output);
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/ExceptionTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/ExceptionTests.cs
new file mode 100644 (file)
index 0000000..2330089
--- /dev/null
@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Schema;
+using NUnit.Framework;
+
+namespace Newtonsoft.Json.Tests
+{
+  public class ExceptionTests : TestFixtureBase
+  {
+    [Test]
+    public void JsonSerializationException()
+    {
+      JsonSerializationException exception = new JsonSerializationException();
+      Assert.AreEqual("Exception of type 'Newtonsoft.Json.JsonSerializationException' was thrown.", exception.Message);
+
+      exception = new JsonSerializationException("Message!");
+      Assert.AreEqual("Message!", exception.Message);
+      Assert.AreEqual(null, exception.InnerException);
+
+      exception = new JsonSerializationException("Message!", new Exception("Inner!"));
+      Assert.AreEqual("Message!", exception.Message);
+      Assert.AreEqual("Inner!", exception.InnerException.Message);
+    }
+
+    [Test]
+    public void JsonWriterException()
+    {
+      JsonWriterException exception = new JsonWriterException();
+      Assert.AreEqual("Exception of type 'Newtonsoft.Json.JsonWriterException' was thrown.", exception.Message);
+
+      exception = new JsonWriterException("Message!");
+      Assert.AreEqual("Message!", exception.Message);
+      Assert.AreEqual(null, exception.InnerException);
+
+      exception = new JsonWriterException("Message!", new Exception("Inner!"));
+      Assert.AreEqual("Message!", exception.Message);
+      Assert.AreEqual("Inner!", exception.InnerException.Message);
+    }
+
+    [Test]
+    public void JsonReaderException()
+    {
+      JsonReaderException exception = new JsonReaderException();
+      Assert.AreEqual("Exception of type 'Newtonsoft.Json.JsonReaderException' was thrown.", exception.Message);
+
+      exception = new JsonReaderException("Message!");
+      Assert.AreEqual("Message!", exception.Message);
+      Assert.AreEqual(null, exception.InnerException);
+
+      exception = new JsonReaderException("Message!", new Exception("Inner!"));
+      Assert.AreEqual("Message!", exception.Message);
+      Assert.AreEqual("Inner!", exception.InnerException.Message);
+    }
+
+    [Test]
+    public void JsonSchemaException()
+    {
+      JsonSchemaException exception = new JsonSchemaException();
+      Assert.AreEqual("Exception of type 'Newtonsoft.Json.Schema.JsonSchemaException' was thrown.", exception.Message);
+
+      exception = new JsonSchemaException("Message!");
+      Assert.AreEqual("Message!", exception.Message);
+      Assert.AreEqual(null, exception.InnerException);
+
+      exception = new JsonSchemaException("Message!", new Exception("Inner!"));
+      Assert.AreEqual("Message!", exception.Message);
+      Assert.AreEqual("Inner!", exception.InnerException.Message);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/FileSystemEntityModel.Designer.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/FileSystemEntityModel.Designer.cs
new file mode 100644 (file)
index 0000000..b5de9bf
--- /dev/null
@@ -0,0 +1,524 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//    This code was generated from a template.
+//
+//    Manual changes to this file may cause unexpected behavior in your application.
+//    Manual changes to this file will be overwritten if the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+using System;
+using System.Data.Objects;
+using System.Data.Objects.DataClasses;
+using System.Data.EntityClient;
+using System.ComponentModel;
+using System.Xml.Serialization;
+using System.Runtime.Serialization;
+
+[assembly: EdmSchemaAttribute()]
+#region EDM Relationship Metadata
+
+[assembly: EdmRelationshipAttribute("DataServicesTestDatabaseModel", "FK_File_Folder", "Folder", System.Data.Metadata.Edm.RelationshipMultiplicity.One, typeof(Newtonsoft.Json.Tests.Folder), "File", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(Newtonsoft.Json.Tests.File))]
+[assembly: EdmRelationshipAttribute("DataServicesTestDatabaseModel", "FK_Folder_Folder", "Folder", System.Data.Metadata.Edm.RelationshipMultiplicity.ZeroOrOne, typeof(Newtonsoft.Json.Tests.Folder), "Folder1", System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(Newtonsoft.Json.Tests.Folder))]
+
+#endregion
+
+namespace Newtonsoft.Json.Tests
+{
+    #region Contexts
+    
+    /// <summary>
+    /// No Metadata Documentation available.
+    /// </summary>
+    public partial class DataServicesTestDatabaseEntities : ObjectContext
+    {
+        #region Constructors
+    
+        /// <summary>
+        /// Initializes a new DataServicesTestDatabaseEntities object using the connection string found in the 'DataServicesTestDatabaseEntities' section of the application configuration file.
+        /// </summary>
+        public DataServicesTestDatabaseEntities() : base("name=DataServicesTestDatabaseEntities", "DataServicesTestDatabaseEntities")
+        {
+            OnContextCreated();
+        }
+    
+        /// <summary>
+        /// Initialize a new DataServicesTestDatabaseEntities object.
+        /// </summary>
+        public DataServicesTestDatabaseEntities(string connectionString) : base(connectionString, "DataServicesTestDatabaseEntities")
+        {
+            OnContextCreated();
+        }
+    
+        /// <summary>
+        /// Initialize a new DataServicesTestDatabaseEntities object.
+        /// </summary>
+        public DataServicesTestDatabaseEntities(EntityConnection connection) : base(connection, "DataServicesTestDatabaseEntities")
+        {
+            OnContextCreated();
+        }
+    
+        #endregion
+    
+        #region Partial Methods
+    
+        partial void OnContextCreated();
+    
+        #endregion
+    
+        #region ObjectSet Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        public ObjectSet<File> File
+        {
+            get
+            {
+                if ((_File == null))
+                {
+                    _File = base.CreateObjectSet<File>("File");
+                }
+                return _File;
+            }
+        }
+        private ObjectSet<File> _File;
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        public ObjectSet<Folder> Folder
+        {
+            get
+            {
+                if ((_Folder == null))
+                {
+                    _Folder = base.CreateObjectSet<Folder>("Folder");
+                }
+                return _Folder;
+            }
+        }
+        private ObjectSet<Folder> _Folder;
+
+        #endregion
+        #region AddTo Methods
+    
+        /// <summary>
+        /// Deprecated Method for adding a new object to the File EntitySet. Consider using the .Add method of the associated ObjectSet&lt;T&gt; property instead.
+        /// </summary>
+        public void AddToFile(File file)
+        {
+            base.AddObject("File", file);
+        }
+    
+        /// <summary>
+        /// Deprecated Method for adding a new object to the Folder EntitySet. Consider using the .Add method of the associated ObjectSet&lt;T&gt; property instead.
+        /// </summary>
+        public void AddToFolder(Folder folder)
+        {
+            base.AddObject("Folder", folder);
+        }
+
+        #endregion
+    }
+    
+
+    #endregion
+    
+    #region Entities
+    
+    /// <summary>
+    /// No Metadata Documentation available.
+    /// </summary>
+    [EdmEntityTypeAttribute(NamespaceName="DataServicesTestDatabaseModel", Name="File")]
+    [Serializable()]
+    [DataContractAttribute(IsReference=true)]
+    public partial class File : EntityObject
+    {
+        #region Factory Method
+    
+        /// <summary>
+        /// Create a new File object.
+        /// </summary>
+        /// <param name="fileId">Initial value of the FileId property.</param>
+        /// <param name="name">Initial value of the Name property.</param>
+        /// <param name="description">Initial value of the Description property.</param>
+        /// <param name="createdDate">Initial value of the CreatedDate property.</param>
+        public static File CreateFile(global::System.Guid fileId, global::System.String name, global::System.String description, global::System.DateTime createdDate)
+        {
+            File file = new File();
+            file.FileId = fileId;
+            file.Name = name;
+            file.Description = description;
+            file.CreatedDate = createdDate;
+            return file;
+        }
+
+        #endregion
+        #region Primitive Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Guid FileId
+        {
+            get
+            {
+                return _FileId;
+            }
+            set
+            {
+                if (_FileId != value)
+                {
+                    OnFileIdChanging(value);
+                    ReportPropertyChanging("FileId");
+                    _FileId = StructuralObject.SetValidValue(value);
+                    ReportPropertyChanged("FileId");
+                    OnFileIdChanged();
+                }
+            }
+        }
+        private global::System.Guid _FileId;
+        partial void OnFileIdChanging(global::System.Guid value);
+        partial void OnFileIdChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String Name
+        {
+            get
+            {
+                return _Name;
+            }
+            set
+            {
+                OnNameChanging(value);
+                ReportPropertyChanging("Name");
+                _Name = StructuralObject.SetValidValue(value, false);
+                ReportPropertyChanged("Name");
+                OnNameChanged();
+            }
+        }
+        private global::System.String _Name;
+        partial void OnNameChanging(global::System.String value);
+        partial void OnNameChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String Description
+        {
+            get
+            {
+                return _Description;
+            }
+            set
+            {
+                OnDescriptionChanging(value);
+                ReportPropertyChanging("Description");
+                _Description = StructuralObject.SetValidValue(value, false);
+                ReportPropertyChanged("Description");
+                OnDescriptionChanged();
+            }
+        }
+        private global::System.String _Description;
+        partial void OnDescriptionChanging(global::System.String value);
+        partial void OnDescriptionChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.DateTime CreatedDate
+        {
+            get
+            {
+                return _CreatedDate;
+            }
+            set
+            {
+                OnCreatedDateChanging(value);
+                ReportPropertyChanging("CreatedDate");
+                _CreatedDate = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("CreatedDate");
+                OnCreatedDateChanged();
+            }
+        }
+        private global::System.DateTime _CreatedDate;
+        partial void OnCreatedDateChanging(global::System.DateTime value);
+        partial void OnCreatedDateChanged();
+
+        #endregion
+    
+        #region Navigation Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [XmlIgnoreAttribute()]
+        [SoapIgnoreAttribute()]
+        [DataMemberAttribute()]
+        [EdmRelationshipNavigationPropertyAttribute("DataServicesTestDatabaseModel", "FK_File_Folder", "Folder")]
+        public Folder Folder
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Folder>("DataServicesTestDatabaseModel.FK_File_Folder", "Folder").Value;
+            }
+            set
+            {
+                ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Folder>("DataServicesTestDatabaseModel.FK_File_Folder", "Folder").Value = value;
+            }
+        }
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [BrowsableAttribute(false)]
+        [DataMemberAttribute()]
+        public EntityReference<Folder> FolderReference
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Folder>("DataServicesTestDatabaseModel.FK_File_Folder", "Folder");
+            }
+            set
+            {
+                if ((value != null))
+                {
+                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference<Folder>("DataServicesTestDatabaseModel.FK_File_Folder", "Folder", value);
+                }
+            }
+        }
+
+        #endregion
+    }
+    
+    /// <summary>
+    /// No Metadata Documentation available.
+    /// </summary>
+    [EdmEntityTypeAttribute(NamespaceName="DataServicesTestDatabaseModel", Name="Folder")]
+    [Serializable()]
+    [DataContractAttribute(IsReference=true)]
+    public partial class Folder : EntityObject
+    {
+        #region Factory Method
+    
+        /// <summary>
+        /// Create a new Folder object.
+        /// </summary>
+        /// <param name="folderId">Initial value of the FolderId property.</param>
+        /// <param name="name">Initial value of the Name property.</param>
+        /// <param name="description">Initial value of the Description property.</param>
+        /// <param name="createdDate">Initial value of the CreatedDate property.</param>
+        public static Folder CreateFolder(global::System.Guid folderId, global::System.String name, global::System.String description, global::System.DateTime createdDate)
+        {
+            Folder folder = new Folder();
+            folder.FolderId = folderId;
+            folder.Name = name;
+            folder.Description = description;
+            folder.CreatedDate = createdDate;
+            return folder;
+        }
+
+        #endregion
+        #region Primitive Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.Guid FolderId
+        {
+            get
+            {
+                return _FolderId;
+            }
+            set
+            {
+                if (_FolderId != value)
+                {
+                    OnFolderIdChanging(value);
+                    ReportPropertyChanging("FolderId");
+                    _FolderId = StructuralObject.SetValidValue(value);
+                    ReportPropertyChanged("FolderId");
+                    OnFolderIdChanged();
+                }
+            }
+        }
+        private global::System.Guid _FolderId;
+        partial void OnFolderIdChanging(global::System.Guid value);
+        partial void OnFolderIdChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String Name
+        {
+            get
+            {
+                return _Name;
+            }
+            set
+            {
+                OnNameChanging(value);
+                ReportPropertyChanging("Name");
+                _Name = StructuralObject.SetValidValue(value, false);
+                ReportPropertyChanged("Name");
+                OnNameChanged();
+            }
+        }
+        private global::System.String _Name;
+        partial void OnNameChanging(global::System.String value);
+        partial void OnNameChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.String Description
+        {
+            get
+            {
+                return _Description;
+            }
+            set
+            {
+                OnDescriptionChanging(value);
+                ReportPropertyChanging("Description");
+                _Description = StructuralObject.SetValidValue(value, false);
+                ReportPropertyChanged("Description");
+                OnDescriptionChanged();
+            }
+        }
+        private global::System.String _Description;
+        partial void OnDescriptionChanging(global::System.String value);
+        partial void OnDescriptionChanged();
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
+        [DataMemberAttribute()]
+        public global::System.DateTime CreatedDate
+        {
+            get
+            {
+                return _CreatedDate;
+            }
+            set
+            {
+                OnCreatedDateChanging(value);
+                ReportPropertyChanging("CreatedDate");
+                _CreatedDate = StructuralObject.SetValidValue(value);
+                ReportPropertyChanged("CreatedDate");
+                OnCreatedDateChanged();
+            }
+        }
+        private global::System.DateTime _CreatedDate;
+        partial void OnCreatedDateChanging(global::System.DateTime value);
+        partial void OnCreatedDateChanged();
+
+        #endregion
+    
+        #region Navigation Properties
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [XmlIgnoreAttribute()]
+        [SoapIgnoreAttribute()]
+        [DataMemberAttribute()]
+        [EdmRelationshipNavigationPropertyAttribute("DataServicesTestDatabaseModel", "FK_File_Folder", "File")]
+        public EntityCollection<File> Files
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<File>("DataServicesTestDatabaseModel.FK_File_Folder", "File");
+            }
+            set
+            {
+                if ((value != null))
+                {
+                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<File>("DataServicesTestDatabaseModel.FK_File_Folder", "File", value);
+                }
+            }
+        }
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [XmlIgnoreAttribute()]
+        [SoapIgnoreAttribute()]
+        [DataMemberAttribute()]
+        [EdmRelationshipNavigationPropertyAttribute("DataServicesTestDatabaseModel", "FK_Folder_Folder", "Folder1")]
+        public EntityCollection<Folder> ChildFolders
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<Folder>("DataServicesTestDatabaseModel.FK_Folder_Folder", "Folder1");
+            }
+            set
+            {
+                if ((value != null))
+                {
+                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<Folder>("DataServicesTestDatabaseModel.FK_Folder_Folder", "Folder1", value);
+                }
+            }
+        }
+    
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [XmlIgnoreAttribute()]
+        [SoapIgnoreAttribute()]
+        [DataMemberAttribute()]
+        [EdmRelationshipNavigationPropertyAttribute("DataServicesTestDatabaseModel", "FK_Folder_Folder", "Folder")]
+        public Folder ParentFolder
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Folder>("DataServicesTestDatabaseModel.FK_Folder_Folder", "Folder").Value;
+            }
+            set
+            {
+                ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Folder>("DataServicesTestDatabaseModel.FK_Folder_Folder", "Folder").Value = value;
+            }
+        }
+        /// <summary>
+        /// No Metadata Documentation available.
+        /// </summary>
+        [BrowsableAttribute(false)]
+        [DataMemberAttribute()]
+        public EntityReference<Folder> ParentFolderReference
+        {
+            get
+            {
+                return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Folder>("DataServicesTestDatabaseModel.FK_Folder_Folder", "Folder");
+            }
+            set
+            {
+                if ((value != null))
+                {
+                    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference<Folder>("DataServicesTestDatabaseModel.FK_Folder_Folder", "Folder", value);
+                }
+            }
+        }
+
+        #endregion
+    }
+
+    #endregion
+    
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/FileSystemEntityModel.edmx b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/FileSystemEntityModel.edmx
new file mode 100644 (file)
index 0000000..f0a34e3
--- /dev/null
@@ -0,0 +1,184 @@
+<?xml version="1.0" encoding="utf-8"?>
+<edmx:Edmx Version="2.0" xmlns:edmx="http://schemas.microsoft.com/ado/2008/10/edmx">
+  <!-- EF Runtime content -->
+  <edmx:Runtime>
+    <!-- SSDL content -->
+    <edmx:StorageModels>
+      <Schema Namespace="DataServicesTestDatabaseModel.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2005" xmlns="http://schemas.microsoft.com/ado/2009/02/edm/ssdl">
+        <EntityContainer Name="DataServicesTestDatabaseModelStoreContainer">
+          <EntitySet Name="File" EntityType="DataServicesTestDatabaseModel.Store.File" store:Type="Tables" Schema="dbo" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" />
+          <EntitySet Name="Folder" EntityType="DataServicesTestDatabaseModel.Store.Folder" store:Type="Tables" Schema="dbo" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" />
+          <AssociationSet Name="FK_File_Folder" Association="DataServicesTestDatabaseModel.Store.FK_File_Folder">
+            <End Role="Folder" EntitySet="Folder" />
+            <End Role="File" EntitySet="File" />
+          </AssociationSet>
+          <AssociationSet Name="FK_Folder_Folder" Association="DataServicesTestDatabaseModel.Store.FK_Folder_Folder">
+            <End Role="Folder" EntitySet="Folder" />
+            <End Role="Folder1" EntitySet="Folder" />
+          </AssociationSet>
+        </EntityContainer>
+        <EntityType Name="File">
+          <Key>
+            <PropertyRef Name="FileId" />
+          </Key>
+          <Property Name="FileId" Type="uniqueidentifier" Nullable="false" />
+          <Property Name="Name" Type="nvarchar" Nullable="false" MaxLength="200" />
+          <Property Name="Description" Type="nvarchar" Nullable="false" MaxLength="200" />
+          <Property Name="CreatedDate" Type="datetime" Nullable="false" />
+          <Property Name="FolderId" Type="uniqueidentifier" Nullable="false" />
+        </EntityType>
+        <EntityType Name="Folder">
+          <Key>
+            <PropertyRef Name="FolderId" />
+          </Key>
+          <Property Name="FolderId" Type="uniqueidentifier" Nullable="false" />
+          <Property Name="Name" Type="nvarchar" Nullable="false" MaxLength="200" />
+          <Property Name="Description" Type="nvarchar" Nullable="false" MaxLength="200" />
+          <Property Name="CreatedDate" Type="datetime" Nullable="false" />
+          <Property Name="ParentFolderId" Type="uniqueidentifier" />
+        </EntityType>
+        <Association Name="FK_File_Folder">
+          <End Role="Folder" Type="DataServicesTestDatabaseModel.Store.Folder" Multiplicity="1" />
+          <End Role="File" Type="DataServicesTestDatabaseModel.Store.File" Multiplicity="*" />
+          <ReferentialConstraint>
+            <Principal Role="Folder">
+              <PropertyRef Name="FolderId" />
+            </Principal>
+            <Dependent Role="File">
+              <PropertyRef Name="FolderId" />
+            </Dependent>
+          </ReferentialConstraint>
+        </Association>
+        <Association Name="FK_Folder_Folder">
+          <End Role="Folder" Type="DataServicesTestDatabaseModel.Store.Folder" Multiplicity="0..1" />
+          <End Role="Folder1" Type="DataServicesTestDatabaseModel.Store.Folder" Multiplicity="*" />
+          <ReferentialConstraint>
+            <Principal Role="Folder">
+              <PropertyRef Name="FolderId" />
+            </Principal>
+            <Dependent Role="Folder1">
+              <PropertyRef Name="ParentFolderId" />
+            </Dependent>
+          </ReferentialConstraint>
+        </Association>
+      </Schema>
+    </edmx:StorageModels>
+    <!-- CSDL content -->
+    <edmx:ConceptualModels>
+      <Schema Namespace="DataServicesTestDatabaseModel" Alias="Self" xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
+        <EntityContainer Name="DataServicesTestDatabaseEntities">
+          <EntitySet Name="File" EntityType="DataServicesTestDatabaseModel.File" />
+          <EntitySet Name="Folder" EntityType="DataServicesTestDatabaseModel.Folder" />
+          <AssociationSet Name="FK_File_Folder" Association="DataServicesTestDatabaseModel.FK_File_Folder">
+            <End Role="Folder" EntitySet="Folder" />
+            <End Role="File" EntitySet="File" />
+          </AssociationSet>
+          <AssociationSet Name="FK_Folder_Folder" Association="DataServicesTestDatabaseModel.FK_Folder_Folder">
+            <End Role="Folder" EntitySet="Folder" />
+            <End Role="Folder1" EntitySet="Folder" />
+          </AssociationSet>
+        </EntityContainer>
+        <EntityType Name="File">
+          <Key>
+            <PropertyRef Name="FileId" />
+          </Key>
+          <Property Name="FileId" Type="Guid" Nullable="false" />
+          <Property Name="Name" Type="String" Nullable="false" MaxLength="200" Unicode="true" FixedLength="false" />
+          <Property Name="Description" Type="String" Nullable="false" MaxLength="200" Unicode="true" FixedLength="false" />
+          <Property Name="CreatedDate" Type="DateTime" Nullable="false" />
+          <NavigationProperty Name="Folder" Relationship="DataServicesTestDatabaseModel.FK_File_Folder" FromRole="File" ToRole="Folder" />
+        </EntityType>
+        <EntityType Name="Folder">
+          <Key>
+            <PropertyRef Name="FolderId" />
+          </Key>
+          <Property Name="FolderId" Type="Guid" Nullable="false" />
+          <Property Name="Name" Type="String" Nullable="false" MaxLength="200" Unicode="true" FixedLength="false" />
+          <Property Name="Description" Type="String" Nullable="false" MaxLength="200" Unicode="true" FixedLength="false" />
+          <Property Name="CreatedDate" Type="DateTime" Nullable="false" />
+          <NavigationProperty Name="Files" Relationship="DataServicesTestDatabaseModel.FK_File_Folder" FromRole="Folder" ToRole="File" />
+          <NavigationProperty Name="ChildFolders" Relationship="DataServicesTestDatabaseModel.FK_Folder_Folder" FromRole="Folder" ToRole="Folder1" />
+          <NavigationProperty Name="ParentFolder" Relationship="DataServicesTestDatabaseModel.FK_Folder_Folder" FromRole="Folder1" ToRole="Folder" />
+        </EntityType>
+        <Association Name="FK_File_Folder">
+          <End Role="Folder" Type="DataServicesTestDatabaseModel.Folder" Multiplicity="1" />
+          <End Role="File" Type="DataServicesTestDatabaseModel.File" Multiplicity="*" />
+        </Association>
+        <Association Name="FK_Folder_Folder">
+          <End Role="Folder" Type="DataServicesTestDatabaseModel.Folder" Multiplicity="0..1" />
+          <End Role="Folder1" Type="DataServicesTestDatabaseModel.Folder" Multiplicity="*" />
+        </Association>
+      </Schema>
+    </edmx:ConceptualModels>
+    <!-- C-S mapping content -->
+    <edmx:Mappings>
+      <Mapping Space="C-S" xmlns="http://schemas.microsoft.com/ado/2008/09/mapping/cs">
+        <EntityContainerMapping StorageEntityContainer="DataServicesTestDatabaseModelStoreContainer" CdmEntityContainer="DataServicesTestDatabaseEntities">
+          <EntitySetMapping Name="File">
+            <EntityTypeMapping TypeName="IsTypeOf(DataServicesTestDatabaseModel.File)">
+              <MappingFragment StoreEntitySet="File">
+                <ScalarProperty Name="FileId" ColumnName="FileId" />
+                <ScalarProperty Name="Name" ColumnName="Name" />
+                <ScalarProperty Name="Description" ColumnName="Description" />
+                <ScalarProperty Name="CreatedDate" ColumnName="CreatedDate" />
+              </MappingFragment>
+            </EntityTypeMapping>
+          </EntitySetMapping>
+          <EntitySetMapping Name="Folder">
+            <EntityTypeMapping TypeName="IsTypeOf(DataServicesTestDatabaseModel.Folder)">
+              <MappingFragment StoreEntitySet="Folder">
+                <ScalarProperty Name="FolderId" ColumnName="FolderId" />
+                <ScalarProperty Name="Name" ColumnName="Name" />
+                <ScalarProperty Name="Description" ColumnName="Description" />
+                <ScalarProperty Name="CreatedDate" ColumnName="CreatedDate" />
+              </MappingFragment>
+            </EntityTypeMapping>
+          </EntitySetMapping>
+          <AssociationSetMapping Name="FK_File_Folder" TypeName="DataServicesTestDatabaseModel.FK_File_Folder" StoreEntitySet="File">
+            <EndProperty Name="Folder">
+              <ScalarProperty Name="FolderId" ColumnName="FolderId" />
+            </EndProperty>
+            <EndProperty Name="File">
+              <ScalarProperty Name="FileId" ColumnName="FileId" />
+            </EndProperty>
+          </AssociationSetMapping>
+          <AssociationSetMapping Name="FK_Folder_Folder" TypeName="DataServicesTestDatabaseModel.FK_Folder_Folder" StoreEntitySet="Folder">
+            <EndProperty Name="Folder">
+              <ScalarProperty Name="FolderId" ColumnName="ParentFolderId" />
+            </EndProperty>
+            <EndProperty Name="Folder1">
+              <ScalarProperty Name="FolderId" ColumnName="FolderId" />
+            </EndProperty>
+            <Condition ColumnName="ParentFolderId" IsNull="false" />
+          </AssociationSetMapping>
+        </EntityContainerMapping>
+      </Mapping>
+    </edmx:Mappings>
+  </edmx:Runtime>
+  <!-- EF Designer content (DO NOT EDIT MANUALLY BELOW HERE) -->
+  <edmx:Designer>
+    <edmx:Connection>
+      <DesignerInfoPropertySet xmlns="http://schemas.microsoft.com/ado/2008/10/edmx">
+        <DesignerProperty Name="MetadataArtifactProcessing" Value="EmbedInOutputAssembly" />
+      </DesignerInfoPropertySet>
+    </edmx:Connection>
+    <edmx:Options>
+      <DesignerInfoPropertySet xmlns="http://schemas.microsoft.com/ado/2008/10/edmx">
+        <DesignerProperty Name="ValidateOnBuild" Value="true" />
+      </DesignerInfoPropertySet>
+    </edmx:Options>
+    <!-- Diagram content (shape and connector positions) -->
+    <edmx:Diagrams>
+      <Diagram Name="FileSystemEntityModel" xmlns="http://schemas.microsoft.com/ado/2008/10/edmx">
+        <EntityTypeShape EntityType="DataServicesTestDatabaseModel.File" Width="1.5" PointX="3" PointY="1.125" Height="1.9802864583333335" IsExpanded="true" />
+        <EntityTypeShape EntityType="DataServicesTestDatabaseModel.Folder" Width="1.5" PointX="0.75" PointY="1" Height="2.3648893229166665" IsExpanded="true" />
+        <AssociationConnector Association="DataServicesTestDatabaseModel.FK_File_Folder" ManuallyRouted="false">
+          <ConnectorPoint PointX="2.25" PointY="2.1151432291666667" />
+          <ConnectorPoint PointX="3" PointY="2.1151432291666667" /></AssociationConnector>
+        <AssociationConnector Association="DataServicesTestDatabaseModel.FK_Folder_Folder" ManuallyRouted="false">
+          <ConnectorPoint PointX="1.2819230769230767" PointY="3.3648893229166665" />
+          <ConnectorPoint PointX="1.2819230769230767" PointY="3.6148893229166665" />
+          <ConnectorPoint PointX="1.7284615384615383" PointY="3.6148893229166665" />
+          <ConnectorPoint PointX="1.7284615384615383" PointY="3.3648893229166665" /></AssociationConnector></Diagram></edmx:Diagrams>
+  </edmx:Designer>
+</edmx:Edmx>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/JsonArrayAttributeTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/JsonArrayAttributeTests.cs
new file mode 100644 (file)
index 0000000..61d89b4
--- /dev/null
@@ -0,0 +1,63 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+
+namespace Newtonsoft.Json.Tests
+{
+  public class JsonArrayAttributeTests : TestFixtureBase
+  {
+    [Test]
+    public void IsReferenceTest()
+    {
+      JsonPropertyAttribute attribute = new JsonPropertyAttribute();
+      Assert.AreEqual(null, attribute._isReference);
+      Assert.AreEqual(false, attribute.IsReference);
+
+      attribute.IsReference = false;
+      Assert.AreEqual(false, attribute._isReference);
+      Assert.AreEqual(false, attribute.IsReference);
+
+      attribute.IsReference = true;
+      Assert.AreEqual(true, attribute._isReference);
+      Assert.AreEqual(true, attribute.IsReference);
+    }
+
+    [Test]
+    public void NullValueHandlingTest()
+    {
+      JsonPropertyAttribute attribute = new JsonPropertyAttribute();
+      Assert.AreEqual(null, attribute._nullValueHandling);
+      Assert.AreEqual(NullValueHandling.Include, attribute.NullValueHandling);
+
+      attribute.NullValueHandling = NullValueHandling.Ignore;
+      Assert.AreEqual(NullValueHandling.Ignore, attribute._nullValueHandling);
+      Assert.AreEqual(NullValueHandling.Ignore, attribute.NullValueHandling);
+    }
+
+    [Test]
+    public void DefaultValueHandlingTest()
+    {
+      JsonPropertyAttribute attribute = new JsonPropertyAttribute();
+      Assert.AreEqual(null, attribute._defaultValueHandling);
+      Assert.AreEqual(DefaultValueHandling.Include, attribute.DefaultValueHandling);
+
+      attribute.DefaultValueHandling = DefaultValueHandling.Ignore;
+      Assert.AreEqual(DefaultValueHandling.Ignore, attribute._defaultValueHandling);
+      Assert.AreEqual(DefaultValueHandling.Ignore, attribute.DefaultValueHandling);
+    }
+
+    [Test]
+    public void ReferenceLoopHandlingTest()
+    {
+      JsonPropertyAttribute attribute = new JsonPropertyAttribute();
+      Assert.AreEqual(null, attribute._defaultValueHandling);
+      Assert.AreEqual(ReferenceLoopHandling.Error, attribute.ReferenceLoopHandling);
+
+      attribute.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
+      Assert.AreEqual(ReferenceLoopHandling.Ignore, attribute._referenceLoopHandling);
+      Assert.AreEqual(ReferenceLoopHandling.Ignore, attribute.ReferenceLoopHandling);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/JsonConvertTest.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/JsonConvertTest.cs
new file mode 100644 (file)
index 0000000..73a5a69
--- /dev/null
@@ -0,0 +1,342 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using Newtonsoft.Json.Utilities;
+using NUnit.Framework;
+
+namespace Newtonsoft.Json.Tests
+{
+  public class JsonConvertTest : TestFixtureBase
+  {
+#if Entities
+    [Test]
+    public void EntitiesTest()
+    {
+      Purchase purchase = new Purchase() { Id = 1 };
+      purchase.PurchaseLine.Add(new PurchaseLine() { Id = 1, Purchase = purchase });
+      purchase.PurchaseLine.Add(new PurchaseLine() { Id = 2, Purchase = purchase });
+
+      StringWriter sw = new StringWriter();
+      JsonSerializer serializer = new JsonSerializer();
+      serializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
+
+      using (JsonWriter jw = new JsonTextWriter(sw))
+      {
+        jw.Formatting = Formatting.Indented;
+
+        serializer.Serialize(jw, purchase);
+      }
+
+      string json = sw.ToString();
+
+      Assert.AreEqual(@"{
+  ""Id"": 1,
+  ""PurchaseLine"": [
+    {
+      ""Id"": 1,
+      ""PurchaseReference"": {
+        ""EntityKey"": null,
+        ""RelationshipName"": ""EntityDataModel.PurchasePurchaseLine"",
+        ""SourceRoleName"": ""PurchaseLine"",
+        ""TargetRoleName"": ""Purchase"",
+        ""RelationshipSet"": null,
+        ""IsLoaded"": false
+      },
+      ""EntityState"": 1,
+      ""EntityKey"": null
+    },
+    {
+      ""Id"": 2,
+      ""PurchaseReference"": {
+        ""EntityKey"": null,
+        ""RelationshipName"": ""EntityDataModel.PurchasePurchaseLine"",
+        ""SourceRoleName"": ""PurchaseLine"",
+        ""TargetRoleName"": ""Purchase"",
+        ""RelationshipSet"": null,
+        ""IsLoaded"": false
+      },
+      ""EntityState"": 1,
+      ""EntityKey"": null
+    }
+  ],
+  ""EntityState"": 1,
+  ""EntityKey"": null
+}", json);
+
+      Purchase newPurchase = JsonConvert.DeserializeObject<Purchase>(json);
+      Assert.AreEqual(1, newPurchase.Id);
+
+      Assert.AreEqual(2, newPurchase.PurchaseLine.Count);
+      Assert.AreEqual(1, newPurchase.PurchaseLine.ElementAt(0).Id);
+      Assert.AreEqual(2, newPurchase.PurchaseLine.ElementAt(1).Id);
+    }
+#endif
+
+    [Test]
+    public void EscapeJavaScriptString()
+    {
+      string result;
+
+      result = JavaScriptUtils.ToEscapedJavaScriptString("How now brown cow?", '"', true);
+      Assert.AreEqual(@"""How now brown cow?""", result);
+
+      result = JavaScriptUtils.ToEscapedJavaScriptString("How now 'brown' cow?", '"', true);
+      Assert.AreEqual(@"""How now 'brown' cow?""", result);
+
+      result = JavaScriptUtils.ToEscapedJavaScriptString("How now <brown> cow?", '"', true);
+      Assert.AreEqual(@"""How now <brown> cow?""", result);
+
+      result = JavaScriptUtils.ToEscapedJavaScriptString(@"How 
+now brown cow?", '"', true);
+      Assert.AreEqual(@"""How \r\nnow brown cow?""", result);
+
+      result = JavaScriptUtils.ToEscapedJavaScriptString("\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007", '"', true);
+      Assert.AreEqual(@"""\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007""", result);
+
+      result =
+        JavaScriptUtils.ToEscapedJavaScriptString("\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013", '"', true);
+      Assert.AreEqual(@"""\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013""", result);
+
+      result =
+        JavaScriptUtils.ToEscapedJavaScriptString(
+          "\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f ", '"', true);
+      Assert.AreEqual(@"""\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f """, result);
+
+      result =
+        JavaScriptUtils.ToEscapedJavaScriptString(
+          "!\"#$%&\u0027()*+,-./0123456789:;\u003c=\u003e?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]", '"', true);
+      Assert.AreEqual(@"""!\""#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]""", result);
+
+      result = JavaScriptUtils.ToEscapedJavaScriptString("^_`abcdefghijklmnopqrstuvwxyz{|}~", '"', true);
+      Assert.AreEqual(@"""^_`abcdefghijklmnopqrstuvwxyz{|}~""", result);
+
+      string data =
+        "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&\u0027()*+,-./0123456789:;\u003c=\u003e?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
+      string expected =
+        @"""\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\""#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~""";
+
+      result = JavaScriptUtils.ToEscapedJavaScriptString(data, '"', true);
+      Assert.AreEqual(expected, result);
+
+      result = JavaScriptUtils.ToEscapedJavaScriptString("Fred's cat.", '\'', true);
+      Assert.AreEqual(result, @"'Fred\'s cat.'");
+
+      result = JavaScriptUtils.ToEscapedJavaScriptString(@"""How are you gentlemen?"" said Cats.", '"', true);
+      Assert.AreEqual(result, @"""\""How are you gentlemen?\"" said Cats.""");
+
+      result = JavaScriptUtils.ToEscapedJavaScriptString(@"""How are' you gentlemen?"" said Cats.", '"', true);
+      Assert.AreEqual(result, @"""\""How are' you gentlemen?\"" said Cats.""");
+
+      result = JavaScriptUtils.ToEscapedJavaScriptString(@"Fred's ""cat"".", '\'', true);
+      Assert.AreEqual(result, @"'Fred\'s ""cat"".'");
+
+      result = JavaScriptUtils.ToEscapedJavaScriptString("\u001farray\u003caddress");
+      Assert.AreEqual(result, @"""\u001farray<address""");
+    }
+
+    [Test]
+    public void EscapeJavaScriptString_UnicodeLinefeeds()
+    {
+      string result;
+
+      result = JavaScriptUtils.ToEscapedJavaScriptString("before" + '\u0085' + "after", '"', true);
+      Assert.AreEqual(@"""before\u0085after""", result);
+
+      result = JavaScriptUtils.ToEscapedJavaScriptString("before" + '\u2028' + "after", '"', true);
+      Assert.AreEqual(@"""before\u2028after""", result);
+
+      result = JavaScriptUtils.ToEscapedJavaScriptString("before" + '\u2029' + "after", '"', true);
+      Assert.AreEqual(@"""before\u2029after""", result);
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Unsupported type: System.Version. Use the JsonSerializer class to get the object's JSON representation.")]
+    public void ToStringInvalid()
+    {
+      JsonConvert.ToString(new Version(1, 0));
+    }
+
+    [Test]
+    public void GuidToString()
+    {
+      Guid guid = new Guid("BED7F4EA-1A96-11d2-8F08-00A0C9A6186D");
+      string json = JsonConvert.ToString(guid);
+      Assert.AreEqual(@"""bed7f4ea-1a96-11d2-8f08-00a0c9a6186d""", json);
+    }
+
+    [Test]
+    public void EnumToString()
+    {
+      string json = JsonConvert.ToString(StringComparison.CurrentCultureIgnoreCase);
+      Assert.AreEqual("1", json);
+    }
+
+    [Test]
+    public void ObjectToString()
+    {
+      object value;
+
+      value = 1;
+      Assert.AreEqual("1", JsonConvert.ToString(value));
+
+      value = 1.1;
+      Assert.AreEqual("1.1", JsonConvert.ToString(value));
+
+      value = 1.1m;
+      Assert.AreEqual("1.1", JsonConvert.ToString(value));
+
+      value = (float)1.1;
+      Assert.AreEqual("1.1", JsonConvert.ToString(value));
+
+      value = (short)1;
+      Assert.AreEqual("1", JsonConvert.ToString(value));
+
+      value = (long)1;
+      Assert.AreEqual("1", JsonConvert.ToString(value));
+
+      value = (byte)1;
+      Assert.AreEqual("1", JsonConvert.ToString(value));
+
+      value = (uint)1;
+      Assert.AreEqual("1", JsonConvert.ToString(value));
+
+      value = (ushort)1;
+      Assert.AreEqual("1", JsonConvert.ToString(value));
+
+      value = (sbyte)1;
+      Assert.AreEqual("1", JsonConvert.ToString(value));
+
+      value = (ulong)1;
+      Assert.AreEqual("1", JsonConvert.ToString(value));
+
+      value = new DateTime(JsonConvert.InitialJavaScriptDateTicks, DateTimeKind.Utc);
+      Assert.AreEqual(@"""\/Date(0)\/""", JsonConvert.ToString(value));
+
+#if !PocketPC && !NET20
+      value = new DateTimeOffset(JsonConvert.InitialJavaScriptDateTicks, TimeSpan.Zero);
+      Assert.AreEqual(@"""\/Date(0+0000)\/""", JsonConvert.ToString(value));
+#endif
+
+      value = null;
+      Assert.AreEqual("null", JsonConvert.ToString(value));
+
+      value = DBNull.Value;
+      Assert.AreEqual("null", JsonConvert.ToString(value));
+
+      value = "I am a string";
+      Assert.AreEqual(@"""I am a string""", JsonConvert.ToString(value));
+
+      value = true;
+      Assert.AreEqual("true", JsonConvert.ToString(value));
+
+      value = 'c';
+      Assert.AreEqual(@"""c""", JsonConvert.ToString(value));
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonReaderException), ExpectedMessage = "After parsing a value an unexpected character was encountered: t. Line 1, position 20.")]
+    public void TestInvalidStrings()
+    {
+      string orig = @"this is a string ""that has quotes"" ";
+
+      string serialized = JsonConvert.SerializeObject(orig);
+
+      // *** Make string invalid by stripping \" \"
+      serialized = serialized.Replace(@"\""", "\"");
+
+      JsonConvert.DeserializeObject<string>(serialized);
+    }
+
+    [Test]
+    public void DeserializeValueObjects()
+    {
+      int i = JsonConvert.DeserializeObject<int>("1");
+      Assert.AreEqual(1, i);
+
+#if !PocketPC && !NET20
+      DateTimeOffset d = JsonConvert.DeserializeObject<DateTimeOffset>(@"""\/Date(-59011455539000+0000)\/""");
+      Assert.AreEqual(new DateTimeOffset(new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Utc)), d);
+#endif
+
+      bool b = JsonConvert.DeserializeObject<bool>("true");
+      Assert.AreEqual(true, b);
+
+      object n = JsonConvert.DeserializeObject<object>("null");
+      Assert.AreEqual(null, n);
+
+      object u = JsonConvert.DeserializeObject<object>("undefined");
+      Assert.AreEqual(null, u);
+    }
+
+    [Test]
+    public void FloatToString()
+    {
+      Assert.AreEqual("1.1", JsonConvert.ToString(1.1));
+      Assert.AreEqual("1.11", JsonConvert.ToString(1.11));
+      Assert.AreEqual("1.111", JsonConvert.ToString(1.111));
+      Assert.AreEqual("1.1111", JsonConvert.ToString(1.1111));
+      Assert.AreEqual("1.11111", JsonConvert.ToString(1.11111));
+      Assert.AreEqual("1.111111", JsonConvert.ToString(1.111111));
+      Assert.AreEqual("1.0", JsonConvert.ToString(1.0));
+      Assert.AreEqual("1.0", JsonConvert.ToString(1d));
+      Assert.AreEqual("-1.0", JsonConvert.ToString(-1d)); 
+      Assert.AreEqual("1.01", JsonConvert.ToString(1.01));
+      Assert.AreEqual("1.001", JsonConvert.ToString(1.001));
+      Assert.AreEqual(JsonConvert.PositiveInfinity, JsonConvert.ToString(double.PositiveInfinity));
+      Assert.AreEqual(JsonConvert.NegativeInfinity, JsonConvert.ToString(double.NegativeInfinity));
+      Assert.AreEqual(JsonConvert.NaN, JsonConvert.ToString(double.NaN));
+    }
+
+    [Test]
+    public void DecimalToString()
+    {
+      Assert.AreEqual("1.1", JsonConvert.ToString(1.1m));
+      Assert.AreEqual("1.11", JsonConvert.ToString(1.11m));
+      Assert.AreEqual("1.111", JsonConvert.ToString(1.111m));
+      Assert.AreEqual("1.1111", JsonConvert.ToString(1.1111m));
+      Assert.AreEqual("1.11111", JsonConvert.ToString(1.11111m));
+      Assert.AreEqual("1.111111", JsonConvert.ToString(1.111111m));
+      Assert.AreEqual("1.0", JsonConvert.ToString(1.0m));
+      Assert.AreEqual("-1.0", JsonConvert.ToString(-1.0m));
+      Assert.AreEqual("-1.0", JsonConvert.ToString(-1m));
+      Assert.AreEqual("1.0", JsonConvert.ToString(1m));
+      Assert.AreEqual("1.01", JsonConvert.ToString(1.01m));
+      Assert.AreEqual("1.001", JsonConvert.ToString(1.001m));
+      Assert.AreEqual("79228162514264337593543950335.0", JsonConvert.ToString(decimal.MaxValue));
+      Assert.AreEqual("-79228162514264337593543950335.0", JsonConvert.ToString(decimal.MinValue));
+    }
+
+    [Test]
+    public void StringEscaping()
+    {
+      string v = @"It's a good day
+""sunshine""";
+
+      string json = JsonConvert.ToString(v);
+      Assert.AreEqual(@"""It's a good day\r\n\""sunshine\""""", json);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs
new file mode 100644 (file)
index 0000000..9578af4
--- /dev/null
@@ -0,0 +1,826 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using NUnit.Framework;
+using Newtonsoft.Json;
+using System.IO;
+using System.Xml;
+
+namespace Newtonsoft.Json.Tests
+{
+  public class JsonTextReaderTest : TestFixtureBase
+  {
+    [Test]
+    public void CloseInput()
+    {
+      MemoryStream ms = new MemoryStream();
+      JsonTextReader reader = new JsonTextReader(new StreamReader(ms));
+
+      Assert.IsTrue(ms.CanRead);
+      reader.Close();
+      Assert.IsFalse(ms.CanRead);
+
+      ms = new MemoryStream();
+      reader = new JsonTextReader(new StreamReader(ms)) { CloseInput = false };
+
+      Assert.IsTrue(ms.CanRead);
+      reader.Close();
+      Assert.IsTrue(ms.CanRead);
+    }
+    
+    [Test]
+    public void YahooFinance()
+    {
+      string input = @"{
+""matches"" : [
+{""t"":""C"", ""n"":""Citigroup Inc."", ""e"":""NYSE"", ""id"":""662713""}
+,{""t"":""CHL"", ""n"":""China Mobile Ltd. (ADR)"", ""e"":""NYSE"", ""id"":""660998""}
+,{""t"":""PTR"", ""n"":""PetroChina Company Limited (ADR)"", ""e"":""NYSE"", ""id"":""664536""}
+,{""t"":""RIO"", ""n"":""Companhia Vale do Rio Doce (ADR)"", ""e"":""NYSE"", ""id"":""671472""}
+,{""t"":""RIOPR"", ""n"":""Companhia Vale do Rio Doce (ADR)"", ""e"":""NYSE"", ""id"":""3512643""}
+,{""t"":""CSCO"", ""n"":""Cisco Systems, Inc."", ""e"":""NASDAQ"", ""id"":""99624""}
+,{""t"":""CVX"", ""n"":""Chevron Corporation"", ""e"":""NYSE"", ""id"":""667226""}
+,{""t"":""TM"", ""n"":""Toyota Motor Corporation (ADR)"", ""e"":""NYSE"", ""id"":""655880""}
+,{""t"":""JPM"", ""n"":""JPMorgan Chase \\x26 Co."", ""e"":""NYSE"", ""id"":""665639""}
+,{""t"":""COP"", ""n"":""ConocoPhillips"", ""e"":""NYSE"", ""id"":""1691168""}
+,{""t"":""LFC"", ""n"":""China Life Insurance Company Ltd. (ADR)"", ""e"":""NYSE"", ""id"":""688679""}
+,{""t"":""NOK"", ""n"":""Nokia Corporation (ADR)"", ""e"":""NYSE"", ""id"":""657729""}
+,{""t"":""KO"", ""n"":""The Coca-Cola Company"", ""e"":""NYSE"", ""id"":""6550""}
+,{""t"":""VZ"", ""n"":""Verizon Communications Inc."", ""e"":""NYSE"", ""id"":""664887""}
+,{""t"":""AMX"", ""n"":""America Movil S.A.B de C.V. (ADR)"", ""e"":""NYSE"", ""id"":""665834""}],
+""all"" : false
+}
+";
+
+      using (JsonReader jsonReader = new JsonTextReader(new StringReader(input)))
+      {
+        while (jsonReader.Read())
+        {
+          Console.WriteLine(jsonReader.Value);
+        }
+      }
+    }
+
+    [Test]
+    public void ReadingIndented()
+    {
+      string input = @"{
+  CPU: 'Intel',
+  Drives: [
+    'DVD read/writer',
+    ""500 gigabyte hard drive""
+  ]
+}";
+
+      StringReader sr = new StringReader(input);
+
+      using (JsonTextReader jsonReader = new JsonTextReader(sr))
+      {
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.None);
+        Assert.AreEqual(0, jsonReader.LineNumber);
+        Assert.AreEqual(0, jsonReader.LinePosition);
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.StartObject);
+        Assert.AreEqual(1, jsonReader.LineNumber);
+        Assert.AreEqual(1, jsonReader.LinePosition);
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.PropertyName);
+        Assert.AreEqual(jsonReader.Value, "CPU");
+        Assert.AreEqual(2, jsonReader.LineNumber);
+        Assert.AreEqual(6, jsonReader.LinePosition);
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.String);
+        Assert.AreEqual(jsonReader.Value, "Intel");
+        Assert.AreEqual(2, jsonReader.LineNumber);
+        Assert.AreEqual(14, jsonReader.LinePosition);
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.PropertyName);
+        Assert.AreEqual(jsonReader.Value, "Drives");
+        Assert.AreEqual(3, jsonReader.LineNumber);
+        Assert.AreEqual(9, jsonReader.LinePosition);
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.StartArray);
+        Assert.AreEqual(3, jsonReader.LineNumber);
+        Assert.AreEqual(11, jsonReader.LinePosition);
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.String);
+        Assert.AreEqual(jsonReader.Value, "DVD read/writer");
+        Assert.AreEqual(jsonReader.QuoteChar, '\'');
+        Assert.AreEqual(4, jsonReader.LineNumber);
+        Assert.AreEqual(21, jsonReader.LinePosition);
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.String);
+        Assert.AreEqual(jsonReader.Value, "500 gigabyte hard drive");
+        Assert.AreEqual(jsonReader.QuoteChar, '"');
+        Assert.AreEqual(5, jsonReader.LineNumber);
+        Assert.AreEqual(29, jsonReader.LinePosition);
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.EndArray);
+        Assert.AreEqual(6, jsonReader.LineNumber);
+        Assert.AreEqual(3, jsonReader.LinePosition);
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.EndObject);
+        Assert.AreEqual(7, jsonReader.LineNumber);
+        Assert.AreEqual(1, jsonReader.LinePosition);
+
+        Assert.IsFalse(jsonReader.Read());
+      }
+    }
+
+    [Test]
+    public void Depth()
+    {
+      string input = "{value:'Purple\\r \\n monkey\\'s:\\tdishwasher',array:[1,2]}";
+
+      StringReader sr = new StringReader(input);
+
+      using (JsonReader jsonReader = new JsonTextReader(sr))
+      {
+        Assert.AreEqual(0, jsonReader.Depth);
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.StartObject);
+        Assert.AreEqual(0, jsonReader.Depth);
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.PropertyName);
+        Assert.AreEqual(1, jsonReader.Depth);
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.String);
+        Assert.AreEqual(jsonReader.Value, "Purple\r \n monkey's:\tdishwasher");
+        Assert.AreEqual(jsonReader.QuoteChar, '\'');
+        Assert.AreEqual(1, jsonReader.Depth);
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.PropertyName);
+        Assert.AreEqual(1, jsonReader.Depth);
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.StartArray);
+        Assert.AreEqual(2, jsonReader.Depth);
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.Integer);
+        Assert.AreEqual(1, jsonReader.Value);
+        Assert.AreEqual(3, jsonReader.Depth);
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.Integer);
+        Assert.AreEqual(2, jsonReader.Value);
+        Assert.AreEqual(3, jsonReader.Depth);
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.EndArray);
+        Assert.AreEqual(1, jsonReader.Depth);
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.EndObject);
+        Assert.AreEqual(0, jsonReader.Depth);
+      }
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentNullException), ExpectedMessage = @"Value cannot be null.
+Parameter name: reader")]
+    public void NullTextReader()
+    {
+      new JsonTextReader(null);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonReaderException), ExpectedMessage = "Unterminated string. Expected delimiter: '. Line 1, position 3.")]
+    public void UnexpectedEndOfString()
+    {
+      JsonReader reader = new JsonTextReader(new StringReader("'hi"));
+      reader.Read();
+    }
+
+    [Test]
+    public void ReadNullTerminatorStrings()
+    {
+      JsonReader reader = new JsonTextReader(new StringReader("'h\0i'"));
+      Assert.IsTrue(reader.Read());
+
+      Assert.AreEqual("h\0i", reader.Value);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonReaderException), ExpectedMessage = "Unexpected end while parsing unicode character. Line 1, position 7.")]
+    public void UnexpectedEndOfHex()
+    {
+      JsonReader reader = new JsonTextReader(new StringReader(@"'h\u006"));
+      reader.Read();
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonReaderException), ExpectedMessage = "Unterminated string. Expected delimiter: '. Line 1, position 3.")]
+    public void UnexpectedEndOfControlCharacter()
+    {
+      JsonReader reader = new JsonTextReader(new StringReader(@"'h\"));
+      reader.Read();
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonReaderException), ExpectedMessage = "Unexpected token when reading bytes: Boolean. Line 1, position 4.")]
+    public void ReadBytesWithBadCharacter()
+    {
+      JsonReader reader = new JsonTextReader(new StringReader(@"true"));
+      reader.ReadAsBytes();
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonReaderException), ExpectedMessage = "Unterminated string. Expected delimiter: '. Line 1, position 17.")]
+    public void ReadBytesWithUnexpectedEnd()
+    {
+      string helloWorld = "Hello world!";
+      byte[] helloWorldData = Encoding.UTF8.GetBytes(helloWorld);
+
+      JsonReader reader = new JsonTextReader(new StringReader(@"'" + Convert.ToBase64String(helloWorldData)));
+      reader.ReadAsBytes();
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonReaderException), ExpectedMessage = "Unexpected end when reading bytes: Line 1, position 3.")]
+    public void ReadBytesNoStartWithUnexpectedEnd()
+    {
+      JsonReader reader = new JsonTextReader(new StringReader(@"[  "));
+      Assert.IsTrue(reader.Read());
+      reader.ReadAsBytes();
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonReaderException), ExpectedMessage = "Unexpected end when parsing unquoted property name. Line 1, position 4.")]
+    public void UnexpectedEndWhenParsingUnquotedProperty()
+    {
+      JsonReader reader = new JsonTextReader(new StringReader(@"{aww"));
+      Assert.IsTrue(reader.Read());
+      reader.Read();
+    }
+
+    [Test]
+    public void ParsingQuotedPropertyWithControlCharacters()
+    {
+      JsonReader reader = new JsonTextReader(new StringReader(@"{'hi\r\nbye':1}"));
+      Assert.IsTrue(reader.Read());
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual(@"hi
+bye", reader.Value);
+      Assert.IsTrue(reader.Read());
+      Assert.IsTrue(reader.Read());
+      Assert.IsFalse(reader.Read());
+    }
+
+    [Test]
+    public void ReadBytesFollowingNumberInArray()
+    {
+      string helloWorld = "Hello world!";
+      byte[] helloWorldData = Encoding.UTF8.GetBytes(helloWorld);
+
+      JsonReader reader = new JsonTextReader(new StringReader(@"[1,'" + Convert.ToBase64String(helloWorldData) + @"']"));
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Integer, reader.TokenType);
+      byte[] data = reader.ReadAsBytes();
+      Assert.AreEqual(helloWorldData, data);
+      Assert.AreEqual(JsonToken.Bytes, reader.TokenType);
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
+
+      Assert.IsFalse(reader.Read());
+    }
+
+    [Test]
+    public void ReadBytesFollowingNumberInObject()
+    {
+      string helloWorld = "Hello world!";
+      byte[] helloWorldData = Encoding.UTF8.GetBytes(helloWorld);
+
+      JsonReader reader = new JsonTextReader(new StringReader(@"{num:1,data:'" + Convert.ToBase64String(helloWorldData) + @"'}"));
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+      Assert.IsTrue(reader.Read());
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Integer, reader.TokenType);
+      Assert.IsTrue(reader.Read());
+      byte[] data = reader.ReadAsBytes();
+      Assert.AreEqual(helloWorldData, data);
+      Assert.AreEqual(JsonToken.Bytes, reader.TokenType);
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      Assert.IsFalse(reader.Read());
+    }
+
+    [Test]
+    public void ReadingEscapedStrings()
+    {
+      string input = "{value:'Purple\\r \\n monkey\\'s:\\tdishwasher'}";
+
+      StringReader sr = new StringReader(input);
+
+      using (JsonReader jsonReader = new JsonTextReader(sr))
+      {
+        Assert.AreEqual(0, jsonReader.Depth);
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.StartObject);
+        Assert.AreEqual(0, jsonReader.Depth);
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.PropertyName);
+        Assert.AreEqual(1, jsonReader.Depth);
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.String);
+        Assert.AreEqual(jsonReader.Value, "Purple\r \n monkey's:\tdishwasher");
+        Assert.AreEqual(jsonReader.QuoteChar, '\'');
+        Assert.AreEqual(1, jsonReader.Depth);
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.EndObject);
+        Assert.AreEqual(0, jsonReader.Depth);
+      }
+    }
+
+    [Test]
+    public void ReadNewlineLastCharacter()
+    {
+      string input = @"{
+  CPU: 'Intel',
+  Drives: [ /* Com*ment */
+    'DVD read/writer',
+    ""500 gigabyte hard drive""
+  ]
+}" + '\n';
+
+      object o = JsonConvert.DeserializeObject(input);
+    }
+
+    [Test]
+    public void WriteReadWrite()
+    {
+      StringBuilder sb = new StringBuilder();
+      StringWriter sw = new StringWriter(sb);
+
+      using (JsonWriter jsonWriter = new JsonTextWriter(sw))
+      {
+        jsonWriter.WriteStartArray();
+        jsonWriter.WriteValue(true);
+
+        jsonWriter.WriteStartObject();
+        jsonWriter.WritePropertyName("integer");
+        jsonWriter.WriteValue(99);
+        jsonWriter.WritePropertyName("string");
+        jsonWriter.WriteValue("how now brown cow?");
+        jsonWriter.WritePropertyName("array");
+
+        jsonWriter.WriteStartArray();
+        for (int i = 0; i < 5; i++)
+        {
+          jsonWriter.WriteValue(i);
+        }
+
+        jsonWriter.WriteStartObject();
+        jsonWriter.WritePropertyName("decimal");
+        jsonWriter.WriteValue(990.00990099m);
+        jsonWriter.WriteEndObject();
+
+        jsonWriter.WriteValue(5);
+        jsonWriter.WriteEndArray();
+
+        jsonWriter.WriteEndObject();
+
+        jsonWriter.WriteValue("This is a string.");
+        jsonWriter.WriteNull();
+        jsonWriter.WriteNull();
+        jsonWriter.WriteEndArray();
+      }
+
+      string json = sb.ToString();
+
+      JsonSerializer serializer = new JsonSerializer();
+
+      object jsonObject = serializer.Deserialize(new JsonTextReader(new StringReader(json)));
+
+      sb = new StringBuilder();
+      sw = new StringWriter(sb);
+
+      using (JsonWriter jsonWriter = new JsonTextWriter(sw))
+      {
+        serializer.Serialize(sw, jsonObject);
+      }
+
+      Assert.AreEqual(json, sb.ToString());
+    }
+
+    [Test]
+    public void FloatingPointNonFiniteNumbers()
+    {
+      string input = @"[
+  NaN,
+  Infinity,
+  -Infinity
+]";
+
+      StringReader sr = new StringReader(input);
+
+      using (JsonReader jsonReader = new JsonTextReader(sr))
+      {
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.StartArray);
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.Float);
+        Assert.AreEqual(jsonReader.Value, double.NaN);
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.Float);
+        Assert.AreEqual(jsonReader.Value, double.PositiveInfinity);
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.Float);
+        Assert.AreEqual(jsonReader.Value, double.NegativeInfinity);
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.EndArray);
+      }
+    }
+
+    [Test]
+    public void LongStringTest()
+    {
+      int length = 20000;
+      string json = @"[""" + new string(' ', length) + @"""]";
+
+      JsonTextReader reader = new JsonTextReader(new StringReader(json));
+
+      reader.Read();
+      Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
+
+      reader.Read();
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual(typeof(string), reader.ValueType);
+      Assert.AreEqual(20000, reader.Value.ToString().Length);
+
+      reader.Read();
+      Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
+
+      reader.Read();
+      Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
+    }
+
+    [Test]
+    public void EscapedUnicodeText()
+    {
+      string json = @"[""\u003c"",""\u5f20""]";
+
+      JsonTextReader reader = new JsonTextReader(new StringReader(json));
+
+      reader.Read();
+      Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
+
+      reader.Read();
+      Assert.AreEqual("<", reader.Value);
+
+      reader.Read();
+      Assert.AreEqual(24352, Convert.ToInt32(Convert.ToChar((string)reader.Value)));
+
+      reader.Read();
+      Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
+    }
+
+    [Test]
+    public void ReadFloatingPointNumber()
+    {
+      string json =
+        @"[0.0,0.0,0.1,1.0,1.000001,1E-06,4.94065645841247E-324,Infinity,-Infinity,NaN,1.7976931348623157E+308,-1.7976931348623157E+308,Infinity,-Infinity,NaN]";
+
+      using (JsonReader jsonReader = new JsonTextReader(new StringReader(json)))
+      {
+        jsonReader.Read();
+        Assert.AreEqual(JsonToken.StartArray, jsonReader.TokenType);
+
+        jsonReader.Read();
+        Assert.AreEqual(JsonToken.Float, jsonReader.TokenType);
+        Assert.AreEqual(0.0, jsonReader.Value);
+
+        jsonReader.Read();
+        Assert.AreEqual(JsonToken.Float, jsonReader.TokenType);
+        Assert.AreEqual(0.0, jsonReader.Value);
+
+        jsonReader.Read();
+        Assert.AreEqual(JsonToken.Float, jsonReader.TokenType);
+        Assert.AreEqual(0.1, jsonReader.Value);
+
+        jsonReader.Read();
+        Assert.AreEqual(JsonToken.Float, jsonReader.TokenType);
+        Assert.AreEqual(1.0, jsonReader.Value);
+
+        jsonReader.Read();
+        Assert.AreEqual(JsonToken.Float, jsonReader.TokenType);
+        Assert.AreEqual(1.000001, jsonReader.Value);
+
+        jsonReader.Read();
+        Assert.AreEqual(JsonToken.Float, jsonReader.TokenType);
+        Assert.AreEqual(1E-06, jsonReader.Value);
+
+        jsonReader.Read();
+        Assert.AreEqual(JsonToken.Float, jsonReader.TokenType);
+        Assert.AreEqual(4.94065645841247E-324, jsonReader.Value);
+
+        jsonReader.Read();
+        Assert.AreEqual(JsonToken.Float, jsonReader.TokenType);
+        Assert.AreEqual(double.PositiveInfinity, jsonReader.Value);
+
+        jsonReader.Read();
+        Assert.AreEqual(JsonToken.Float, jsonReader.TokenType);
+        Assert.AreEqual(double.NegativeInfinity, jsonReader.Value);
+
+        jsonReader.Read();
+        Assert.AreEqual(JsonToken.Float, jsonReader.TokenType);
+        Assert.AreEqual(double.NaN, jsonReader.Value);
+
+        jsonReader.Read();
+        Assert.AreEqual(JsonToken.Float, jsonReader.TokenType);
+        Assert.AreEqual(double.MaxValue, jsonReader.Value);
+
+        jsonReader.Read();
+        Assert.AreEqual(JsonToken.Float, jsonReader.TokenType);
+        Assert.AreEqual(double.MinValue, jsonReader.Value);
+
+        jsonReader.Read();
+        Assert.AreEqual(JsonToken.Float, jsonReader.TokenType);
+        Assert.AreEqual(double.PositiveInfinity, jsonReader.Value);
+
+        jsonReader.Read();
+        Assert.AreEqual(JsonToken.Float, jsonReader.TokenType);
+        Assert.AreEqual(double.NegativeInfinity, jsonReader.Value);
+
+        jsonReader.Read();
+        Assert.AreEqual(JsonToken.Float, jsonReader.TokenType);
+        Assert.AreEqual(double.NaN, jsonReader.Value);
+
+        jsonReader.Read();
+        Assert.AreEqual(JsonToken.EndArray, jsonReader.TokenType);
+      }
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonReaderException), ExpectedMessage = @"Invalid character after parsing property name. Expected ':' but got: "". Line 3, position 9.")]
+    public void MissingColon()
+    {
+      string json = @"{
+    ""A"" : true,
+    ""B"" ""hello"", // Notice the colon is missing
+    ""C"" : ""bye""
+}";
+
+      JsonTextReader reader = new JsonTextReader(new StringReader(json));
+
+      reader.Read();
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      reader.Read();
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+
+      reader.Read();
+      Assert.AreEqual(JsonToken.Boolean, reader.TokenType);
+
+      reader.Read();
+    }
+
+    [Test]
+    public void ReadSingleBytes()
+    {
+      StringReader s = new StringReader(@"""SGVsbG8gd29ybGQu""");
+      JsonTextReader reader = new JsonTextReader(s);
+
+      byte[] data = reader.ReadAsBytes();
+      Assert.IsNotNull(data);
+
+      string text = Encoding.UTF8.GetString(data, 0, data.Length);
+      Assert.AreEqual("Hello world.", text);
+    }
+
+    [Test]
+    public void ReadOctalNumber()
+    {
+      StringReader s = new StringReader(@"[0372, 0xFA, 0XFA]");
+      JsonTextReader jsonReader = new JsonTextReader(s);
+
+      Assert.IsTrue(jsonReader.Read());
+      Assert.AreEqual(JsonToken.StartArray, jsonReader.TokenType);
+
+      Assert.IsTrue(jsonReader.Read());
+      Assert.AreEqual(JsonToken.Integer, jsonReader.TokenType);
+      Assert.AreEqual(250, jsonReader.Value);
+
+      Assert.IsTrue(jsonReader.Read());
+      Assert.AreEqual(JsonToken.Integer, jsonReader.TokenType);
+      Assert.AreEqual(250, jsonReader.Value);
+
+      Assert.IsTrue(jsonReader.Read());
+      Assert.AreEqual(JsonToken.Integer, jsonReader.TokenType);
+      Assert.AreEqual(250, jsonReader.Value);
+
+      Assert.IsTrue(jsonReader.Read());
+      Assert.AreEqual(JsonToken.EndArray, jsonReader.TokenType);
+
+      Assert.IsFalse(jsonReader.Read());
+    }
+
+    [Test]
+    public void ReadUnicode()
+    {
+      string json = @"{""Message"":""Hi,I\u0092ve send you smth""}";
+
+      JsonTextReader reader = new JsonTextReader(new StringReader(json));
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("Message", reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual(@"Hi,I" + '\u0092' + "ve send you smth", reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      Assert.IsFalse(reader.Read());
+    }
+
+    [Test]
+    public void ReadHexidecimalWithAllLetters()
+    {
+      string json = @"{""text"":0xabcdef12345}";
+
+      JsonTextReader reader = new JsonTextReader(new StringReader(json));
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Integer, reader.TokenType);
+      Assert.AreEqual(11806310474565, reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+    }
+
+#if !NET20
+    [Test]
+    public void ReadAsDateTimeOffset()
+    {
+      string json = "{\"Offset\":\"\\/Date(946663200000+0600)\\/\"}";
+
+      JsonTextReader reader = new JsonTextReader(new StringReader(json));
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+
+      reader.ReadAsDateTimeOffset();
+      Assert.AreEqual(JsonToken.Date, reader.TokenType);
+      Assert.AreEqual(typeof(DateTimeOffset), reader.ValueType);
+      Assert.AreEqual(new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(6)), reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+    }
+
+    [Test]
+    public void ReadAsDateTimeOffsetNegative()
+    {
+      string json = @"{""Offset"":""\/Date(946706400000-0600)\/""}";
+
+      JsonTextReader reader = new JsonTextReader(new StringReader(json));
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+
+      reader.ReadAsDateTimeOffset();
+      Assert.AreEqual(JsonToken.Date, reader.TokenType);
+      Assert.AreEqual(typeof(DateTimeOffset), reader.ValueType);
+      Assert.AreEqual(new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(-6)), reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+    }
+
+    [Test]
+    public void ReadAsDateTimeOffsetHoursOnly()
+    {
+      string json = "{\"Offset\":\"\\/Date(946663200000+06)\\/\"}";
+
+      JsonTextReader reader = new JsonTextReader(new StringReader(json));
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+
+      reader.ReadAsDateTimeOffset();
+      Assert.AreEqual(JsonToken.Date, reader.TokenType);
+      Assert.AreEqual(typeof(DateTimeOffset), reader.ValueType);
+      Assert.AreEqual(new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(6)), reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+    }
+
+    [Test]
+    public void ReadAsDateTimeOffsetWithMinutes()
+    {
+      string json = @"{""Offset"":""\/Date(946708260000-0631)\/""}";
+
+      JsonTextReader reader = new JsonTextReader(new StringReader(json));
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+
+      reader.ReadAsDateTimeOffset();
+      Assert.AreEqual(JsonToken.Date, reader.TokenType);
+      Assert.AreEqual(typeof(DateTimeOffset), reader.ValueType);
+      Assert.AreEqual(new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(-6).Add(TimeSpan.FromMinutes(-31))), reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+    }
+#endif
+
+    [Test]
+    public void ReadAsDecimal()
+    {
+      string json = @"{""decimal"":-7.92281625142643E+28}";
+
+      JsonTextReader reader = new JsonTextReader(new StringReader(json));
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+
+      decimal? d = reader.ReadAsDecimal();
+      Assert.AreEqual(JsonToken.Float, reader.TokenType);
+      Assert.AreEqual(typeof(decimal), reader.ValueType);
+      Assert.AreEqual(-79228162514264300000000000000m, d);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs
new file mode 100644 (file)
index 0000000..1165400
--- /dev/null
@@ -0,0 +1,622 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using NUnit.Framework;
+using Newtonsoft.Json;
+using System.IO;
+
+namespace Newtonsoft.Json.Tests
+{
+  public class JsonTextWriterTest : TestFixtureBase
+  {
+    [Test]
+    public void CloseOutput()
+    {
+      MemoryStream ms = new MemoryStream();
+      JsonTextWriter writer = new JsonTextWriter(new StreamWriter(ms));
+
+      Assert.IsTrue(ms.CanRead);
+      writer.Close();
+      Assert.IsFalse(ms.CanRead);
+
+      ms = new MemoryStream();
+      writer = new JsonTextWriter(new StreamWriter(ms)) { CloseOutput = false };
+
+      Assert.IsTrue(ms.CanRead);
+      writer.Close();
+      Assert.IsTrue(ms.CanRead);
+    }
+    
+    [Test]
+    public void ValueFormatting()
+    {
+      StringBuilder sb = new StringBuilder();
+      StringWriter sw = new StringWriter(sb);
+
+      using (JsonWriter jsonWriter = new JsonTextWriter(sw))
+      {
+        jsonWriter.WriteStartArray();
+        jsonWriter.WriteValue('@');
+        jsonWriter.WriteValue("\r\n\t\f\b?{\\r\\n\"\'");
+        jsonWriter.WriteValue(true);
+        jsonWriter.WriteValue(10);
+        jsonWriter.WriteValue(10.99);
+        jsonWriter.WriteValue(0.99);
+        jsonWriter.WriteValue(0.000000000000000001d);
+        jsonWriter.WriteValue(0.000000000000000001m);
+        jsonWriter.WriteValue((string)null);
+        jsonWriter.WriteValue((object)null);
+        jsonWriter.WriteValue("This is a string.");
+        jsonWriter.WriteNull();
+        jsonWriter.WriteUndefined();
+        jsonWriter.WriteEndArray();
+      }
+
+      string expected = @"[""@"",""\r\n\t\f\b?{\\r\\n\""'"",true,10,10.99,0.99,1E-18,0.000000000000000001,null,null,""This is a string."",null,undefined]";
+      string result = sb.ToString();
+
+      Console.WriteLine("ValueFormatting");
+      Console.WriteLine(result);
+
+      Assert.AreEqual(expected, result);
+    }
+
+    [Test]
+    public void NullableValueFormatting()
+    {
+      StringWriter sw = new StringWriter();
+      using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
+      {
+        jsonWriter.WriteStartArray();
+        jsonWriter.WriteValue((char?)null);
+        jsonWriter.WriteValue((char?)'c');
+        jsonWriter.WriteValue((bool?)null);
+        jsonWriter.WriteValue((bool?)true);
+        jsonWriter.WriteValue((byte?)null);
+        jsonWriter.WriteValue((byte?)1);
+        jsonWriter.WriteValue((sbyte?)null);
+        jsonWriter.WriteValue((sbyte?)1);
+        jsonWriter.WriteValue((short?)null);
+        jsonWriter.WriteValue((short?)1);
+        jsonWriter.WriteValue((ushort?)null);
+        jsonWriter.WriteValue((ushort?)1);
+        jsonWriter.WriteValue((int?)null);
+        jsonWriter.WriteValue((int?)1);
+        jsonWriter.WriteValue((uint?)null);
+        jsonWriter.WriteValue((uint?)1);
+        jsonWriter.WriteValue((long?)null);
+        jsonWriter.WriteValue((long?)1);
+        jsonWriter.WriteValue((ulong?)null);
+        jsonWriter.WriteValue((ulong?)1);
+        jsonWriter.WriteValue((double?)null);
+        jsonWriter.WriteValue((double?)1.1);
+        jsonWriter.WriteValue((float?)null);
+        jsonWriter.WriteValue((float?)1.1);
+        jsonWriter.WriteValue((decimal?)null);
+        jsonWriter.WriteValue((decimal?)1.1m);
+        jsonWriter.WriteValue((DateTime?)null);
+        jsonWriter.WriteValue((DateTime?)new DateTime(JsonConvert.InitialJavaScriptDateTicks, DateTimeKind.Utc));
+#if !PocketPC && !NET20
+        jsonWriter.WriteValue((DateTimeOffset?)null);
+        jsonWriter.WriteValue((DateTimeOffset?)new DateTimeOffset(JsonConvert.InitialJavaScriptDateTicks, TimeSpan.Zero));
+#endif
+        jsonWriter.WriteEndArray();
+      }
+
+      string json = sw.ToString();
+      string expected;
+
+#if !PocketPC && !NET20
+      expected = @"[null,""c"",null,true,null,1,null,1,null,1,null,1,null,1,null,1,null,1,null,1,null,1.1,null,1.1,null,1.1,null,""\/Date(0)\/"",null,""\/Date(0+0000)\/""]";
+#else
+      expected = @"[null,""c"",null,true,null,1,null,1,null,1,null,1,null,1,null,1,null,1,null,1,null,1.1,null,1.1,null,1.1,null,""\/Date(0)\/""]";
+#endif
+
+      Assert.AreEqual(expected, json);
+    }
+
+    [Test]
+    public void WriteValueObjectWithNullable()
+    {
+      StringWriter sw = new StringWriter();
+      using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
+      {
+        char? value = 'c';
+
+        jsonWriter.WriteStartArray();
+        jsonWriter.WriteValue((object)value);
+        jsonWriter.WriteEndArray();
+      }
+
+      string json = sw.ToString();
+      string expected = @"[""c""]";
+
+      Assert.AreEqual(expected, json);
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentException), ExpectedMessage = @"Unsupported type: System.Version. Use the JsonSerializer class to get the object's JSON representation.")]
+    public void WriteValueObjectWithUnsupportedValue()
+    {
+      StringWriter sw = new StringWriter();
+      using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
+      {
+        jsonWriter.WriteStartArray();
+        jsonWriter.WriteValue(new Version(1, 1, 1, 1));
+        jsonWriter.WriteEndArray();
+      }
+    }
+
+    [Test]
+    public void StringEscaping()
+    {
+      StringBuilder sb = new StringBuilder();
+      StringWriter sw = new StringWriter(sb);
+
+      using (JsonWriter jsonWriter = new JsonTextWriter(sw))
+      {
+        jsonWriter.WriteStartArray();
+        jsonWriter.WriteValue(@"""These pretzels are making me thirsty!""");
+        jsonWriter.WriteValue("Jeff's house was burninated.");
+        jsonWriter.WriteValue(@"1. You don't talk about fight club.
+2. You don't talk about fight club.");
+        jsonWriter.WriteValue("35% of\t statistics\n are made\r up.");
+        jsonWriter.WriteEndArray();
+      }
+
+      string expected = @"[""\""These pretzels are making me thirsty!\"""",""Jeff's house was burninated."",""1. You don't talk about fight club.\r\n2. You don't talk about fight club."",""35% of\t statistics\n are made\r up.""]";
+      string result = sb.ToString();
+
+      Console.WriteLine("StringEscaping");
+      Console.WriteLine(result);
+
+      Assert.AreEqual(expected, result);
+    }
+
+    [Test]
+    public void Indenting()
+    {
+      StringBuilder sb = new StringBuilder();
+      StringWriter sw = new StringWriter(sb);
+
+      using (JsonWriter jsonWriter = new JsonTextWriter(sw))
+      {
+        jsonWriter.Formatting = Formatting.Indented;
+
+        jsonWriter.WriteStartObject();
+        jsonWriter.WritePropertyName("CPU");
+        jsonWriter.WriteValue("Intel");
+        jsonWriter.WritePropertyName("PSU");
+        jsonWriter.WriteValue("500W");
+        jsonWriter.WritePropertyName("Drives");
+        jsonWriter.WriteStartArray();
+        jsonWriter.WriteValue("DVD read/writer");
+        jsonWriter.WriteComment("(broken)");
+        jsonWriter.WriteValue("500 gigabyte hard drive");
+        jsonWriter.WriteValue("200 gigabype hard drive");
+        jsonWriter.WriteEnd();
+        jsonWriter.WriteEndObject();
+      }
+
+      // {
+      //   "CPU": "Intel",
+      //   "PSU": "500W",
+      //   "Drives": [
+      //     "DVD read/writer"
+      //     /*(broken)*/,
+      //     "500 gigabyte hard drive",
+      //     "200 gigabype hard drive"
+      //   ]
+      // }
+
+      string expected = @"{
+  ""CPU"": ""Intel"",
+  ""PSU"": ""500W"",
+  ""Drives"": [
+    ""DVD read/writer""
+    /*(broken)*/,
+    ""500 gigabyte hard drive"",
+    ""200 gigabype hard drive""
+  ]
+}";
+      string result = sb.ToString();
+
+      Console.WriteLine("Indenting");
+      Console.WriteLine(result);
+
+      Assert.AreEqual(expected, result);
+    }
+
+    [Test]
+    public void State()
+    {
+      StringBuilder sb = new StringBuilder();
+      StringWriter sw = new StringWriter(sb);
+
+      using (JsonWriter jsonWriter = new JsonTextWriter(sw))
+      {
+        Assert.AreEqual(WriteState.Start, jsonWriter.WriteState);
+
+        jsonWriter.WriteStartObject();
+        Assert.AreEqual(WriteState.Object, jsonWriter.WriteState);
+
+        jsonWriter.WritePropertyName("CPU");
+        Assert.AreEqual(WriteState.Property, jsonWriter.WriteState);
+
+        jsonWriter.WriteValue("Intel");
+        Assert.AreEqual(WriteState.Object, jsonWriter.WriteState);
+
+        jsonWriter.WritePropertyName("Drives");
+        Assert.AreEqual(WriteState.Property, jsonWriter.WriteState);
+
+        jsonWriter.WriteStartArray();
+        Assert.AreEqual(WriteState.Array, jsonWriter.WriteState);
+
+        jsonWriter.WriteValue("DVD read/writer");
+        Assert.AreEqual(WriteState.Array, jsonWriter.WriteState);
+
+        jsonWriter.WriteEnd();
+        Assert.AreEqual(WriteState.Object, jsonWriter.WriteState);
+
+        jsonWriter.WriteEndObject();
+        Assert.AreEqual(WriteState.Start, jsonWriter.WriteState);
+      }
+    }
+
+    [Test]
+    public void FloatingPointNonFiniteNumbers()
+    {
+      StringBuilder sb = new StringBuilder();
+      StringWriter sw = new StringWriter(sb);
+
+      using (JsonWriter jsonWriter = new JsonTextWriter(sw))
+      {
+        jsonWriter.Formatting = Formatting.Indented;
+
+        jsonWriter.WriteStartArray();
+        jsonWriter.WriteValue(double.NaN);
+        jsonWriter.WriteValue(double.PositiveInfinity);
+        jsonWriter.WriteValue(double.NegativeInfinity);
+        jsonWriter.WriteValue(float.NaN);
+        jsonWriter.WriteValue(float.PositiveInfinity);
+        jsonWriter.WriteValue(float.NegativeInfinity);
+        jsonWriter.WriteEndArray();
+
+        jsonWriter.Flush();
+      }
+
+      string expected = @"[
+  NaN,
+  Infinity,
+  -Infinity,
+  NaN,
+  Infinity,
+  -Infinity
+]";
+      string result = sb.ToString();
+
+      Assert.AreEqual(expected, result);
+    }
+
+    [Test]
+    public void WriteRawInStart()
+    {
+      StringBuilder sb = new StringBuilder();
+      StringWriter sw = new StringWriter(sb);
+
+      using (JsonWriter jsonWriter = new JsonTextWriter(sw))
+      {
+        jsonWriter.Formatting = Formatting.Indented;
+
+        jsonWriter.WriteRaw("[1,2,3,4,5]");
+        jsonWriter.WriteWhitespace("  ");
+        jsonWriter.WriteStartArray();
+        jsonWriter.WriteValue(double.NaN);
+        jsonWriter.WriteEndArray();
+      }
+
+      string expected = @"[1,2,3,4,5]  [
+  NaN
+]";
+      string result = sb.ToString();
+
+      Assert.AreEqual(expected, result);
+    }
+
+    [Test]
+    public void WriteRawInArray()
+    {
+      StringBuilder sb = new StringBuilder();
+      StringWriter sw = new StringWriter(sb);
+
+      using (JsonWriter jsonWriter = new JsonTextWriter(sw))
+      {
+        jsonWriter.Formatting = Formatting.Indented;
+
+        jsonWriter.WriteStartArray();
+        jsonWriter.WriteValue(double.NaN);
+        jsonWriter.WriteRaw(",[1,2,3,4,5]");
+        jsonWriter.WriteRaw(",[1,2,3,4,5]");
+        jsonWriter.WriteValue(float.NaN);
+        jsonWriter.WriteEndArray();
+      }
+
+      string expected = @"[
+  NaN,[1,2,3,4,5],[1,2,3,4,5],
+  NaN
+]";
+      string result = sb.ToString();
+
+      Assert.AreEqual(expected, result);
+    }
+
+    [Test]
+    public void WriteRawInObject()
+    {
+      StringBuilder sb = new StringBuilder();
+      StringWriter sw = new StringWriter(sb);
+
+      using (JsonWriter jsonWriter = new JsonTextWriter(sw))
+      {
+        jsonWriter.Formatting = Formatting.Indented;
+
+        jsonWriter.WriteStartObject();
+        jsonWriter.WriteRaw(@"""PropertyName"":[1,2,3,4,5]");
+        jsonWriter.WriteEnd();
+      }
+
+      string expected = @"{""PropertyName"":[1,2,3,4,5]}";
+      string result = sb.ToString();
+
+      Assert.AreEqual(expected, result);
+    }
+
+    [Test]
+    public void WriteToken()
+    {
+      JsonTextReader reader = new JsonTextReader(new StringReader("[1,2,3,4,5]"));
+      reader.Read();
+      reader.Read();
+
+      StringWriter sw = new StringWriter();
+      JsonTextWriter writer = new JsonTextWriter(sw);
+      writer.WriteToken(reader);
+
+      Assert.AreEqual("1", sw.ToString());
+    }
+
+    [Test]
+    public void WriteRawValue()
+    {
+      StringBuilder sb = new StringBuilder();
+      StringWriter sw = new StringWriter(sb);
+
+      using (JsonWriter jsonWriter = new JsonTextWriter(sw))
+      {
+        int i = 0;
+        string rawJson = "[1,2]";
+
+        jsonWriter.WriteStartObject();
+
+        while (i < 3)
+        {
+          jsonWriter.WritePropertyName("d" + i);
+          jsonWriter.WriteRawValue(rawJson);
+
+          i++;
+        }
+
+        jsonWriter.WriteEndObject();
+      }
+
+      Assert.AreEqual(@"{""d0"":[1,2],""d1"":[1,2],""d2"":[1,2]}", sb.ToString());
+    }
+
+    [Test]
+    public void WriteObjectNestedInConstructor()
+    {
+      StringBuilder sb = new StringBuilder();
+      StringWriter sw = new StringWriter(sb);
+
+      using (JsonWriter jsonWriter = new JsonTextWriter(sw))
+      {
+        jsonWriter.WriteStartObject();
+        jsonWriter.WritePropertyName("con");
+
+        jsonWriter.WriteStartConstructor("Ext.data.JsonStore");
+        jsonWriter.WriteStartObject();
+        jsonWriter.WritePropertyName("aa");
+        jsonWriter.WriteValue("aa");
+        jsonWriter.WriteEndObject();
+        jsonWriter.WriteEndConstructor();
+
+        jsonWriter.WriteEndObject();
+      }
+
+      Assert.AreEqual(@"{""con"":new Ext.data.JsonStore({""aa"":""aa""})}", sb.ToString());
+    }
+
+    [Test]
+    public void WriteFloatingPointNumber()
+    {
+      StringBuilder sb = new StringBuilder();
+      StringWriter sw = new StringWriter(sb);
+
+      using (JsonWriter jsonWriter = new JsonTextWriter(sw))
+      {
+        jsonWriter.WriteStartArray();
+
+        jsonWriter.WriteValue(0.0);
+        jsonWriter.WriteValue(0f);
+        jsonWriter.WriteValue(0.1);
+        jsonWriter.WriteValue(1.0);
+        jsonWriter.WriteValue(1.000001);
+        jsonWriter.WriteValue(0.000001);
+        jsonWriter.WriteValue(double.Epsilon);
+        jsonWriter.WriteValue(double.PositiveInfinity);
+        jsonWriter.WriteValue(double.NegativeInfinity);
+        jsonWriter.WriteValue(double.NaN);
+        jsonWriter.WriteValue(double.MaxValue);
+        jsonWriter.WriteValue(double.MinValue);
+        jsonWriter.WriteValue(float.PositiveInfinity);
+        jsonWriter.WriteValue(float.NegativeInfinity);
+        jsonWriter.WriteValue(float.NaN);
+
+        jsonWriter.WriteEndArray();
+      }
+
+      Assert.AreEqual(@"[0.0,0.0,0.1,1.0,1.000001,1E-06,4.94065645841247E-324,Infinity,-Infinity,NaN,1.7976931348623157E+308,-1.7976931348623157E+308,Infinity,-Infinity,NaN]", sb.ToString());
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonWriterException), ExpectedMessage = "No token to close.")]
+    public void BadWriteEndArray()
+    {
+      StringBuilder sb = new StringBuilder();
+      StringWriter sw = new StringWriter(sb);
+
+      using (JsonWriter jsonWriter = new JsonTextWriter(sw))
+      {
+        jsonWriter.WriteStartArray();
+
+        jsonWriter.WriteValue(0.0);
+
+        jsonWriter.WriteEndArray();
+        jsonWriter.WriteEndArray();
+      }
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentException), ExpectedMessage = @"Invalid JavaScript string quote character. Valid quote characters are ' and "".")]
+    public void InvalidQuoteChar()
+    {
+      StringBuilder sb = new StringBuilder();
+      StringWriter sw = new StringWriter(sb);
+
+      using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
+      {
+        jsonWriter.Formatting = Formatting.Indented;
+        jsonWriter.QuoteChar = '*';
+      }
+    }
+
+    [Test]
+    public void Indentation()
+    {
+      StringBuilder sb = new StringBuilder();
+      StringWriter sw = new StringWriter(sb);
+
+      using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
+      {
+        jsonWriter.Formatting = Formatting.Indented;
+        Assert.AreEqual(Formatting.Indented, jsonWriter.Formatting);
+
+        jsonWriter.Indentation = 5;
+        Assert.AreEqual(5, jsonWriter.Indentation);
+        jsonWriter.IndentChar = '_';
+        Assert.AreEqual('_', jsonWriter.IndentChar);
+        jsonWriter.QuoteName = true;
+        Assert.AreEqual(true, jsonWriter.QuoteName);
+        jsonWriter.QuoteChar = '\'';
+        Assert.AreEqual('\'', jsonWriter.QuoteChar);
+
+        jsonWriter.WriteStartObject();
+        jsonWriter.WritePropertyName("propertyName");
+        jsonWriter.WriteValue(double.NaN);
+        jsonWriter.WriteEndObject();
+      }
+
+      string expected = @"{
+_____'propertyName': NaN
+}";
+      string result = sb.ToString();
+
+      Assert.AreEqual(expected, result);
+    }
+
+    [Test]
+    public void WriteSingleBytes()
+    {
+      StringBuilder sb = new StringBuilder();
+      StringWriter sw = new StringWriter(sb);
+
+      string text = "Hello world.";
+      byte[] data = Encoding.UTF8.GetBytes(text);
+
+      using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
+      {
+        jsonWriter.Formatting = Formatting.Indented;
+        Assert.AreEqual(Formatting.Indented, jsonWriter.Formatting);
+
+        jsonWriter.WriteValue(data);
+      }
+
+      string expected = @"""SGVsbG8gd29ybGQu""";
+      string result = sb.ToString();
+
+      Assert.AreEqual(expected, result);
+
+      byte[] d2 = Convert.FromBase64String(result.Trim('"'));
+
+      Assert.AreEqual(text, Encoding.UTF8.GetString(d2, 0, d2.Length));
+    }
+
+    [Test]
+    public void WriteBytesInArray()
+    {
+      StringBuilder sb = new StringBuilder();
+      StringWriter sw = new StringWriter(sb);
+
+      string text = "Hello world.";
+      byte[] data = Encoding.UTF8.GetBytes(text);
+
+      using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
+      {
+        jsonWriter.Formatting = Formatting.Indented;
+        Assert.AreEqual(Formatting.Indented, jsonWriter.Formatting);
+
+        jsonWriter.WriteStartArray();
+        jsonWriter.WriteValue(data);
+        jsonWriter.WriteValue(data);
+        jsonWriter.WriteValue((object)data);
+        jsonWriter.WriteValue((byte[])null);
+        jsonWriter.WriteEndArray();
+      }
+
+      string expected = @"[
+  ""SGVsbG8gd29ybGQu"",
+  ""SGVsbG8gd29ybGQu"",
+  ""SGVsbG8gd29ybGQu"",
+  null
+]";
+      string result = sb.ToString();
+
+      Assert.AreEqual(expected, result);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/JsonValidatingReaderTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/JsonValidatingReaderTests.cs
new file mode 100644 (file)
index 0000000..c8ce1d9
--- /dev/null
@@ -0,0 +1,1213 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using System.Xml;
+using System.Xml.Schema;
+using Newtonsoft.Json.Schema;
+
+namespace Newtonsoft.Json.Tests
+{
+  public class JsonValidatingReaderTests : TestFixtureBase
+  {
+    [Test]
+    public void CheckInnerReader()
+    {
+      string json = "{'name':'James','hobbies':['pie','cake']}";
+      JsonReader reader = new JsonTextReader(new StringReader(json));
+
+      JsonValidatingReader validatingReader = new JsonValidatingReader(reader);
+      Assert.AreEqual(reader, validatingReader.Reader);
+    }
+
+    [Test]
+    public void ValidateTypes()
+    {
+      string schemaJson = @"{
+  ""description"":""A person"",
+  ""type"":""object"",
+  ""properties"":
+  {
+    ""name"":{""type"":""string""},
+    ""hobbies"":
+    {
+      ""type"":""array"",
+      ""items"": {""type"":""string""}
+    }
+  }
+}";
+
+      string json = @"{'name':""James"",'hobbies':[""pie"",'cake']}";
+
+      Json.Schema.ValidationEventArgs validationEventArgs = null;
+
+      JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
+      reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
+      JsonSchema schema = JsonSchema.Parse(schemaJson);
+      reader.Schema = schema;
+      Assert.AreEqual(schema, reader.Schema);
+
+      Assert.AreEqual(0, reader.Depth);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("name", reader.Value.ToString());
+
+      Assert.AreEqual(1, reader.Depth);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("James", reader.Value.ToString());
+      Assert.AreEqual(typeof(string), reader.ValueType);
+      Assert.AreEqual('"', reader.QuoteChar);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("hobbies", reader.Value.ToString());
+      Assert.AreEqual('\'', reader.QuoteChar);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("pie", reader.Value.ToString());
+      Assert.AreEqual('"', reader.QuoteChar);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("cake", reader.Value.ToString());
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      Assert.IsNull(validationEventArgs);
+    }
+
+    [Test]
+    public void ValidateUnrestrictedArray()
+    {
+      string schemaJson = @"{
+  ""type"":""array""
+}";
+
+      string json = "['pie','cake',['nested1','nested2'],{'nestedproperty1':1.1,'nestedproperty2':[null]}]";
+
+      Json.Schema.ValidationEventArgs validationEventArgs = null;
+
+      JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
+      reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
+      reader.Schema = JsonSchema.Parse(schemaJson);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("pie", reader.Value.ToString());
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("cake", reader.Value.ToString());
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("nested1", reader.Value.ToString());
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("nested2", reader.Value.ToString());
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("nestedproperty1", reader.Value.ToString());
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Float, reader.TokenType);
+      Assert.AreEqual(1.1, reader.Value);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("nestedproperty2", reader.Value.ToString());
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Null, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
+
+      Assert.IsNull(validationEventArgs);
+    }
+
+    [Test]
+    public void StringLessThanMinimumLength()
+    {
+      string schemaJson = @"{
+  ""type"":""string"",
+  ""minLength"":5,
+  ""maxLength"":50,
+}";
+
+      string json = "'pie'";
+
+      Json.Schema.ValidationEventArgs validationEventArgs = null;
+
+      JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
+      reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
+      reader.Schema = JsonSchema.Parse(schemaJson);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("String 'pie' is less than minimum length of 5. Line 1, position 5.", validationEventArgs.Message);
+
+      Assert.IsNotNull(validationEventArgs);
+    }
+
+    [Test]
+    public void StringGreaterThanMaximumLength()
+    {
+      string schemaJson = @"{
+  ""type"":""string"",
+  ""minLength"":5,
+  ""maxLength"":10
+}";
+
+      string json = "'The quick brown fox jumps over the lazy dog.'";
+
+      Json.Schema.ValidationEventArgs validationEventArgs = null;
+
+      JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
+      reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
+      reader.Schema = JsonSchema.Parse(schemaJson);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("String 'The quick brown fox jumps over the lazy dog.' exceeds maximum length of 10. Line 1, position 46.", validationEventArgs.Message);
+
+      Assert.IsNotNull(validationEventArgs);
+    }
+
+    [Test]
+    public void StringIsNotInEnum()
+    {
+      string schemaJson = @"{
+  ""type"":""array"",
+  ""items"":{
+    ""type"":""string"",
+    ""enum"":[""one"",""two""]
+  },
+  ""maxItems"":3
+}";
+
+      string json = "['one','two','THREE']";
+
+      Json.Schema.ValidationEventArgs validationEventArgs = null;
+
+      JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
+      reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
+      reader.Schema = JsonSchema.Parse(schemaJson);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual(null, validationEventArgs);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual(@"Value ""THREE"" is not defined in enum. Line 1, position 20.", validationEventArgs.Message);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
+
+      Assert.IsNotNull(validationEventArgs);
+    }
+
+    [Test]
+    public void StringDoesNotMatchPattern()
+    {
+      string schemaJson = @"{
+  ""type"":""string"",
+  ""pattern"":""foo""
+}";
+
+      string json = "'The quick brown fox jumps over the lazy dog.'";
+
+      Json.Schema.ValidationEventArgs validationEventArgs = null;
+
+      JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
+      reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
+      reader.Schema = JsonSchema.Parse(schemaJson);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("String 'The quick brown fox jumps over the lazy dog.' does not match regex pattern 'foo'. Line 1, position 46.", validationEventArgs.Message);
+
+      Assert.IsNotNull(validationEventArgs);
+    }
+
+    [Test]
+    public void IntegerGreaterThanMaximumValue()
+    {
+      string schemaJson = @"{
+  ""type"":""integer"",
+  ""maximum"":5
+}";
+
+      string json = "10";
+
+      Json.Schema.ValidationEventArgs validationEventArgs = null;
+
+      JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
+      reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
+      reader.Schema = JsonSchema.Parse(schemaJson);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Integer, reader.TokenType);
+      Assert.AreEqual("Integer 10 exceeds maximum value of 5. Line 1, position 2.", validationEventArgs.Message);
+
+      Assert.IsNotNull(validationEventArgs);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSchemaException), ExpectedMessage = "Integer 10 exceeds maximum value of 5. Line 1, position 2.")]
+    public void ThrowExceptionWhenNoValidationEventHandler()
+    {
+      string schemaJson = @"{
+  ""type"":""integer"",
+  ""maximum"":5
+}";
+
+      JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader("10")));
+      reader.Schema = JsonSchema.Parse(schemaJson);
+
+      Assert.IsTrue(reader.Read());
+    }
+
+    [Test]
+    public void IntegerLessThanMinimumValue()
+    {
+      string schemaJson = @"{
+  ""type"":""integer"",
+  ""minimum"":5
+}";
+
+      string json = "1";
+
+      Json.Schema.ValidationEventArgs validationEventArgs = null;
+
+      JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
+      reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
+      reader.Schema = JsonSchema.Parse(schemaJson);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Integer, reader.TokenType);
+      Assert.AreEqual("Integer 1 is less than minimum value of 5. Line 1, position 1.", validationEventArgs.Message);
+
+      Assert.IsNotNull(validationEventArgs);
+    }
+
+    [Test]
+    public void IntegerIsNotInEnum()
+    {
+      string schemaJson = @"{
+  ""type"":""array"",
+  ""items"":{
+    ""type"":""integer"",
+    ""enum"":[1,2]
+  },
+  ""maxItems"":3
+}";
+
+      string json = "[1,2,3]";
+
+      Json.Schema.ValidationEventArgs validationEventArgs = null;
+
+      JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
+      reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
+      reader.Schema = JsonSchema.Parse(schemaJson);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Integer, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Integer, reader.TokenType);
+      Assert.AreEqual(null, validationEventArgs);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Integer, reader.TokenType);
+      Assert.AreEqual(@"Value 3 is not defined in enum. Line 1, position 7.", validationEventArgs.Message);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
+
+      Assert.IsNotNull(validationEventArgs);
+    }
+
+    [Test]
+    public void FloatGreaterThanMaximumValue()
+    {
+      string schemaJson = @"{
+  ""type"":""number"",
+  ""maximum"":5
+}";
+
+      string json = "10.0";
+
+      Json.Schema.ValidationEventArgs validationEventArgs = null;
+
+      JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
+      reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
+      reader.Schema = JsonSchema.Parse(schemaJson);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Float, reader.TokenType);
+      Assert.AreEqual("Float 10.0 exceeds maximum value of 5. Line 1, position 4.", validationEventArgs.Message);
+
+      Assert.IsNotNull(validationEventArgs);
+    }
+
+    [Test]
+    public void FloatLessThanMinimumValue()
+    {
+      string schemaJson = @"{
+  ""type"":""number"",
+  ""minimum"":5
+}";
+
+      string json = "1.1";
+
+      Json.Schema.ValidationEventArgs validationEventArgs = null;
+
+      JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
+      reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
+      reader.Schema = JsonSchema.Parse(schemaJson);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Float, reader.TokenType);
+      Assert.AreEqual("Float 1.1 is less than minimum value of 5. Line 1, position 3.", validationEventArgs.Message);
+
+      Assert.IsNotNull(validationEventArgs);
+    }
+
+    [Test]
+    public void FloatIsNotInEnum()
+    {
+      string schemaJson = @"{
+  ""type"":""array"",
+  ""items"":{
+    ""type"":""number"",
+    ""enum"":[1.1,2.2]
+  },
+  ""maxItems"":3
+}";
+
+      string json = "[1.1,2.2,3.0]";
+
+      Json.Schema.ValidationEventArgs validationEventArgs = null;
+
+      JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
+      reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
+      reader.Schema = JsonSchema.Parse(schemaJson);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Float, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Float, reader.TokenType);
+      Assert.AreEqual(null, validationEventArgs);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Float, reader.TokenType);
+      Assert.AreEqual(@"Value 3.0 is not defined in enum. Line 1, position 13.", validationEventArgs.Message);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
+
+      Assert.IsNotNull(validationEventArgs);
+    }
+
+    [Test]
+    public void FloatExceedsMaxDecimalPlaces()
+    {
+      string schemaJson = @"{
+  ""type"":""array"",
+  ""items"":{
+    ""type"":""number"",
+    ""divisibleBy"":0.1
+  }
+}";
+
+      string json = "[1.1,2.2,4.001]";
+
+      Json.Schema.ValidationEventArgs validationEventArgs = null;
+
+      JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
+      reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
+      reader.Schema = JsonSchema.Parse(schemaJson);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Float, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Float, reader.TokenType);
+      Assert.AreEqual(null, validationEventArgs);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Float, reader.TokenType);
+      Assert.AreEqual(@"Float 4.001 is not evenly divisible by 0.1. Line 1, position 15.", validationEventArgs.Message);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
+
+      Assert.IsNotNull(validationEventArgs);
+    }
+
+    [Test]
+    public void NullNotInEnum()
+    {
+      string schemaJson = @"{
+  ""type"":""array"",
+  ""items"":{
+    ""type"":""null"",
+    ""enum"":[]
+  },
+  ""maxItems"":3
+}";
+
+      string json = "[null]";
+
+      Json.Schema.ValidationEventArgs validationEventArgs = null;
+
+      JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
+      reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
+      reader.Schema = JsonSchema.Parse(schemaJson);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Null, reader.TokenType);
+      Assert.AreEqual(@"Value null is not defined in enum. Line 1, position 5.", validationEventArgs.Message);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
+
+      Assert.IsNotNull(validationEventArgs);
+    }
+
+    [Test]
+    public void BooleanNotInEnum()
+    {
+      string schemaJson = @"{
+  ""type"":""array"",
+  ""items"":{
+    ""type"":""boolean"",
+    ""enum"":[true]
+  },
+  ""maxItems"":3
+}";
+
+      string json = "[true,false]";
+
+      Json.Schema.ValidationEventArgs validationEventArgs = null;
+
+      JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
+      reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
+      reader.Schema = JsonSchema.Parse(schemaJson);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Boolean, reader.TokenType);
+      Assert.AreEqual(null, validationEventArgs);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Boolean, reader.TokenType);
+      Assert.AreEqual(@"Value false is not defined in enum. Line 1, position 11.", validationEventArgs.Message);
+      
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
+
+      Assert.IsNotNull(validationEventArgs);
+    }
+    
+    [Test]
+    public void ArrayCountGreaterThanMaximumItems()
+    {
+      string schemaJson = @"{
+  ""type"":""array"",
+  ""minItems"":2,
+  ""maxItems"":3
+}";
+
+      string json = "[null,null,null,null]";
+
+      Json.Schema.ValidationEventArgs validationEventArgs = null;
+
+      JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
+      reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
+      reader.Schema = JsonSchema.Parse(schemaJson);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Null, reader.TokenType);
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Null, reader.TokenType);
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Null, reader.TokenType);
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Null, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
+      Assert.AreEqual("Array item count 4 exceeds maximum count of 3. Line 1, position 21.", validationEventArgs.Message);
+
+      Assert.IsNotNull(validationEventArgs);
+    }
+
+    [Test]
+    public void ArrayCountLessThanMinimumItems()
+    {
+      string schemaJson = @"{
+  ""type"":""array"",
+  ""minItems"":2,
+  ""maxItems"":3
+}";
+
+      string json = "[null]";
+
+      Json.Schema.ValidationEventArgs validationEventArgs = null;
+
+      JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
+      reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
+      reader.Schema = JsonSchema.Parse(schemaJson);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Null, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
+      Assert.AreEqual("Array item count 1 is less than minimum count of 2. Line 1, position 6.", validationEventArgs.Message);
+
+      Assert.IsNotNull(validationEventArgs);
+    }
+
+    [Test]
+    public void InvalidDataType()
+    {
+      string schemaJson = @"{
+  ""type"":""string"",
+  ""minItems"":2,
+  ""maxItems"":3,
+  ""items"":{}
+}";
+
+      string json = "[null,null,null,null]";
+
+      Json.Schema.ValidationEventArgs validationEventArgs = null;
+
+      JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
+      reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
+      reader.Schema = JsonSchema.Parse(schemaJson);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
+      Assert.AreEqual(@"Invalid type. Expected String but got Array. Line 1, position 1.", validationEventArgs.Message);
+
+      Assert.IsNotNull(validationEventArgs);
+    }
+
+    [Test]
+    public void StringDisallowed()
+    {
+      string schemaJson = @"{
+  ""type"":""array"",
+  ""items"":{
+    ""disallow"":[""number""]
+  },
+  ""maxItems"":3
+}";
+
+      string json = "['pie',1.1]";
+
+      Json.Schema.ValidationEventArgs validationEventArgs = null;
+
+      JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
+      reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
+      reader.Schema = JsonSchema.Parse(schemaJson);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual(null, validationEventArgs);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Float, reader.TokenType);
+      Assert.AreEqual(@"Type Float is disallowed. Line 1, position 11.", validationEventArgs.Message);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
+
+      Assert.IsNotNull(validationEventArgs);
+    }
+
+    [Test]
+    public void MissingRequiredProperties()
+    {
+      string schemaJson = @"{
+  ""description"":""A person"",
+  ""type"":""object"",
+  ""properties"":
+  {
+    ""name"":{""type"":""string""},
+    ""hobbies"":{""type"":""string"",""required"":true},
+    ""age"":{""type"":""integer"",""required"":true}
+  }
+}";
+
+      string json = "{'name':'James'}";
+
+      Json.Schema.ValidationEventArgs validationEventArgs = null;
+
+      JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
+      reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
+      reader.Schema = JsonSchema.Parse(schemaJson);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("name", reader.Value.ToString());
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("James", reader.Value.ToString());
+      Assert.AreEqual(null, validationEventArgs);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+      Assert.AreEqual("Required properties are missing from object: hobbies, age. Line 1, position 16.", validationEventArgs.Message);
+
+      Assert.IsNotNull(validationEventArgs);
+    }
+
+    [Test]
+    public void MissingNonRequiredProperties()
+    {
+      string schemaJson = @"{
+  ""description"":""A person"",
+  ""type"":""object"",
+  ""properties"":
+  {
+    ""name"":{""type"":""string"",""required"":true},
+    ""hobbies"":{""type"":""string"",""required"":false},
+    ""age"":{""type"":""integer""}
+  }
+}";
+
+      string json = "{'name':'James'}";
+
+      Json.Schema.ValidationEventArgs validationEventArgs = null;
+
+      JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
+      reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
+      reader.Schema = JsonSchema.Parse(schemaJson);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("name", reader.Value.ToString());
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("James", reader.Value.ToString());
+      Assert.IsNull(validationEventArgs);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      Assert.IsNull(validationEventArgs);
+    }
+
+    [Test]
+    public void DisableAdditionalProperties()
+    {
+      string schemaJson = @"{
+  ""description"":""A person"",
+  ""type"":""object"",
+  ""properties"":
+  {
+    ""name"":{""type"":""string""}
+  },
+  ""additionalProperties"":false
+}";
+
+      string json = "{'name':'James','additionalProperty1':null,'additionalProperty2':null}";
+
+      Json.Schema.ValidationEventArgs validationEventArgs = null;
+
+      JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
+      reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
+      reader.Schema = JsonSchema.Parse(schemaJson);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("name", reader.Value.ToString());
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("James", reader.Value.ToString());
+      Assert.AreEqual(null, validationEventArgs);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("additionalProperty1", reader.Value.ToString());
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Null, reader.TokenType);
+      Assert.AreEqual(null, reader.Value);
+      Assert.AreEqual("Property 'additionalProperty1' has not been defined and the schema does not allow additional properties. Line 1, position 38.", validationEventArgs.Message);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("additionalProperty2", reader.Value.ToString());
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Null, reader.TokenType);
+      Assert.AreEqual(null, reader.Value);
+      Assert.AreEqual("Property 'additionalProperty2' has not been defined and the schema does not allow additional properties. Line 1, position 65.", validationEventArgs.Message);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      Assert.IsNotNull(validationEventArgs);
+    }
+
+    [Test]
+    public void ExtendsStringGreaterThanMaximumLength()
+    {
+      string schemaJson = @"{
+  ""extends"":{
+    ""type"":""string"",
+    ""minLength"":5,
+    ""maxLength"":10
+  },
+  ""maxLength"":9
+}";
+
+      List<string> errors = new List<string>();
+      string json = "'The quick brown fox jumps over the lazy dog.'";
+
+      Json.Schema.ValidationEventArgs validationEventArgs = null;
+
+      JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
+      reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; errors.Add(validationEventArgs.Message); };
+      reader.Schema = JsonSchema.Parse(schemaJson);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual(1, errors.Count);
+      Assert.AreEqual("String 'The quick brown fox jumps over the lazy dog.' exceeds maximum length of 9. Line 1, position 46.", errors[0]);
+
+      Assert.IsNotNull(validationEventArgs);
+    }
+
+    private JsonSchema GetExtendedSchema()
+    {
+      string first = @"{
+  ""id"":""first"",
+  ""type"":""object"",
+  ""properties"":
+  {
+    ""firstproperty"":{""type"":""string"",""required"":true}
+  },
+  ""additionalProperties"":{}
+}";
+
+      string second = @"{
+  ""id"":""second"",
+  ""type"":""object"",
+  ""extends"":{""$ref"":""first""},
+  ""properties"":
+  {
+    ""secondproperty"":{""type"":""string"",""required"":true}
+  },
+  ""additionalProperties"":false
+}";
+
+      JsonSchemaResolver resolver = new JsonSchemaResolver();
+      JsonSchema firstSchema = JsonSchema.Parse(first, resolver);
+      JsonSchema secondSchema = JsonSchema.Parse(second, resolver);
+
+      return secondSchema;
+    }
+
+    [Test]
+    public void ExtendsDisallowAdditionProperties()
+    {
+      string json = "{'firstproperty':'blah','secondproperty':'blah2','additional':'blah3','additional2':'blah4'}";
+
+      Json.Schema.ValidationEventArgs validationEventArgs = null;
+
+      JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
+      reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
+      reader.Schema = GetExtendedSchema();
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("firstproperty", reader.Value.ToString());
+      Assert.AreEqual(null, validationEventArgs);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("blah", reader.Value.ToString());
+      Assert.AreEqual(null, validationEventArgs);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("secondproperty", reader.Value.ToString());
+      Assert.AreEqual(null, validationEventArgs);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("blah2", reader.Value.ToString());
+      Assert.AreEqual(null, validationEventArgs);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("additional", reader.Value.ToString());
+      Assert.AreEqual("Property 'additional' has not been defined and the schema does not allow additional properties. Line 1, position 62.", validationEventArgs.Message);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("blah3", reader.Value.ToString());
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("additional2", reader.Value.ToString());
+      Assert.AreEqual("Property 'additional2' has not been defined and the schema does not allow additional properties. Line 1, position 84.", validationEventArgs.Message);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("blah4", reader.Value.ToString());
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      Assert.IsFalse(reader.Read());
+    }
+
+    [Test]
+    public void ExtendsMissingRequiredProperties()
+    {
+      string json = "{}";
+
+      List<string> errors = new List<string>();
+
+      JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
+      reader.ValidationEventHandler += (sender, args) => { errors.Add(args.Message); };
+      reader.Schema = GetExtendedSchema();
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      Assert.AreEqual(1, errors.Count);
+      Assert.AreEqual("Required properties are missing from object: secondproperty, firstproperty. Line 1, position 2.", errors[0]);
+    }
+
+    [Test]
+    public void NoAdditionalProperties()
+    {
+      string schemaJson = @"{
+  ""type"":""array"",
+  ""items"": [{""type"":""string""},{""type"":""integer""}],
+  ""additionalProperties"": false
+}";
+
+      string json = @"[1, 'a', null]";
+
+      Json.Schema.ValidationEventArgs validationEventArgs = null;
+
+      JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
+      reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
+      reader.Schema = JsonSchema.Parse(schemaJson);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Integer, reader.TokenType);
+      Assert.AreEqual("Invalid type. Expected String but got Integer. Line 1, position 3.", validationEventArgs.Message);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("Invalid type. Expected Integer but got String. Line 1, position 7.", validationEventArgs.Message);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Null, reader.TokenType);
+      Assert.AreEqual("Index 3 has not been defined and the schema does not allow additional items. Line 1, position 13.", validationEventArgs.Message);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
+
+      Assert.IsFalse(reader.Read());
+    }
+
+    [Test]
+    public void PatternPropertiesNoAdditionalProperties()
+    {
+      string schemaJson = @"{
+  ""type"":""object"",
+  ""patternProperties"": {
+     ""hi"": {""type"":""string""},
+     ""ho"": {""type"":""string""}
+  },
+  ""additionalProperties"": false
+}";
+
+      string json = @"{
+  ""hi"": ""A string!"",
+  ""hide"": ""A string!"",
+  ""ho"": 1,
+  ""hey"": ""A string!""
+}";
+
+      Json.Schema.ValidationEventArgs validationEventArgs = null;
+
+      JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
+      reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; };
+      reader.Schema = JsonSchema.Parse(schemaJson);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual(null, validationEventArgs);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual(null, validationEventArgs);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual(null, validationEventArgs);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Integer, reader.TokenType);
+      Assert.AreEqual("Invalid type. Expected String but got Integer. Line 4, position 10.", validationEventArgs.Message);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("Property 'hey' has not been defined and the schema does not allow additional properties. Line 5, position 8.", validationEventArgs.Message);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      Assert.IsFalse(reader.Read());
+    }
+
+    [Test]
+    public void ExtendedComplex()
+    {
+      string first = @"{
+  ""id"":""first"",
+  ""type"":""object"",
+  ""properties"":
+  {
+    ""firstproperty"":{""type"":""string""},
+    ""secondproperty"":{""type"":""string"",""maxLength"":10},
+    ""thirdproperty"":{
+      ""type"":""object"",
+      ""properties"":
+      {
+        ""thirdproperty_firstproperty"":{""type"":""string"",""maxLength"":10,""minLength"":7}
+      }
+    }
+  },
+  ""additionalProperties"":{}
+}";
+
+      string second = @"{
+  ""id"":""second"",
+  ""type"":""object"",
+  ""extends"":{""$ref"":""first""},
+  ""properties"":
+  {
+    ""secondproperty"":{""type"":""any""},
+    ""thirdproperty"":{
+      ""extends"":{
+        ""properties"":
+        {
+          ""thirdproperty_firstproperty"":{""maxLength"":9,""minLength"":6,""pattern"":""hi2u""}
+        },
+        ""additionalProperties"":{""maxLength"":9,""minLength"":6,""enum"":[""one"",""two""]}
+      },
+      ""type"":""object"",
+      ""properties"":
+      {
+        ""thirdproperty_firstproperty"":{""pattern"":""hi""}
+      },
+      ""additionalProperties"":{""type"":""string"",""enum"":[""two"",""three""]}
+    },
+    ""fourthproperty"":{""type"":""string""}
+  },
+  ""additionalProperties"":false
+}";
+
+      JsonSchemaResolver resolver = new JsonSchemaResolver();
+      JsonSchema firstSchema = JsonSchema.Parse(first, resolver);
+      JsonSchema secondSchema = JsonSchema.Parse(second, resolver);
+
+      JsonSchemaModelBuilder modelBuilder = new JsonSchemaModelBuilder();
+
+      string json = @"{
+  'firstproperty':'blahblahblahblahblahblah',
+  'secondproperty':'secasecasecasecaseca',
+  'thirdproperty':{
+    'thirdproperty_firstproperty':'aaa',
+    'additional':'three'
+  }
+}";
+
+      Json.Schema.ValidationEventArgs validationEventArgs = null;
+      List<string> errors = new List<string>();
+
+      JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json)));
+      reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; errors.Add(validationEventArgs.Message); };
+      reader.Schema = secondSchema;
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("firstproperty", reader.Value.ToString());
+      Assert.AreEqual(null, validationEventArgs);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("blahblahblahblahblahblah", reader.Value.ToString());
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("secondproperty", reader.Value.ToString());
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("secasecasecasecaseca", reader.Value.ToString());
+      Assert.AreEqual(1, errors.Count);
+      Assert.AreEqual("String 'secasecasecasecaseca' exceeds maximum length of 10. Line 3, position 41.", errors[0]);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("thirdproperty", reader.Value.ToString());
+      Assert.AreEqual(1, errors.Count);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+      Assert.AreEqual(1, errors.Count);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("thirdproperty_firstproperty", reader.Value.ToString());
+      Assert.AreEqual(1, errors.Count);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("aaa", reader.Value.ToString());
+      Assert.AreEqual(4, errors.Count);
+      Assert.AreEqual("String 'aaa' is less than minimum length of 7. Line 5, position 39.", errors[1]);
+      Assert.AreEqual("String 'aaa' does not match regex pattern 'hi'. Line 5, position 39.", errors[2]);
+      Assert.AreEqual("String 'aaa' does not match regex pattern 'hi2u'. Line 5, position 39.", errors[3]);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+      Assert.AreEqual("additional", reader.Value.ToString());
+      Assert.AreEqual(4, errors.Count);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+      Assert.AreEqual("three", reader.Value.ToString());
+      Assert.AreEqual(5, errors.Count);
+      Assert.AreEqual("String 'three' is less than minimum length of 6. Line 6, position 24.", errors[4]);
+      
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      Assert.IsFalse(reader.Read());
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/ComponentModel/BindingTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/ComponentModel/BindingTests.cs
new file mode 100644 (file)
index 0000000..c7adbef
--- /dev/null
@@ -0,0 +1,78 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+#if !PocketPC && !SILVERLIGHT
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using System.Web.UI;
+using Newtonsoft.Json.Linq;
+
+namespace Newtonsoft.Json.Tests.Linq.ComponentModel
+{
+  public class BindingTests : TestFixtureBase
+  {
+    [Test]
+    public void DataBinderEval()
+    {
+      JObject o = new JObject(
+        new JProperty("First", "String!"),
+        new JProperty("Second", 12345.6789m),
+        new JProperty("Third", new JArray(
+          1,
+          2, 
+          3,
+          4,
+          5,
+          new JObject(
+            new JProperty("Fourth", "String!"),
+            new JProperty("Fifth", new JObject(
+              new JProperty("Sixth", "String!")))))));
+
+      object value;
+
+      value = (string)DataBinder.Eval(o, "First.Value");
+      Assert.AreEqual(value, (string)o["First"]);
+
+      value = DataBinder.Eval(o, "Second.Value");
+      Assert.AreEqual(value, (decimal)o["Second"]);
+
+      value = DataBinder.Eval(o, "Third");
+      Assert.AreEqual(value, o["Third"]);
+
+      value = DataBinder.Eval(o, "Third[0].Value");
+      Assert.AreEqual((int)value, (int)o["Third"][0]);
+
+      value = DataBinder.Eval(o, "Third[5].Fourth.Value");
+      Assert.AreEqual(value, (string)o["Third"][5]["Fourth"]);
+
+      value = DataBinder.Eval(o, "Third[5].Fifth.Sixth.Value");
+      Assert.AreEqual(value, (string)o["Third"][5]["Fifth"]["Sixth"]);
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/ComponentModel/JPropertyDescriptorTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/ComponentModel/JPropertyDescriptorTests.cs
new file mode 100644 (file)
index 0000000..b8ee7ae
--- /dev/null
@@ -0,0 +1,91 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+#if !SILVERLIGHT
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using Newtonsoft.Json.Linq.ComponentModel;
+using Newtonsoft.Json.Linq;
+
+namespace Newtonsoft.Json.Tests.Linq.ComponentModel
+{
+  public class JPropertyDescriptorTests : TestFixtureBase
+  {
+    [Test]
+    public void GetValue()
+    {
+      JObject o = JObject.Parse("{prop1:'12345!',prop2:[1,'two','III']}");
+
+      JPropertyDescriptor prop1 = new JPropertyDescriptor("prop1", typeof(string));
+      JPropertyDescriptor prop2 = new JPropertyDescriptor("prop2", typeof(JArray));
+
+      Assert.AreEqual("12345!", ((JValue) prop1.GetValue(o)).Value);
+      Assert.AreEqual(o["prop2"], prop2.GetValue(o));
+    }
+
+    [Test]
+    public void SetValue()
+    {
+      JObject o = JObject.Parse("{prop1:'12345!'}");
+
+      JPropertyDescriptor propertyDescriptor1 = new JPropertyDescriptor("prop1", typeof(string));
+
+      propertyDescriptor1.SetValue(o, "54321!");
+
+      Assert.AreEqual("54321!", (string)o["prop1"]);
+    }
+
+    [Test]
+    public void ResetValue()
+    {
+      JObject o = JObject.Parse("{prop1:'12345!'}");
+
+      JPropertyDescriptor propertyDescriptor1 = new JPropertyDescriptor("prop1", typeof(string));
+      propertyDescriptor1.ResetValue(o);
+
+      Assert.AreEqual("12345!", (string)o["prop1"]);
+    }
+
+    [Test]
+    public void IsReadOnly()
+    {
+      JPropertyDescriptor propertyDescriptor1 = new JPropertyDescriptor("prop1", typeof(string));
+
+      Assert.AreEqual(false, propertyDescriptor1.IsReadOnly);
+    }
+
+    [Test]
+    public void PropertyType()
+    {
+      JPropertyDescriptor propertyDescriptor1 = new JPropertyDescriptor("prop1", typeof(string));
+
+      Assert.AreEqual(typeof(string), propertyDescriptor1.PropertyType);
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/DynamicTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/DynamicTests.cs
new file mode 100644 (file)
index 0000000..32f9df1
--- /dev/null
@@ -0,0 +1,662 @@
+#if !(NET35 || NET20)
+using System;
+using System.Collections.Generic;
+using System.Dynamic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Linq;
+using NUnit.Framework;
+using Newtonsoft.Json.Utilities;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Tests.Linq
+{
+  public class DynamicTests : TestFixtureBase
+  {
+    [Test]
+    public void JObjectPropertyNames()
+    {
+      JObject o = new JObject(
+        new JProperty("ChildValue", "blah blah"));
+
+      dynamic d = o;
+
+      d.First = "A value!";
+
+      Assert.AreEqual(new JValue("A value!"), d.First);
+      Assert.AreEqual("A value!", (string)d.First);
+
+      d.First = null;
+      Assert.AreEqual(JTokenType.Null, d.First.Type);
+
+      Assert.IsTrue(d.Remove("First"));
+      Assert.IsNull(d.First);
+
+      JValue v1 = d.ChildValue;
+      JValue v2 = d["ChildValue"];
+      Assert.AreEqual(v1, v2);
+
+      JValue newValue1 = new JValue("Blah blah");
+      d.NewValue = newValue1;
+      JValue newValue2 = d.NewValue;
+
+      Assert.IsTrue(ReferenceEquals(newValue1, newValue2));
+    }
+
+    [Test]
+    public void JObjectEnumerator()
+    {
+      JObject o = new JObject(
+        new JProperty("ChildValue", "blah blah"));
+
+      dynamic d = o;
+
+      foreach (JProperty value in d)
+      {
+        Assert.AreEqual("ChildValue", value.Name);
+        Assert.AreEqual("blah blah", (string)value.Value);
+      }
+
+      foreach (dynamic value in d)
+      {
+        Assert.AreEqual("ChildValue", value.Name);
+        Assert.AreEqual("blah blah", (string)value.Value);
+      }
+    }
+
+    [Test]
+    public void JObjectPropertyNameWithJArray()
+    {
+      JObject o = new JObject(
+        new JProperty("ChildValue", "blah blah"));
+
+      dynamic d = o;
+
+      d.First = new JArray();
+      d.First.Add("Hi");
+
+      Assert.AreEqual(1, d.First.Count);
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Could not determine JSON object type for type System.String[].")]
+    public void JObjectPropertyNameWithNonToken()
+    {
+      dynamic d = new JObject();
+
+      d.First = new [] {"One", "II", "3"};
+    }
+
+    [Test]
+    public void JObjectMethods()
+    {
+      JObject o = new JObject(
+        new JProperty("ChildValue", "blah blah"));
+
+      dynamic d = o;
+
+      d.Add("NewValue", 1);
+
+      object count = d.Count;
+
+      Assert.IsNull(count);
+      Assert.IsNull(d["Count"]);
+
+      JToken v;
+      Assert.IsTrue(d.TryGetValue("ChildValue", out v));
+      Assert.AreEqual("blah blah", (string)v);
+    }
+
+    [Test]
+    public void JValueEquals()
+    {
+      JObject o = new JObject(
+        new JProperty("Null", new JValue(null, JTokenType.Null)),
+        new JProperty("Integer", new JValue(1)),
+        new JProperty("Float", new JValue(1.1d)),
+        new JProperty("Decimal", new JValue(1.1m)),
+        new JProperty("DateTime", new JValue(new DateTime(2000, 12, 29, 23, 51, 10, DateTimeKind.Utc))),
+        new JProperty("Boolean", new JValue(true)),
+        new JProperty("String", new JValue("A string lol!")),
+        new JProperty("Bytes", new JValue(Encoding.UTF8.GetBytes("A string lol!")))
+        );
+
+      dynamic d = o;
+
+      Assert.IsTrue(d.Null == d.Null);
+      Assert.IsTrue(d.Null == null);
+      Assert.IsTrue(d.Null == new JValue(null, JTokenType.Null));
+      Assert.IsFalse(d.Null == 1);
+
+      Assert.IsTrue(d.Integer == d.Integer);
+      Assert.IsTrue(d.Integer > 0);
+      Assert.IsTrue(d.Integer > 0.0m);
+      Assert.IsTrue(d.Integer > 0.0f);
+      Assert.IsTrue(d.Integer > null);
+      Assert.IsTrue(d.Integer >= null);
+      Assert.IsTrue(d.Integer == 1);
+      Assert.IsTrue(d.Integer == 1m);
+      Assert.IsTrue(d.Integer != 1.1f);
+      Assert.IsTrue(d.Integer != 1.1d);
+
+      Assert.IsTrue(d.Decimal == d.Decimal);
+      Assert.IsTrue(d.Decimal > 0);
+      Assert.IsTrue(d.Decimal > 0.0m);
+      Assert.IsTrue(d.Decimal > 0.0f);
+      Assert.IsTrue(d.Decimal > null);
+      Assert.IsTrue(d.Decimal >= null);
+      Assert.IsTrue(d.Decimal == 1.1);
+      Assert.IsTrue(d.Decimal == 1.1m);
+      Assert.IsTrue(d.Decimal != 1.0f);
+      Assert.IsTrue(d.Decimal != 1.0d);
+
+      Assert.IsTrue(d.Float == d.Float);
+      Assert.IsTrue(d.Float > 0);
+      Assert.IsTrue(d.Float > 0.0m);
+      Assert.IsTrue(d.Float > 0.0f);
+      Assert.IsTrue(d.Float > null);
+      Assert.IsTrue(d.Float >= null);
+      Assert.IsTrue(d.Float < 2);
+      Assert.IsTrue(d.Float <= 1.1);
+      Assert.IsTrue(d.Float == 1.1);
+      Assert.IsTrue(d.Float == 1.1m);
+      Assert.IsTrue(d.Float != 1.0f);
+      Assert.IsTrue(d.Float != 1.0d);
+
+      Assert.IsTrue(d.Bytes == d.Bytes);
+      Assert.IsTrue(d.Bytes == Encoding.UTF8.GetBytes("A string lol!"));
+      Assert.IsTrue(d.Bytes == new JValue(Encoding.UTF8.GetBytes("A string lol!")));
+    }
+
+    [Test]
+    public void JValueAddition()
+    {
+      JObject o = new JObject(
+        new JProperty("Null", new JValue(null, JTokenType.Null)),
+        new JProperty("Integer", new JValue(1)),
+        new JProperty("Float", new JValue(1.1d)),
+        new JProperty("Decimal", new JValue(1.1m)),
+        new JProperty("DateTime", new JValue(new DateTime(2000, 12, 29, 23, 51, 10, DateTimeKind.Utc))),
+        new JProperty("Boolean", new JValue(true)),
+        new JProperty("String", new JValue("A string lol!")),
+        new JProperty("Bytes", new JValue(Encoding.UTF8.GetBytes("A string lol!")))
+        );
+
+      dynamic d = o;
+      dynamic r;
+
+      #region Add
+      r = d.String + " LAMO!";
+      Assert.AreEqual("A string lol! LAMO!", (string)r);
+      r += " gg";
+      Assert.AreEqual("A string lol! LAMO! gg", (string)r);
+
+      r = d.String + null;
+      Assert.AreEqual("A string lol!", (string)r);
+      r += null;
+      Assert.AreEqual("A string lol!", (string)r);
+
+      r = d.Integer + 1;
+      Assert.AreEqual(2, (int)r);
+      r += 2;
+      Assert.AreEqual(4, (int)r);
+
+      r = d.Integer + 1.1;
+      Assert.AreEqual(2.1, (double)r);
+      r += 2;
+      Assert.AreEqual(4.1, (double)r);
+
+      r = d.Integer + 1.1d;
+      Assert.AreEqual(2.1, (decimal)r);
+      r += 2;
+      Assert.AreEqual(4.1, (decimal)r);
+
+      r = d.Integer + null;
+      Assert.AreEqual(null, r.Value);
+      r += 2;
+      Assert.AreEqual(null, r.Value);
+
+      r = d.Float + 1;
+      Assert.AreEqual(2.1, (double)r);
+      r += 2;
+      Assert.AreEqual(4.1, (double)r);
+
+      r = d.Float + 1.1;
+      Assert.AreEqual(2.2, (double)r);
+      r += 2;
+      Assert.AreEqual(4.2, (double)r);
+
+      r = d.Float + 1.1d;
+      Assert.AreEqual(2.2, (decimal)r);
+      r += 2;
+      Assert.AreEqual(4.2, (decimal)r);
+
+      r = d.Float + null;
+      Assert.AreEqual(null, r.Value);
+      r += 2;
+      Assert.AreEqual(null, r.Value);
+
+      r = d.Decimal + 1;
+      Assert.AreEqual(2.1, (decimal)r);
+      r += 2;
+      Assert.AreEqual(4.1, (decimal)r);
+
+      r = d.Decimal + 1.1;
+      Assert.AreEqual(2.2, (decimal)r);
+      r += 2;
+      Assert.AreEqual(4.2, (decimal)r);
+
+      r = d.Decimal + 1.1d;
+      Assert.AreEqual(2.2, (decimal)r);
+      r += 2;
+      Assert.AreEqual(4.2, (decimal)r);
+
+      r = d.Decimal + null;
+      Assert.AreEqual(null, r.Value);
+      r += 2;
+      Assert.AreEqual(null, r.Value);
+      #endregion
+
+      #region Subtract
+      r = d.Integer - 1;
+      Assert.AreEqual(0, (int)r);
+      r -= 2;
+      Assert.AreEqual(-2, (int)r);
+
+      r = d.Integer - 1.1;
+      Assert.AreEqual(-0.1, (double)r, 0.00001);
+      r -= 2;
+      Assert.AreEqual(-2.1, (double)r);
+
+      r = d.Integer - 1.1d;
+      Assert.AreEqual(-0.1, (decimal)r);
+      r -= 2;
+      Assert.AreEqual(-2.1, (decimal)r);
+
+      r = d.Integer - null;
+      Assert.AreEqual(null, r.Value);
+      r -= 2;
+      Assert.AreEqual(null, r.Value);
+
+      r = d.Float - 1;
+      Assert.AreEqual(0.1, (double)r, 0.00001);
+      r -= 2;
+      Assert.AreEqual(-1.9, (double)r);
+
+      r = d.Float - 1.1;
+      Assert.AreEqual(0, (double)r);
+      r -= 2;
+      Assert.AreEqual(-2, (double)r);
+
+      r = d.Float - 1.1d;
+      Assert.AreEqual(0, (decimal)r);
+      r -= 2;
+      Assert.AreEqual(-2, (decimal)r);
+
+      r = d.Float - null;
+      Assert.AreEqual(null, r.Value);
+      r -= 2;
+      Assert.AreEqual(null, r.Value);
+
+      r = d.Decimal - 1;
+      Assert.AreEqual(0.1, (decimal)r);
+      r -= 2;
+      Assert.AreEqual(-1.9, (decimal)r);
+
+      r = d.Decimal - 1.1;
+      Assert.AreEqual(0, (decimal)r);
+      r -= 2;
+      Assert.AreEqual(-2, (decimal)r);
+
+      r = d.Decimal - 1.1d;
+      Assert.AreEqual(0, (decimal)r);
+      r -= 2;
+      Assert.AreEqual(-2, (decimal)r);
+
+      r = d.Decimal - null;
+      Assert.AreEqual(null, r.Value);
+      r -= 2;
+      Assert.AreEqual(null, r.Value);
+      #endregion
+
+      #region Multiply
+      r = d.Integer * 1;
+      Assert.AreEqual(1, (int)r);
+      r *= 2;
+      Assert.AreEqual(2, (int)r);
+
+      r = d.Integer * 1.1;
+      Assert.AreEqual(1.1, (double)r);
+      r *= 2;
+      Assert.AreEqual(2.2, (double)r);
+
+      r = d.Integer * 1.1d;
+      Assert.AreEqual(1.1, (decimal)r);
+      r *= 2;
+      Assert.AreEqual(2.2, (decimal)r);
+
+      r = d.Integer * null;
+      Assert.AreEqual(null, r.Value);
+      r *= 2;
+      Assert.AreEqual(null, r.Value);
+
+      r = d.Float * 1;
+      Assert.AreEqual(1.1, (double)r);
+      r *= 2;
+      Assert.AreEqual(2.2, (double)r);
+
+      r = d.Float * 1.1;
+      Assert.AreEqual(1.21, (double)r, 0.00001);
+      r *= 2;
+      Assert.AreEqual(2.42, (double)r, 0.00001);
+
+      r = d.Float * 1.1d;
+      Assert.AreEqual(1.21, (decimal)r);
+      r *= 2;
+      Assert.AreEqual(2.42, (decimal)r);
+
+      r = d.Float * null;
+      Assert.AreEqual(null, r.Value);
+      r *= 2;
+      Assert.AreEqual(null, r.Value);
+
+      r = d.Decimal * 1;
+      Assert.AreEqual(1.1, (decimal)r);
+      r *= 2;
+      Assert.AreEqual(2.2, (decimal)r);
+
+      r = d.Decimal * 1.1;
+      Assert.AreEqual(1.21, (decimal)r);
+      r *= 2;
+      Assert.AreEqual(2.42, (decimal)r);
+
+      r = d.Decimal * 1.1d;
+      Assert.AreEqual(1.21, (decimal)r);
+      r *= 2;
+      Assert.AreEqual(2.42, (decimal)r);
+
+      r = d.Decimal * null;
+      Assert.AreEqual(null, r.Value);
+      r *= 2;
+      Assert.AreEqual(null, r.Value);
+      #endregion
+
+      #region Divide
+      r = d.Integer / 1;
+      Assert.AreEqual(1, (int)r);
+      r /= 2;
+      Assert.AreEqual(0, (int)r);
+
+      r = d.Integer / 1.1;
+      Assert.AreEqual(0.9090909090909091, (double)r);
+      r /= 2;
+      Assert.AreEqual(0.454545454545455, (double)r, 0.00001);
+
+      r = d.Integer / 1.1d;
+      Assert.AreEqual(0.909090909090909m, (decimal)r);
+      r /= 2;
+      Assert.AreEqual(0.454545454545454m, (decimal)r);
+
+      r = d.Integer / null;
+      Assert.AreEqual(null, r.Value);
+      r /= 2;
+      Assert.AreEqual(null, r.Value);
+
+      r = d.Float / 1;
+      Assert.AreEqual(1.1, (double)r);
+      r /= 2;
+      Assert.AreEqual(0.55, (double)r);
+
+      r = d.Float / 1.1;
+      Assert.AreEqual(1, (double)r, 0.00001);
+      r /= 2;
+      Assert.AreEqual(0.5, (double)r, 0.00001);
+
+      r = d.Float / 1.1d;
+      Assert.AreEqual(1m, (decimal)r);
+      r /= 2;
+      Assert.AreEqual(0.5m, (decimal)r);
+
+      r = d.Float / null;
+      Assert.AreEqual(null, r.Value);
+      r /= 2;
+      Assert.AreEqual(null, r.Value);
+
+      r = d.Decimal / 1;
+      Assert.AreEqual(1.1d, (decimal)r);
+      r /= 2;
+      Assert.AreEqual(0.55d, (decimal)r);
+
+      r = d.Decimal / 1.1;
+      Assert.AreEqual(1d, (decimal)r);
+      r /= 2;
+      Assert.AreEqual(0.5d, (decimal)r);
+
+      r = d.Decimal / 1.1d;
+      Assert.AreEqual(1d, (decimal)r);
+      r /= 2;
+      Assert.AreEqual(0.5d, (decimal)r);
+
+      r = d.Decimal / null;
+      Assert.AreEqual(null, r.Value);
+      r /= 2;
+      Assert.AreEqual(null, r.Value);
+      #endregion
+    }
+
+    [Test]
+    public void JValueToString()
+    {
+      JObject o = new JObject(
+        new JProperty("Null", new JValue(null, JTokenType.Null)),
+        new JProperty("Integer", new JValue(1)),
+        new JProperty("Float", new JValue(1.1)),
+        new JProperty("DateTime", new JValue(new DateTime(2000, 12, 29, 23, 51, 10, DateTimeKind.Utc))),
+        new JProperty("Boolean", new JValue(true)),
+        new JProperty("String", new JValue("A string lol!")),
+        new JProperty("Bytes", new JValue(Encoding.UTF8.GetBytes("A string lol!")))
+        );
+
+      dynamic d = o;
+
+      Assert.AreEqual("", d.Null.ToString());
+      Assert.AreEqual("1", d.Integer.ToString());
+      Assert.AreEqual("1.1", d.Float.ToString(CultureInfo.InvariantCulture));
+      Assert.AreEqual("12/29/2000 23:51:10", d.DateTime.ToString(null, CultureInfo.InvariantCulture));
+      Assert.AreEqual("True", d.Boolean.ToString());
+      Assert.AreEqual("A string lol!", d.String.ToString());
+      Assert.AreEqual("System.Byte[]", d.Bytes.ToString());
+    }
+
+    [Test]
+    public void JObjectGetDynamicPropertyNames()
+    {
+      JObject o = new JObject(
+        new JProperty("ChildValue", "blah blah"),
+        new JProperty("Hello Joe", null));
+
+      dynamic d = o;
+
+      List<string> memberNames = o.GetDynamicMemberNames().ToList();
+
+      Assert.AreEqual(2, memberNames.Count);
+      Assert.AreEqual("ChildValue", memberNames[0]);
+      Assert.AreEqual("Hello Joe", memberNames[1]);
+
+      o = new JObject(
+        new JProperty("ChildValue1", "blah blah"),
+        new JProperty("Hello Joe1", null));
+
+      d = o;
+
+      memberNames = o.GetDynamicMemberNames().ToList();
+
+      Assert.AreEqual(2, memberNames.Count);
+      Assert.AreEqual("ChildValue1", memberNames[0]);
+      Assert.AreEqual("Hello Joe1", memberNames[1]);
+    }
+
+    [Test]
+    public void JValueConvert()
+    {
+      AssertValueConverted<bool>(true);
+      AssertValueConverted<bool?>(true);
+      AssertValueConverted<bool?>(false);
+      AssertValueConverted<bool?>(null);
+      AssertValueConverted<bool?>("true", true);
+      AssertValueConverted<byte[]>(null);
+      AssertValueConverted<byte[]>(Encoding.UTF8.GetBytes("blah"));
+      AssertValueConverted<DateTime>(new DateTime(2000, 12, 20, 23, 59, 2, DateTimeKind.Utc));
+      AssertValueConverted<DateTime?>(new DateTime(2000, 12, 20, 23, 59, 2, DateTimeKind.Utc));
+      AssertValueConverted<DateTime?>(null);
+      AssertValueConverted<DateTimeOffset>(new DateTimeOffset(2000, 12, 20, 23, 59, 2, TimeSpan.FromHours(1)));
+      AssertValueConverted<DateTimeOffset?>(new DateTimeOffset(2000, 12, 20, 23, 59, 2, TimeSpan.FromHours(1)));
+      AssertValueConverted<DateTimeOffset?>(null);
+      AssertValueConverted<decimal>(99.9m);
+      AssertValueConverted<decimal?>(99.9m);
+      AssertValueConverted<decimal>(1);
+      AssertValueConverted<decimal>(1.1f, 1.1m);
+      AssertValueConverted<decimal>("1.1", 1.1m);
+      AssertValueConverted<double>(99.9);
+      AssertValueConverted<double>(99.9m);
+      AssertValueConverted<double?>(99.9);
+      AssertValueConverted<float>(99.9f);
+      AssertValueConverted<float?>(99.9f);
+      AssertValueConverted<int>(int.MinValue);
+      AssertValueConverted<int?>(int.MinValue);
+      AssertValueConverted<long>(long.MaxValue);
+      AssertValueConverted<long?>(long.MaxValue);
+      AssertValueConverted<short>(short.MaxValue);
+      AssertValueConverted<short?>(short.MaxValue);
+      AssertValueConverted<string>("blah");
+      AssertValueConverted<string>(null);
+      AssertValueConverted<string>(1, "1");
+      AssertValueConverted<uint>(uint.MinValue);
+      AssertValueConverted<uint?>(uint.MinValue);
+      AssertValueConverted<uint?>("1", 1);
+      AssertValueConverted<ulong>(ulong.MaxValue);
+      AssertValueConverted<ulong?>(ulong.MaxValue);
+      AssertValueConverted<ushort>(ushort.MinValue);
+      AssertValueConverted<ushort?>(ushort.MinValue);
+      AssertValueConverted<ushort?>(null);
+    }
+
+    private static void AssertValueConverted<T>(object value)
+    {
+      AssertValueConverted<T>(value, value);
+    }
+
+    private static void AssertValueConverted<T>(object value, object expected)
+    {
+      JValue v = new JValue(value);
+      dynamic d = v;
+
+      T t = d;
+      Assert.AreEqual(expected, t);
+    }
+
+    [Test]
+    public void DynamicSerializerExample()
+    {
+      dynamic value = new DynamicDictionary();
+
+      value.Name = "Arine Admin";
+      value.Enabled = true;
+      value.Roles = new[] {"Admin", "User"};
+
+      string json = JsonConvert.SerializeObject(value, Formatting.Indented);
+      // {
+      //   "Name": "Arine Admin",
+      //   "Enabled": true,
+      //   "Roles": [
+      //     "Admin",
+      //     "User"
+      //   ]
+      // }
+
+      dynamic newValue = JsonConvert.DeserializeObject<DynamicDictionary>(json);
+
+      string role = newValue.Roles[0];
+      // Admin
+    }
+
+    [Test]
+    public void DynamicLinqExample()
+    {
+      JObject oldAndBusted = new JObject();
+      oldAndBusted["Name"] = "Arnie Admin";
+      oldAndBusted["Enabled"] = true;
+      oldAndBusted["Roles"] = new JArray(new[] { "Admin", "User" });
+
+      string oldRole = (string) oldAndBusted["Roles"][0];
+      // Admin
+
+
+      dynamic newHotness = new JObject();
+      newHotness.Name = "Arnie Admin";
+      newHotness.Enabled = true;
+      newHotness.Roles = new JArray(new[] { "Admin", "User" });
+
+      string newRole = newHotness.Roles[0];
+      // Admin
+    }
+
+    [Test]
+    public void ImprovedDynamicLinqExample()
+    {
+      dynamic product = new JObject();
+      product.ProductName = "Elbow Grease";
+      product.Enabled = true;
+      product.Price = 4.90m;
+      product.StockCount = 9000;
+      product.StockValue = 44100;
+
+      // All Elbow Grease must go sale!
+      // 50% off price
+
+      product.Price = product.Price / 2;
+      product.StockValue = product.StockCount * product.Price;
+      product.ProductName = product.ProductName + " (SALE)";
+
+      string json = product.ToString();
+      // {
+      //   "ProductName": "Elbow Grease (SALE)",
+      //   "Enabled": true,
+      //   "Price": 2.45,
+      //   "StockCount": 9000,
+      //   "StockValue": 22050.0
+      // }
+
+      Assert.AreEqual(@"{
+  ""ProductName"": ""Elbow Grease (SALE)"",
+  ""Enabled"": true,
+  ""Price"": 2.45,
+  ""StockCount"": 9000,
+  ""StockValue"": 22050.0
+}", json);
+    }
+
+    public class DynamicDictionary : DynamicObject
+    {
+      private readonly IDictionary<string, object> _values = new Dictionary<string, object>();
+
+      public override IEnumerable<string> GetDynamicMemberNames()
+      {
+        return _values.Keys;
+      }
+
+      public override bool TryGetMember(GetMemberBinder binder, out object result)
+      {
+        result = _values[binder.Name];
+        return true;
+      }
+
+      public override bool TrySetMember(SetMemberBinder binder, object value)
+      {
+        _values[binder.Name] = value;
+        return true;
+      }
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JArrayTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JArrayTests.cs
new file mode 100644 (file)
index 0000000..7666502
--- /dev/null
@@ -0,0 +1,440 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using Newtonsoft.Json.Linq;
+
+namespace Newtonsoft.Json.Tests.Linq
+{
+  public class JArrayTests : TestFixtureBase
+  {
+    [Test]
+    public void Clear()
+    {
+      JArray a = new JArray { 1 };
+      Assert.AreEqual(1, a.Count);
+
+      a.Clear();
+      Assert.AreEqual(0, a.Count);
+    }
+
+    [Test]
+    public void Contains()
+    {
+      JValue v = new JValue(1);
+
+      JArray a = new JArray { v };
+
+      Assert.AreEqual(false, a.Contains(new JValue(2)));
+      Assert.AreEqual(false, a.Contains(new JValue(1)));
+      Assert.AreEqual(false, a.Contains(null));
+      Assert.AreEqual(true, a.Contains(v));
+    }
+
+    [Test]
+    public void GenericCollectionCopyTo()
+    {
+      JArray j = new JArray();
+      j.Add(new JValue(1));
+      j.Add(new JValue(2));
+      j.Add(new JValue(3));
+      Assert.AreEqual(3, j.Count);
+
+      JToken[] a = new JToken[5];
+
+      ((ICollection<JToken>)j).CopyTo(a, 1);
+
+      Assert.AreEqual(null, a[0]);
+
+      Assert.AreEqual(1, (int)a[1]);
+
+      Assert.AreEqual(2, (int)a[2]);
+
+      Assert.AreEqual(3, (int)a[3]);
+
+      Assert.AreEqual(null, a[4]);
+
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentNullException), ExpectedMessage = @"Value cannot be null.
+Parameter name: array")]
+    public void GenericCollectionCopyToNullArrayShouldThrow()
+    {
+      JArray j = new JArray();
+      ((ICollection<JToken>)j).CopyTo(null, 0);
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentOutOfRangeException), ExpectedMessage = @"arrayIndex is less than 0.
+Parameter name: arrayIndex")]
+    public void GenericCollectionCopyToNegativeArrayIndexShouldThrow()
+    {
+      JArray j = new JArray();
+      ((ICollection<JToken>)j).CopyTo(new JToken[1], -1);
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentException), ExpectedMessage = @"arrayIndex is equal to or greater than the length of array.")]
+    public void GenericCollectionCopyToArrayIndexEqualGreaterToArrayLengthShouldThrow()
+    {
+      JArray j = new JArray();
+      ((ICollection<JToken>)j).CopyTo(new JToken[1], 1);
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentException), ExpectedMessage = @"The number of elements in the source JObject is greater than the available space from arrayIndex to the end of the destination array.")]
+    public void GenericCollectionCopyToInsufficientArrayCapacity()
+    {
+      JArray j = new JArray();
+      j.Add(new JValue(1));
+      j.Add(new JValue(2));
+      j.Add(new JValue(3));
+
+      ((ICollection<JToken>)j).CopyTo(new JToken[3], 1);
+    }
+
+    [Test]
+    public void Remove()
+    {
+      JValue v = new JValue(1);
+      JArray j = new JArray();
+      j.Add(v);
+
+      Assert.AreEqual(1, j.Count);
+
+      Assert.AreEqual(false, j.Remove(new JValue(1)));
+      Assert.AreEqual(false, j.Remove(null));
+      Assert.AreEqual(true, j.Remove(v));
+      Assert.AreEqual(false, j.Remove(v));
+
+      Assert.AreEqual(0, j.Count);
+    }
+
+    [Test]
+    public void IndexOf()
+    {
+      JValue v1 = new JValue(1);
+      JValue v2 = new JValue(1);
+      JValue v3 = new JValue(1);
+
+      JArray j = new JArray();
+
+      j.Add(v1);
+      Assert.AreEqual(0, j.IndexOf(v1));
+
+      j.Add(v2);
+      Assert.AreEqual(0, j.IndexOf(v1));
+      Assert.AreEqual(1, j.IndexOf(v2));
+
+      j.AddFirst(v3);
+      Assert.AreEqual(1, j.IndexOf(v1));
+      Assert.AreEqual(2, j.IndexOf(v2));
+      Assert.AreEqual(0, j.IndexOf(v3));
+
+      v3.Remove();
+      Assert.AreEqual(0, j.IndexOf(v1));
+      Assert.AreEqual(1, j.IndexOf(v2));
+      Assert.AreEqual(-1, j.IndexOf(v3));
+    }
+
+    [Test]
+    public void RemoveAt()
+    {
+      JValue v1 = new JValue(1);
+      JValue v2 = new JValue(1);
+      JValue v3 = new JValue(1);
+
+      JArray j = new JArray();
+
+      j.Add(v1);
+      j.Add(v2);
+      j.Add(v3);
+
+      Assert.AreEqual(true, j.Contains(v1));
+      j.RemoveAt(0);
+      Assert.AreEqual(false, j.Contains(v1));
+
+      Assert.AreEqual(true, j.Contains(v3));
+      j.RemoveAt(1);
+      Assert.AreEqual(false, j.Contains(v3));
+
+      Assert.AreEqual(1, j.Count);
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentOutOfRangeException), ExpectedMessage = @"index is equal to or greater than Count.
+Parameter name: index")]
+    public void RemoveAtOutOfRangeIndexShouldError()
+    {
+      JArray j = new JArray();
+      j.RemoveAt(0);
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentOutOfRangeException), ExpectedMessage = @"index is less than 0.
+Parameter name: index")]
+    public void RemoveAtNegativeIndexShouldError()
+    {
+      JArray j = new JArray();
+      j.RemoveAt(-1);
+    }
+
+    [Test]
+    public void Insert()
+    {
+      JValue v1 = new JValue(1);
+      JValue v2 = new JValue(2);
+      JValue v3 = new JValue(3);
+      JValue v4 = new JValue(4);
+
+      JArray j = new JArray();
+
+      j.Add(v1);
+      j.Add(v2);
+      j.Add(v3);
+      j.Insert(1, v4);
+
+      Assert.AreEqual(0, j.IndexOf(v1));
+      Assert.AreEqual(1, j.IndexOf(v4));
+      Assert.AreEqual(2, j.IndexOf(v2));
+      Assert.AreEqual(3, j.IndexOf(v3));
+    }
+
+    [Test]
+    public void AddFirstAddedTokenShouldBeFirst()
+    {
+      JValue v1 = new JValue(1);
+      JValue v2 = new JValue(2);
+      JValue v3 = new JValue(3);
+
+      JArray j = new JArray();
+      Assert.AreEqual(null, j.First);
+      Assert.AreEqual(null, j.Last);
+
+      j.AddFirst(v1);
+      Assert.AreEqual(v1, j.First);
+      Assert.AreEqual(v1, j.Last);
+
+      j.AddFirst(v2);
+      Assert.AreEqual(v2, j.First);
+      Assert.AreEqual(v1, j.Last);
+
+      j.AddFirst(v3);
+      Assert.AreEqual(v3, j.First);
+      Assert.AreEqual(v1, j.Last);
+    }
+
+    [Test]
+    public void InsertShouldInsertAtZeroIndex()
+    {
+      JValue v1 = new JValue(1);
+      JValue v2 = new JValue(2);
+
+      JArray j = new JArray();
+
+      j.Insert(0, v1);
+      Assert.AreEqual(0, j.IndexOf(v1));
+
+      j.Insert(0, v2);
+      Assert.AreEqual(1, j.IndexOf(v1));
+      Assert.AreEqual(0, j.IndexOf(v2));
+    }
+
+    [Test]
+    public void InsertNull()
+    {
+      JArray j = new JArray();
+      j.Insert(0, null);
+
+      Assert.AreEqual(null, ((JValue)j[0]).Value);
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentOutOfRangeException), ExpectedMessage = @"Specified argument was out of the range of valid values.
+Parameter name: index")]
+    public void InsertNegativeIndexShouldThrow()
+    {
+      JArray j = new JArray();
+      j.Insert(-1, new JValue(1));
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentOutOfRangeException), ExpectedMessage = @"Specified argument was out of the range of valid values.
+Parameter name: index")]
+    public void InsertOutOfRangeIndexShouldThrow()
+    {
+      JArray j = new JArray();
+      j.Insert(2, new JValue(1));
+    }
+
+    [Test]
+    public void Item()
+    {
+      JValue v1 = new JValue(1);
+      JValue v2 = new JValue(2);
+      JValue v3 = new JValue(3);
+      JValue v4 = new JValue(4);
+
+      JArray j = new JArray();
+
+      j.Add(v1);
+      j.Add(v2);
+      j.Add(v3);
+
+      j[1] = v4;
+
+      Assert.AreEqual(null, v2.Parent);
+      Assert.AreEqual(-1, j.IndexOf(v2));
+      Assert.AreEqual(j, v4.Parent);
+      Assert.AreEqual(1, j.IndexOf(v4));
+    }
+
+    [Test]
+    [ExpectedException(typeof(Exception), ExpectedMessage = "Error reading JArray from JsonReader. Current JsonReader item is not an array: StartObject")]
+    public void Parse_ShouldThrowOnUnexpectedToken()
+    {
+      string json = @"{""prop"":""value""}";
+      JArray.Parse(json);
+    }
+
+    public class ListItemFields
+    {
+      public string ListItemText { get; set; }
+      public object ListItemValue { get; set; }
+    }
+
+    [Test]
+    public void ArrayOrder()
+    {
+      string itemZeroText = "Zero text";
+
+      IEnumerable<ListItemFields> t = new List<ListItemFields>
+      {
+        new ListItemFields { ListItemText = "First", ListItemValue = 1 },
+        new ListItemFields { ListItemText = "Second", ListItemValue = 2 },
+        new ListItemFields { ListItemText = "Third", ListItemValue = 3 }
+      };
+
+      JObject optionValues =
+          new JObject(
+              new JProperty("options",
+                  new JArray(
+                      new JObject(
+                          new JProperty("text", itemZeroText),
+                          new JProperty("value", "0")),
+                          from r in t
+                          orderby r.ListItemValue
+                          select new JObject(
+                              new JProperty("text", r.ListItemText),
+                              new JProperty("value", r.ListItemValue.ToString())))));
+
+      string result = "myOptions = " + optionValues.ToString();
+
+      Assert.AreEqual(@"myOptions = {
+  ""options"": [
+    {
+      ""text"": ""Zero text"",
+      ""value"": ""0""
+    },
+    {
+      ""text"": ""First"",
+      ""value"": ""1""
+    },
+    {
+      ""text"": ""Second"",
+      ""value"": ""2""
+    },
+    {
+      ""text"": ""Third"",
+      ""value"": ""3""
+    }
+  ]
+}", result);
+    }
+
+    [Test]
+    public void Iterate()
+    {
+      JArray a = new JArray(1, 2, 3, 4, 5);
+
+      int i = 1;
+      foreach (JToken token in a)
+      {
+        Assert.AreEqual(i, (int)token);
+        i++;
+      }
+    }
+
+    
+#if !SILVERLIGHT
+    [Test]
+    public void ITypedListGetItemProperties()
+    {
+      JProperty p1 = new JProperty("Test1", 1);
+      JProperty p2 = new JProperty("Test2", "Two");
+      ITypedList a = new JArray(new JObject(p1, p2));
+
+      PropertyDescriptorCollection propertyDescriptors = a.GetItemProperties(null);
+      Assert.IsNotNull(propertyDescriptors);
+      Assert.AreEqual(2, propertyDescriptors.Count);
+      Assert.AreEqual("Test1", propertyDescriptors[0].Name);
+      Assert.AreEqual("Test2", propertyDescriptors[1].Name);
+    }
+#endif
+
+    [Test]
+    public void AddArrayToSelf()
+    {
+      JArray a = new JArray(1, 2);
+      a.Add(a);
+
+      Assert.AreEqual(3, a.Count);
+      Assert.AreEqual(1, (int)a[0]);
+      Assert.AreEqual(2, (int)a[1]);
+      Assert.AreNotSame(a, a[2]);
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentException), ExpectedMessage = @"Set JArray values with invalid key value: ""badvalue"". Array position index expected.")]
+    public void SetValueWithInvalidIndex()
+    {
+      JArray a = new JArray();
+      a["badvalue"] = new JValue(3);
+    }
+
+    [Test]
+    public void SetValue()
+    {
+      object key = 0;
+
+      JArray a = new JArray((object)null);
+      a[key] = new JValue(3);
+
+      Assert.AreEqual(3, (int)a[key]);
+    }
+
+    [Test]
+    public void ReplaceAll()
+    {
+      JArray a = new JArray(new [] { 1, 2, 3 });
+      Assert.AreEqual(3, a.Count);
+      Assert.AreEqual(1, (int)a[0]);
+      Assert.AreEqual(2, (int)a[1]);
+      Assert.AreEqual(3, (int)a[2]);
+
+      a.ReplaceAll(1);
+      Assert.AreEqual(1, a.Count);
+      Assert.AreEqual(1, (int)a[0]);
+    }
+
+    [Test]
+    [ExpectedException(typeof(Exception), ExpectedMessage = "Unexpected end of content while loading JArray.")]
+    public void ParseIncomplete()
+    {
+      JArray.Parse("[1");
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JConstructorTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JConstructorTests.cs
new file mode 100644 (file)
index 0000000..43b981a
--- /dev/null
@@ -0,0 +1,69 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Linq;
+using NUnit.Framework;
+using System.IO;
+
+namespace Newtonsoft.Json.Tests.Linq
+{
+  public class JConstructorTests : TestFixtureBase
+  {
+    [Test]
+    public void Load()
+    {
+      JsonReader reader = new JsonTextReader(new StringReader("new Date(123)"));
+      reader.Read();
+
+      JConstructor constructor = JConstructor.Load(reader);
+      Assert.AreEqual("Date", constructor.Name);
+      Assert.IsTrue(JToken.DeepEquals(new JValue(123), constructor.Values().ElementAt(0)));
+    }
+
+    [Test]
+    public void CreateWithMultiValue()
+    {
+      JConstructor constructor = new JConstructor("Test", new List<int> { 1, 2, 3 });
+      Assert.AreEqual("Test", constructor.Name);
+      Assert.AreEqual(3, constructor.Children().Count());
+      Assert.AreEqual(1, (int)constructor.Children().ElementAt(0));
+      Assert.AreEqual(2, (int)constructor.Children().ElementAt(1));
+      Assert.AreEqual(3, (int)constructor.Children().ElementAt(2));
+    }
+
+    [Test]
+    public void Iterate()
+    {
+      JConstructor c = new JConstructor("MrConstructor", 1, 2, 3, 4, 5);
+
+      int i = 1;
+      foreach (JToken token in c)
+      {
+        Assert.AreEqual(i, (int)token);
+        i++;
+      }
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentException), ExpectedMessage = @"Set JConstructor values with invalid key value: ""badvalue"". Argument position index expected.")]
+    public void SetValueWithInvalidIndex()
+    {
+      JConstructor c = new JConstructor();
+      c["badvalue"] = new JValue(3);
+    }
+
+    [Test]
+    public void SetValue()
+    {
+      object key = 0;
+
+      JConstructor c = new JConstructor();
+      c.Name = "con";
+      c.Add(null);
+      c[key] = new JValue(3);
+
+      Assert.AreEqual(3, (int)c[key]);
+    }
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs
new file mode 100644 (file)
index 0000000..6a9216d
--- /dev/null
@@ -0,0 +1,1595 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Tests.TestObjects;
+using NUnit.Framework;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Converters;
+using System.IO;
+using System.Collections;
+using System.Collections.Specialized;
+#if !PocketPC && !SILVERLIGHT
+using System.Web.UI;
+#endif
+
+namespace Newtonsoft.Json.Tests.Linq
+{
+  public class JObjectTests : TestFixtureBase
+  {
+    [Test]
+    public void TryGetValue()
+    {
+      JObject o = new JObject();
+      o.Add("PropertyNameValue", new JValue(1));
+      Assert.AreEqual(1, o.Children().Count());
+
+      JToken t;
+      Assert.AreEqual(false, o.TryGetValue("sdf", out t));
+      Assert.AreEqual(null, t);
+
+      Assert.AreEqual(false, o.TryGetValue(null, out t));
+      Assert.AreEqual(null, t);
+
+      Assert.AreEqual(true, o.TryGetValue("PropertyNameValue", out t));
+      Assert.AreEqual(true, JToken.DeepEquals(new JValue(1), t));
+    }
+
+    [Test]
+    public void DictionaryItemShouldSet()
+    {
+      JObject o = new JObject();
+      o["PropertyNameValue"] = new JValue(1);
+      Assert.AreEqual(1, o.Children().Count());
+
+      JToken t;
+      Assert.AreEqual(true, o.TryGetValue("PropertyNameValue", out t));
+      Assert.AreEqual(true, JToken.DeepEquals(new JValue(1), t));
+
+      o["PropertyNameValue"] = new JValue(2);
+      Assert.AreEqual(1, o.Children().Count());
+
+      Assert.AreEqual(true, o.TryGetValue("PropertyNameValue", out t));
+      Assert.AreEqual(true, JToken.DeepEquals(new JValue(2), t));
+
+      o["PropertyNameValue"] = null;
+      Assert.AreEqual(1, o.Children().Count());
+
+      Assert.AreEqual(true, o.TryGetValue("PropertyNameValue", out t));
+      Assert.AreEqual(true, JToken.DeepEquals(new JValue((object)null), t));
+    }
+
+    [Test]
+    public void Remove()
+    {
+      JObject o = new JObject();
+      o.Add("PropertyNameValue", new JValue(1));
+      Assert.AreEqual(1, o.Children().Count());
+
+      Assert.AreEqual(false, o.Remove("sdf"));
+      Assert.AreEqual(false, o.Remove(null));
+      Assert.AreEqual(true, o.Remove("PropertyNameValue"));
+
+      Assert.AreEqual(0, o.Children().Count());
+    }
+
+    [Test]
+    public void GenericCollectionRemove()
+    {
+      JValue v = new JValue(1);
+      JObject o = new JObject();
+      o.Add("PropertyNameValue", v);
+      Assert.AreEqual(1, o.Children().Count());
+
+      Assert.AreEqual(false, ((ICollection<KeyValuePair<string, JToken>>)o).Remove(new KeyValuePair<string, JToken>("PropertyNameValue1", new JValue(1))));
+      Assert.AreEqual(false, ((ICollection<KeyValuePair<string, JToken>>)o).Remove(new KeyValuePair<string, JToken>("PropertyNameValue", new JValue(2))));
+      Assert.AreEqual(false, ((ICollection<KeyValuePair<string, JToken>>)o).Remove(new KeyValuePair<string, JToken>("PropertyNameValue", new JValue(1))));
+      Assert.AreEqual(true, ((ICollection<KeyValuePair<string, JToken>>)o).Remove(new KeyValuePair<string, JToken>("PropertyNameValue", v)));
+
+      Assert.AreEqual(0, o.Children().Count());
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Can not add property PropertyNameValue to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object.")]
+    public void DuplicatePropertyNameShouldThrow()
+    {
+      JObject o = new JObject();
+      o.Add("PropertyNameValue", null);
+      o.Add("PropertyNameValue", null);
+    }
+
+    [Test]
+    public void GenericDictionaryAdd()
+    {
+      JObject o = new JObject();
+
+      o.Add("PropertyNameValue", new JValue(1));
+      Assert.AreEqual(1, (int)o["PropertyNameValue"]);
+
+      o.Add("PropertyNameValue1", null);
+      Assert.AreEqual(null, ((JValue)o["PropertyNameValue1"]).Value);
+
+      Assert.AreEqual(2, o.Children().Count());
+    }
+
+    [Test]
+    public void GenericCollectionAdd()
+    {
+      JObject o = new JObject();
+      ((ICollection<KeyValuePair<string,JToken>>)o).Add(new KeyValuePair<string,JToken>("PropertyNameValue", new JValue(1)));
+
+      Assert.AreEqual(1, (int)o["PropertyNameValue"]);
+      Assert.AreEqual(1, o.Children().Count());
+    }
+
+    [Test]
+    public void GenericCollectionClear()
+    {
+      JObject o = new JObject();
+      o.Add("PropertyNameValue", new JValue(1));
+      Assert.AreEqual(1, o.Children().Count());
+
+      JProperty p = (JProperty)o.Children().ElementAt(0);
+
+      ((ICollection<KeyValuePair<string, JToken>>)o).Clear();
+      Assert.AreEqual(0, o.Children().Count());
+
+      Assert.AreEqual(null, p.Parent);
+    }
+
+    [Test]
+    public void GenericCollectionContains()
+    {
+      JValue v = new JValue(1);
+      JObject o = new JObject();
+      o.Add("PropertyNameValue", v);
+      Assert.AreEqual(1, o.Children().Count());
+
+      bool contains = ((ICollection<KeyValuePair<string, JToken>>)o).Contains(new KeyValuePair<string, JToken>("PropertyNameValue", new JValue(1)));
+      Assert.AreEqual(false, contains);
+
+      contains = ((ICollection<KeyValuePair<string, JToken>>)o).Contains(new KeyValuePair<string, JToken>("PropertyNameValue", v));
+      Assert.AreEqual(true, contains);
+
+      contains = ((ICollection<KeyValuePair<string, JToken>>)o).Contains(new KeyValuePair<string, JToken>("PropertyNameValue", new JValue(2)));
+      Assert.AreEqual(false, contains);
+
+      contains = ((ICollection<KeyValuePair<string, JToken>>)o).Contains(new KeyValuePair<string, JToken>("PropertyNameValue1", new JValue(1)));
+      Assert.AreEqual(false, contains);
+
+      contains = ((ICollection<KeyValuePair<string, JToken>>)o).Contains(default(KeyValuePair<string, JToken>));
+      Assert.AreEqual(false, contains);
+    }
+
+    [Test]
+    public void GenericDictionaryContains()
+    {
+      JObject o = new JObject();
+      o.Add("PropertyNameValue", new JValue(1));
+      Assert.AreEqual(1, o.Children().Count());
+
+      bool contains = ((IDictionary<string, JToken>)o).ContainsKey("PropertyNameValue");
+      Assert.AreEqual(true, contains);
+    }
+
+    [Test]
+    public void GenericCollectionCopyTo()
+    {
+      JObject o = new JObject();
+      o.Add("PropertyNameValue", new JValue(1));
+      o.Add("PropertyNameValue2", new JValue(2));
+      o.Add("PropertyNameValue3", new JValue(3));
+      Assert.AreEqual(3, o.Children().Count());
+
+      KeyValuePair<string, JToken>[] a = new KeyValuePair<string,JToken>[5];
+
+      ((ICollection<KeyValuePair<string, JToken>>)o).CopyTo(a, 1);
+
+      Assert.AreEqual(default(KeyValuePair<string,JToken>), a[0]);
+      
+      Assert.AreEqual("PropertyNameValue", a[1].Key);
+      Assert.AreEqual(1, (int)a[1].Value);
+
+      Assert.AreEqual("PropertyNameValue2", a[2].Key);
+      Assert.AreEqual(2, (int)a[2].Value);
+
+      Assert.AreEqual("PropertyNameValue3", a[3].Key);
+      Assert.AreEqual(3, (int)a[3].Value);
+
+      Assert.AreEqual(default(KeyValuePair<string, JToken>), a[4]);
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentNullException), ExpectedMessage = @"Value cannot be null.
+Parameter name: array")]
+    public void GenericCollectionCopyToNullArrayShouldThrow()
+    {
+      JObject o = new JObject();
+      ((ICollection<KeyValuePair<string, JToken>>)o).CopyTo(null, 0);
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentOutOfRangeException), ExpectedMessage = @"arrayIndex is less than 0.
+Parameter name: arrayIndex")]
+    public void GenericCollectionCopyToNegativeArrayIndexShouldThrow()
+    {
+      JObject o = new JObject();
+      ((ICollection<KeyValuePair<string, JToken>>)o).CopyTo(new KeyValuePair<string, JToken>[1], -1);
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentException), ExpectedMessage = @"arrayIndex is equal to or greater than the length of array.")]
+    public void GenericCollectionCopyToArrayIndexEqualGreaterToArrayLengthShouldThrow()
+    {
+      JObject o = new JObject();
+      ((ICollection<KeyValuePair<string, JToken>>)o).CopyTo(new KeyValuePair<string, JToken>[1], 1);
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentException), ExpectedMessage = @"The number of elements in the source JObject is greater than the available space from arrayIndex to the end of the destination array.")]
+    public void GenericCollectionCopyToInsufficientArrayCapacity()
+    {
+      JObject o = new JObject();
+      o.Add("PropertyNameValue", new JValue(1));
+      o.Add("PropertyNameValue2", new JValue(2));
+      o.Add("PropertyNameValue3", new JValue(3));
+
+      ((ICollection<KeyValuePair<string, JToken>>)o).CopyTo(new KeyValuePair<string, JToken>[3], 1);
+    }
+
+    [Test]
+    public void FromObjectRaw()
+    {
+      PersonRaw raw = new PersonRaw
+      {
+        FirstName = "FirstNameValue",
+        RawContent = new JRaw("[1,2,3,4,5]"),
+        LastName = "LastNameValue"
+      };
+
+      JObject o = JObject.FromObject(raw);
+
+      Assert.AreEqual("FirstNameValue", (string)o["first_name"]);
+      Assert.AreEqual(JTokenType.Raw, ((JValue)o["RawContent"]).Type);
+      Assert.AreEqual("[1,2,3,4,5]", (string)o["RawContent"]);
+      Assert.AreEqual("LastNameValue", (string)o["last_name"]);
+    }
+
+    [Test]
+    public void JTokenReader()
+    {
+      PersonRaw raw = new PersonRaw
+      {
+        FirstName = "FirstNameValue",
+        RawContent = new JRaw("[1,2,3,4,5]"),
+        LastName = "LastNameValue"
+      };
+
+      JObject o = JObject.FromObject(raw);
+
+      JsonReader reader = new JTokenReader(o);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.Raw, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.String, reader.TokenType);
+
+      Assert.IsTrue(reader.Read());
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      Assert.IsFalse(reader.Read());
+    }
+
+    [Test]
+    public void DeserializeFromRaw()
+    {
+      PersonRaw raw = new PersonRaw
+      {
+        FirstName = "FirstNameValue",
+        RawContent = new JRaw("[1,2,3,4,5]"),
+        LastName = "LastNameValue"
+      };
+
+      JObject o = JObject.FromObject(raw);
+
+      JsonReader reader = new JTokenReader(o);
+      JsonSerializer serializer = new JsonSerializer();
+      raw = (PersonRaw)serializer.Deserialize(reader, typeof(PersonRaw));
+
+      Assert.AreEqual("FirstNameValue", raw.FirstName);
+      Assert.AreEqual("LastNameValue", raw.LastName);
+      Assert.AreEqual("[1,2,3,4,5]", raw.RawContent.Value);
+    }
+
+    [Test]
+    [ExpectedException(typeof(Exception), ExpectedMessage = "Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray")]
+    public void Parse_ShouldThrowOnUnexpectedToken()
+    {
+      string json = @"[""prop""]";
+      JObject.Parse(json);
+    }
+
+    [Test]
+    public void ParseJavaScriptDate()
+    {
+      string json = @"[new Date(1207285200000)]";
+
+      JArray a = (JArray)JsonConvert.DeserializeObject(json);
+      JValue v = (JValue)a[0];
+
+      Assert.AreEqual(JsonConvert.ConvertJavaScriptTicksToDateTime(1207285200000), (DateTime)v);
+    }
+
+    [Test]
+    public void GenericValueCast()
+    {
+      string json = @"{""foo"":true}";
+      JObject o = (JObject)JsonConvert.DeserializeObject(json);
+      bool? value = o.Value<bool?>("foo");
+      Assert.AreEqual(true, value);
+
+      json = @"{""foo"":null}"; 
+      o = (JObject)JsonConvert.DeserializeObject(json);
+      value = o.Value<bool?>("foo");
+      Assert.AreEqual(null, value);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonReaderException), ExpectedMessage = "Invalid property identifier character: ]. Line 3, position 9.")]
+    public void Blog()
+    {
+      JObject person = JObject.Parse(@"{
+        ""name"": ""James"",
+        ]!#$THIS IS: BAD JSON![{}}}}]
+      }");
+
+      // Invalid property identifier character: ]. Line 3, position 9.
+    }
+
+    [Test]
+    public void RawChildValues()
+    {
+      JObject o = new JObject();
+      o["val1"] = new JRaw("1");
+      o["val2"] = new JRaw("1");
+
+      string json = o.ToString();
+
+      Assert.AreEqual(@"{
+  ""val1"": 1,
+  ""val2"": 1
+}", json);
+    }
+
+    [Test]
+    public void Iterate()
+    {
+      JObject o = new JObject();
+      o.Add("PropertyNameValue1", new JValue(1));
+      o.Add("PropertyNameValue2", new JValue(2));
+
+      JToken t = o;
+
+      int i = 1;
+      foreach (JProperty property in t)
+      {
+        Assert.AreEqual("PropertyNameValue" + i, property.Name);
+        Assert.AreEqual(i, (int)property.Value);
+
+        i++;
+      }
+    }
+
+    [Test]
+    public void KeyValuePairIterate()
+    {
+      JObject o = new JObject();
+      o.Add("PropertyNameValue1", new JValue(1));
+      o.Add("PropertyNameValue2", new JValue(2));
+
+      int i = 1;
+      foreach (KeyValuePair<string, JToken> pair in o)
+      {
+        Assert.AreEqual("PropertyNameValue" + i, pair.Key);
+        Assert.AreEqual(i, (int)pair.Value);
+
+        i++;
+      }
+    }
+
+    [Test]
+    public void WriteObjectNullStringValue()
+    {
+      string s = null;
+      JValue v = new JValue(s);
+      Assert.AreEqual(null, v.Value);
+      Assert.AreEqual(JTokenType.String, v.Type);
+
+      JObject o = new JObject();
+      o["title"] = v;
+
+      string output = o.ToString();
+      
+      Assert.AreEqual(@"{
+  ""title"": null
+}", output);
+    }
+
+    [Test]
+    public void Example()
+    {
+      string json = @"{
+        ""Name"": ""Apple"",
+        ""Expiry"": new Date(1230422400000),
+        ""Price"": 3.99,
+        ""Sizes"": [
+          ""Small"",
+          ""Medium"",
+          ""Large""
+        ]
+      }";
+
+      JObject o = JObject.Parse(json);
+
+      string name = (string)o["Name"];
+      // Apple
+
+      JArray sizes = (JArray)o["Sizes"];
+
+      string smallest = (string)sizes[0];
+      // Small
+
+      Console.WriteLine(name);
+      Console.WriteLine(smallest);
+    }
+
+    [Test]
+    public void DeserializeClassManually()
+    {
+      string jsonText = @"{
+  ""short"":
+  {
+    ""original"":""http://www.foo.com/"",
+    ""short"":""krehqk"",
+    ""error"":
+    {
+      ""code"":0,
+      ""msg"":""No action taken""
+    }
+  }
+}";
+
+      JObject json = JObject.Parse(jsonText);
+
+      Shortie shortie = new Shortie
+                        {
+                          Original = (string)json["short"]["original"],
+                          Short = (string)json["short"]["short"],
+                          Error = new ShortieException
+                                  {
+                                    Code = (int)json["short"]["error"]["code"],
+                                    ErrorMessage = (string)json["short"]["error"]["msg"]
+                                  }
+                        };
+
+      Console.WriteLine(shortie.Original);
+      // http://www.foo.com/
+
+      Console.WriteLine(shortie.Error.ErrorMessage);
+      // No action taken
+
+      Assert.AreEqual("http://www.foo.com/", shortie.Original);
+      Assert.AreEqual("krehqk", shortie.Short);
+      Assert.AreEqual(null, shortie.Shortened);
+      Assert.AreEqual(0, shortie.Error.Code);
+      Assert.AreEqual("No action taken", shortie.Error.ErrorMessage);
+    }
+
+    [Test]
+    public void JObjectContainingHtml()
+    {
+      JObject o = new JObject();
+      o["rc"] = new JValue(200);
+      o["m"] = new JValue("");
+      o["o"] = new JValue(@"<div class='s1'>
+    <div class='avatar'>                    
+        <a href='asdf'>asdf</a><br />
+        <strong>0</strong>
+    </div>
+    <div class='sl'>
+        <p>
+            444444444
+        </p>
+    </div>
+    <div class='clear'>
+    </div>                        
+</div>");
+
+      Assert.AreEqual(@"{
+  ""rc"": 200,
+  ""m"": """",
+  ""o"": ""<div class='s1'>\r\n    <div class='avatar'>                    \r\n        <a href='asdf'>asdf</a><br />\r\n        <strong>0</strong>\r\n    </div>\r\n    <div class='sl'>\r\n        <p>\r\n            444444444\r\n        </p>\r\n    </div>\r\n    <div class='clear'>\r\n    </div>                        \r\n</div>""
+}", o.ToString());
+    }
+
+    [Test]
+    public void ImplicitValueConversions()
+    {
+      JObject moss = new JObject();
+      moss["FirstName"] = new JValue("Maurice");
+      moss["LastName"] = new JValue("Moss");
+      moss["BirthDate"] = new JValue(new DateTime(1977, 12, 30));
+      moss["Department"] = new JValue("IT");
+      moss["JobTitle"] = new JValue("Support");
+
+      Console.WriteLine(moss.ToString());
+      //{
+      //  "FirstName": "Maurice",
+      //  "LastName": "Moss",
+      //  "BirthDate": "\/Date(252241200000+1300)\/",
+      //  "Department": "IT",
+      //  "JobTitle": "Support"
+      //}
+
+
+      JObject jen = new JObject();
+      jen["FirstName"] = "Jen";
+      jen["LastName"] = "Barber";
+      jen["BirthDate"] = new DateTime(1978, 3, 15);
+      jen["Department"] = "IT";
+      jen["JobTitle"] = "Manager";
+
+      Console.WriteLine(jen.ToString());
+      //{
+      //  "FirstName": "Jen",
+      //  "LastName": "Barber",
+      //  "BirthDate": "\/Date(258721200000+1300)\/",
+      //  "Department": "IT",
+      //  "JobTitle": "Manager"
+      //}
+    }
+
+    [Test]
+    public void ReplaceJPropertyWithJPropertyWithSameName()
+    {
+      JProperty p1 = new JProperty("Test1", 1);
+      JProperty p2 = new JProperty("Test2", "Two");
+
+      JObject o = new JObject(p1, p2);
+      IList l = o;
+      Assert.AreEqual(p1, l[0]);
+      Assert.AreEqual(p2, l[1]);
+
+      JProperty p3 = new JProperty("Test1", "III");
+
+      p1.Replace(p3);
+      Assert.AreEqual(null, p1.Parent);
+      Assert.AreEqual(l, p3.Parent);
+
+      Assert.AreEqual(p3, l[0]);
+      Assert.AreEqual(p2, l[1]);
+
+      Assert.AreEqual(2, l.Count);
+      Assert.AreEqual(2, o.Properties().Count());
+
+      JProperty p4 = new JProperty("Test4", "IV");
+
+      p2.Replace(p4);
+      Assert.AreEqual(null, p2.Parent);
+      Assert.AreEqual(l, p4.Parent);
+
+      Assert.AreEqual(p3, l[0]);
+      Assert.AreEqual(p4, l[1]);
+    }
+
+#if !PocketPC && !SILVERLIGHT && !NET20
+    [Test]
+    public void PropertyChanging()
+    {
+      object changing = null;
+      object changed = null;
+      int changingCount = 0;
+      int changedCount = 0;
+
+      JObject o = new JObject();
+      o.PropertyChanging += (sender, args) =>
+        {
+          JObject s = (JObject) sender;
+          changing = (s[args.PropertyName] != null) ? ((JValue)s[args.PropertyName]).Value : null;
+          changingCount++;
+        };
+      o.PropertyChanged += (sender, args) =>
+      {
+        JObject s = (JObject)sender;
+        changed = (s[args.PropertyName] != null) ? ((JValue)s[args.PropertyName]).Value : null;
+        changedCount++;
+      };
+
+      o["StringValue"] = "value1";
+      Assert.AreEqual(null, changing);
+      Assert.AreEqual("value1", changed);
+      Assert.AreEqual("value1", (string)o["StringValue"]);
+      Assert.AreEqual(1, changingCount);
+      Assert.AreEqual(1, changedCount);
+
+      o["StringValue"] = "value1";
+      Assert.AreEqual(1, changingCount);
+      Assert.AreEqual(1, changedCount);
+
+      o["StringValue"] = "value2";
+      Assert.AreEqual("value1", changing);
+      Assert.AreEqual("value2", changed);
+      Assert.AreEqual("value2", (string)o["StringValue"]);
+      Assert.AreEqual(2, changingCount);
+      Assert.AreEqual(2, changedCount);
+
+      o["StringValue"] = null;
+      Assert.AreEqual("value2", changing);
+      Assert.AreEqual(null, changed);
+      Assert.AreEqual(null, (string)o["StringValue"]);
+      Assert.AreEqual(3, changingCount);
+      Assert.AreEqual(3, changedCount);
+
+      o["NullValue"] = null;
+      Assert.AreEqual(null, changing);
+      Assert.AreEqual(null, changed);
+      Assert.AreEqual(new JValue((object)null), o["NullValue"]);
+      Assert.AreEqual(4, changingCount);
+      Assert.AreEqual(4, changedCount);
+
+      o["NullValue"] = null;
+      Assert.AreEqual(4, changingCount);
+      Assert.AreEqual(4, changedCount);
+    }
+#endif
+
+    [Test]
+    public void PropertyChanged()
+    {
+      object changed = null;
+      int changedCount = 0;
+
+      JObject o = new JObject();
+      o.PropertyChanged += (sender, args) =>
+      {
+        JObject s = (JObject)sender;
+        changed = (s[args.PropertyName] != null) ? ((JValue)s[args.PropertyName]).Value : null;
+        changedCount++;
+      };
+
+      o["StringValue"] = "value1";
+      Assert.AreEqual("value1", changed);
+      Assert.AreEqual("value1", (string)o["StringValue"]);
+      Assert.AreEqual(1, changedCount);
+
+      o["StringValue"] = "value1";
+      Assert.AreEqual(1, changedCount);
+
+      o["StringValue"] = "value2";
+      Assert.AreEqual("value2", changed);
+      Assert.AreEqual("value2", (string)o["StringValue"]);
+      Assert.AreEqual(2, changedCount);
+
+      o["StringValue"] = null;
+      Assert.AreEqual(null, changed);
+      Assert.AreEqual(null, (string)o["StringValue"]);
+      Assert.AreEqual(3, changedCount);
+
+      o["NullValue"] = null;
+      Assert.AreEqual(null, changed);
+      Assert.AreEqual(new JValue((object)null), o["NullValue"]);
+      Assert.AreEqual(4, changedCount);
+
+      o["NullValue"] = null;
+      Assert.AreEqual(4, changedCount);
+    }
+
+    [Test]
+    public void IListContains()
+    {
+      JProperty p = new JProperty("Test", 1);
+      IList l = new JObject(p);
+
+      Assert.IsTrue(l.Contains(p));
+      Assert.IsFalse(l.Contains(new JProperty("Test", 1)));
+    }
+
+    [Test]
+    public void IListIndexOf()
+    {
+      JProperty p = new JProperty("Test", 1);
+      IList l = new JObject(p);
+
+      Assert.AreEqual(0, l.IndexOf(p));
+      Assert.AreEqual(-1, l.IndexOf(new JProperty("Test", 1)));
+    }
+
+    [Test]
+    public void IListClear()
+    {
+      JProperty p = new JProperty("Test", 1);
+      IList l = new JObject(p);
+
+      Assert.AreEqual(1, l.Count);
+
+      l.Clear();
+
+      Assert.AreEqual(0, l.Count);
+    }
+
+    [Test]
+    public void IListCopyTo()
+    {
+      JProperty p1 = new JProperty("Test1", 1);
+      JProperty p2 = new JProperty("Test2", "Two");
+      IList l = new JObject(p1, p2);
+
+      object[] a = new object[l.Count];
+
+      l.CopyTo(a, 0);
+
+      Assert.AreEqual(p1, a[0]);
+      Assert.AreEqual(p2, a[1]);
+    }
+
+    [Test]
+    public void IListAdd()
+    {
+      JProperty p1 = new JProperty("Test1", 1);
+      JProperty p2 = new JProperty("Test2", "Two");
+      IList l = new JObject(p1, p2);
+
+      JProperty p3 = new JProperty("Test3", "III");
+
+      l.Add(p3);
+
+      Assert.AreEqual(3, l.Count);
+      Assert.AreEqual(p3, l[2]);
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject.")]
+    public void IListAddBadToken()
+    {
+      JProperty p1 = new JProperty("Test1", 1);
+      JProperty p2 = new JProperty("Test2", "Two");
+      IList l = new JObject(p1, p2);
+
+      l.Add(new JValue("Bad!"));
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Argument is not a JToken.")]
+    public void IListAddBadValue()
+    {
+      JProperty p1 = new JProperty("Test1", 1);
+      JProperty p2 = new JProperty("Test2", "Two");
+      IList l = new JObject(p1, p2);
+
+      l.Add("Bad!");
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Can not add property Test2 to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object.")]
+    public void IListAddPropertyWithExistingName()
+    {
+      JProperty p1 = new JProperty("Test1", 1);
+      JProperty p2 = new JProperty("Test2", "Two");
+      IList l = new JObject(p1, p2);
+
+      JProperty p3 = new JProperty("Test2", "II");
+
+      l.Add(p3);
+    }
+
+    [Test]
+    public void IListRemove()
+    {
+      JProperty p1 = new JProperty("Test1", 1);
+      JProperty p2 = new JProperty("Test2", "Two");
+      IList l = new JObject(p1, p2);
+
+      JProperty p3 = new JProperty("Test3", "III");
+
+      // won't do anything
+      l.Remove(p3);
+      Assert.AreEqual(2, l.Count);
+
+      l.Remove(p1);
+      Assert.AreEqual(1, l.Count);
+      Assert.IsFalse(l.Contains(p1));
+      Assert.IsTrue(l.Contains(p2));
+
+      l.Remove(p2);
+      Assert.AreEqual(0, l.Count);
+      Assert.IsFalse(l.Contains(p2));
+      Assert.AreEqual(null, p2.Parent);
+    }
+
+    [Test]
+    public void IListRemoveAt()
+    {
+      JProperty p1 = new JProperty("Test1", 1);
+      JProperty p2 = new JProperty("Test2", "Two");
+      IList l = new JObject(p1, p2);
+
+      // won't do anything
+      l.RemoveAt(0);
+
+      l.Remove(p1);
+      Assert.AreEqual(1, l.Count);
+
+      l.Remove(p2);
+      Assert.AreEqual(0, l.Count);
+    }
+
+    [Test]
+    public void IListInsert()
+    {
+      JProperty p1 = new JProperty("Test1", 1);
+      JProperty p2 = new JProperty("Test2", "Two");
+      IList l = new JObject(p1, p2);
+
+      JProperty p3 = new JProperty("Test3", "III");
+
+      l.Insert(1, p3);
+      Assert.AreEqual(l, p3.Parent);
+
+      Assert.AreEqual(p1, l[0]);
+      Assert.AreEqual(p3, l[1]);
+      Assert.AreEqual(p2, l[2]);
+    }
+
+    [Test]
+    public void IListIsReadOnly()
+    {
+      IList l = new JObject();
+      Assert.IsFalse(l.IsReadOnly);
+    }
+
+    [Test]
+    public void IListIsFixedSize()
+    {
+      IList l = new JObject();
+      Assert.IsFalse(l.IsFixedSize);
+    }
+
+    [Test]
+    public void IListSetItem()
+    {
+      JProperty p1 = new JProperty("Test1", 1);
+      JProperty p2 = new JProperty("Test2", "Two");
+      IList l = new JObject(p1, p2);
+
+      JProperty p3 = new JProperty("Test3", "III");
+
+      l[0] = p3;
+
+      Assert.AreEqual(p3, l[0]);
+      Assert.AreEqual(p2, l[1]);
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Can not add property Test3 to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object.")]
+    public void IListSetItemAlreadyExists()
+    {
+      JProperty p1 = new JProperty("Test1", 1);
+      JProperty p2 = new JProperty("Test2", "Two");
+      IList l = new JObject(p1, p2);
+
+      JProperty p3 = new JProperty("Test3", "III");
+
+      l[0] = p3;
+      l[1] = p3;
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentException), ExpectedMessage = @"Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject.")]
+    public void IListSetItemInvalid()
+    {
+      JProperty p1 = new JProperty("Test1", 1);
+      JProperty p2 = new JProperty("Test2", "Two");
+      IList l = new JObject(p1, p2);
+
+      l[0] = new JValue(true);
+    }
+
+    [Test]
+    public void IListSyncRoot()
+    {
+      JProperty p1 = new JProperty("Test1", 1);
+      JProperty p2 = new JProperty("Test2", "Two");
+      IList l = new JObject(p1, p2);
+
+      Assert.IsNotNull(l.SyncRoot);
+    }
+
+    [Test]
+    public void IListIsSynchronized()
+    {
+      JProperty p1 = new JProperty("Test1", 1);
+      JProperty p2 = new JProperty("Test2", "Two");
+      IList l = new JObject(p1, p2);
+
+      Assert.IsFalse(l.IsSynchronized);
+    }
+
+    [Test]
+    public void GenericListJTokenContains()
+    {
+      JProperty p = new JProperty("Test", 1);
+      IList<JToken> l = new JObject(p);
+
+      Assert.IsTrue(l.Contains(p));
+      Assert.IsFalse(l.Contains(new JProperty("Test", 1)));
+    }
+
+    [Test]
+    public void GenericListJTokenIndexOf()
+    {
+      JProperty p = new JProperty("Test", 1);
+      IList<JToken> l = new JObject(p);
+
+      Assert.AreEqual(0, l.IndexOf(p));
+      Assert.AreEqual(-1, l.IndexOf(new JProperty("Test", 1)));
+    }
+
+    [Test]
+    public void GenericListJTokenClear()
+    {
+      JProperty p = new JProperty("Test", 1);
+      IList<JToken> l = new JObject(p);
+
+      Assert.AreEqual(1, l.Count);
+
+      l.Clear();
+
+      Assert.AreEqual(0, l.Count);
+    }
+
+    [Test]
+    public void GenericListJTokenCopyTo()
+    {
+      JProperty p1 = new JProperty("Test1", 1);
+      JProperty p2 = new JProperty("Test2", "Two");
+      IList<JToken> l = new JObject(p1, p2);
+
+      JToken[] a = new JToken[l.Count];
+
+      l.CopyTo(a, 0);
+
+      Assert.AreEqual(p1, a[0]);
+      Assert.AreEqual(p2, a[1]);
+    }
+
+    [Test]
+    public void GenericListJTokenAdd()
+    {
+      JProperty p1 = new JProperty("Test1", 1);
+      JProperty p2 = new JProperty("Test2", "Two");
+      IList<JToken> l = new JObject(p1, p2);
+
+      JProperty p3 = new JProperty("Test3", "III");
+
+      l.Add(p3);
+
+      Assert.AreEqual(3, l.Count);
+      Assert.AreEqual(p3, l[2]);
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject.")]
+    public void GenericListJTokenAddBadToken()
+    {
+      JProperty p1 = new JProperty("Test1", 1);
+      JProperty p2 = new JProperty("Test2", "Two");
+      IList<JToken> l = new JObject(p1, p2);
+
+      l.Add(new JValue("Bad!"));
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject.")]
+    public void GenericListJTokenAddBadValue()
+    {
+      JProperty p1 = new JProperty("Test1", 1);
+      JProperty p2 = new JProperty("Test2", "Two");
+      IList<JToken> l = new JObject(p1, p2);
+
+      // string is implicitly converted to JValue
+      l.Add("Bad!");
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Can not add property Test2 to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object.")]
+    public void GenericListJTokenAddPropertyWithExistingName()
+    {
+      JProperty p1 = new JProperty("Test1", 1);
+      JProperty p2 = new JProperty("Test2", "Two");
+      IList<JToken> l = new JObject(p1, p2);
+
+      JProperty p3 = new JProperty("Test2", "II");
+
+      l.Add(p3);
+    }
+
+    [Test]
+    public void GenericListJTokenRemove()
+    {
+      JProperty p1 = new JProperty("Test1", 1);
+      JProperty p2 = new JProperty("Test2", "Two");
+      IList<JToken> l = new JObject(p1, p2);
+
+      JProperty p3 = new JProperty("Test3", "III");
+
+      // won't do anything
+      Assert.IsFalse(l.Remove(p3));
+      Assert.AreEqual(2, l.Count);
+
+      Assert.IsTrue(l.Remove(p1));
+      Assert.AreEqual(1, l.Count);
+      Assert.IsFalse(l.Contains(p1));
+      Assert.IsTrue(l.Contains(p2));
+
+      Assert.IsTrue(l.Remove(p2));
+      Assert.AreEqual(0, l.Count);
+      Assert.IsFalse(l.Contains(p2));
+      Assert.AreEqual(null, p2.Parent);
+    }
+
+    [Test]
+    public void GenericListJTokenRemoveAt()
+    {
+      JProperty p1 = new JProperty("Test1", 1);
+      JProperty p2 = new JProperty("Test2", "Two");
+      IList<JToken> l = new JObject(p1, p2);
+
+      // won't do anything
+      l.RemoveAt(0);
+
+      l.Remove(p1);
+      Assert.AreEqual(1, l.Count);
+
+      l.Remove(p2);
+      Assert.AreEqual(0, l.Count);
+    }
+
+    [Test]
+    public void GenericListJTokenInsert()
+    {
+      JProperty p1 = new JProperty("Test1", 1);
+      JProperty p2 = new JProperty("Test2", "Two");
+      IList<JToken> l = new JObject(p1, p2);
+
+      JProperty p3 = new JProperty("Test3", "III");
+
+      l.Insert(1, p3);
+      Assert.AreEqual(l, p3.Parent);
+
+      Assert.AreEqual(p1, l[0]);
+      Assert.AreEqual(p3, l[1]);
+      Assert.AreEqual(p2, l[2]);
+    }
+
+    [Test]
+    public void GenericListJTokenIsReadOnly()
+    {
+      IList<JToken> l = new JObject();
+      Assert.IsFalse(l.IsReadOnly);
+    }
+
+    [Test]
+    public void GenericListJTokenSetItem()
+    {
+      JProperty p1 = new JProperty("Test1", 1);
+      JProperty p2 = new JProperty("Test2", "Two");
+      IList<JToken> l = new JObject(p1, p2);
+
+      JProperty p3 = new JProperty("Test3", "III");
+
+      l[0] = p3;
+
+      Assert.AreEqual(p3, l[0]);
+      Assert.AreEqual(p2, l[1]);
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Can not add property Test3 to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object.")]
+    public void GenericListJTokenSetItemAlreadyExists()
+    {
+      JProperty p1 = new JProperty("Test1", 1);
+      JProperty p2 = new JProperty("Test2", "Two");
+      IList<JToken> l = new JObject(p1, p2);
+
+      JProperty p3 = new JProperty("Test3", "III");
+
+      l[0] = p3;
+      l[1] = p3;
+    }
+
+#if !SILVERLIGHT
+    [Test]
+    public void IBindingListSortDirection()
+    {
+      IBindingList l = new JObject();
+      Assert.AreEqual(ListSortDirection.Ascending, l.SortDirection);
+    }
+
+    [Test]
+    public void IBindingListSortProperty()
+    {
+      IBindingList l = new JObject();
+      Assert.AreEqual(null, l.SortProperty);
+    }
+
+    [Test]
+    public void IBindingListSupportsChangeNotification()
+    {
+      IBindingList l = new JObject();
+      Assert.AreEqual(true, l.SupportsChangeNotification);
+    }
+
+    [Test]
+    public void IBindingListSupportsSearching()
+    {
+      IBindingList l = new JObject();
+      Assert.AreEqual(false, l.SupportsSearching);
+    }
+
+    [Test]
+    public void IBindingListSupportsSorting()
+    {
+      IBindingList l = new JObject();
+      Assert.AreEqual(false, l.SupportsSorting);
+    }
+
+    [Test]
+    public void IBindingListAllowEdit()
+    {
+      IBindingList l = new JObject();
+      Assert.AreEqual(true, l.AllowEdit);
+    }
+
+    [Test]
+    public void IBindingListAllowNew()
+    {
+      IBindingList l = new JObject();
+      Assert.AreEqual(true, l.AllowNew);
+    }
+
+    [Test]
+    public void IBindingListAllowRemove()
+    {
+      IBindingList l = new JObject();
+      Assert.AreEqual(true, l.AllowRemove);
+    }
+
+    [Test]
+    public void IBindingListAddIndex()
+    {
+      IBindingList l = new JObject();
+      // do nothing
+      l.AddIndex(null);
+    }
+
+    [Test]
+    [ExpectedException(typeof(NotSupportedException))]
+    public void IBindingListApplySort()
+    {
+      IBindingList l = new JObject();
+      l.ApplySort(null, ListSortDirection.Ascending);
+    }
+
+    [Test]
+    [ExpectedException(typeof(NotSupportedException))]
+    public void IBindingListRemoveSort()
+    {
+      IBindingList l = new JObject();
+      l.RemoveSort();
+    }
+
+    [Test]
+    public void IBindingListRemoveIndex()
+    {
+      IBindingList l = new JObject();
+      // do nothing
+      l.RemoveIndex(null);
+    }
+
+    [Test]
+    [ExpectedException(typeof(NotSupportedException))]
+    public void IBindingListFind()
+    {
+      IBindingList l = new JObject();
+      l.Find(null, null);
+    }
+
+    [Test]
+    public void IBindingListIsSorted()
+    {
+      IBindingList l = new JObject();
+      Assert.AreEqual(false, l.IsSorted);
+    }
+
+    [Test]
+    [ExpectedException(typeof(Exception), ExpectedMessage = "Could not determine new value to add to 'Newtonsoft.Json.Linq.JObject'.")]
+    public void IBindingListAddNew()
+    {
+      IBindingList l = new JObject();
+      l.AddNew();
+    }
+
+    [Test]
+    public void IBindingListAddNewWithEvent()
+    {
+      JObject o = new JObject();
+      o.AddingNew += (s, e) => e.NewObject = new JProperty("Property!");
+
+      IBindingList l = o;
+      object newObject = l.AddNew();
+      Assert.IsNotNull(newObject);
+
+      JProperty p = (JProperty) newObject;
+      Assert.AreEqual("Property!", p.Name);
+      Assert.AreEqual(o, p.Parent);
+    }
+
+    [Test]
+    public void ITypedListGetListName()
+    {
+      JProperty p1 = new JProperty("Test1", 1);
+      JProperty p2 = new JProperty("Test2", "Two");
+      ITypedList l = new JObject(p1, p2);
+
+      Assert.AreEqual(string.Empty, l.GetListName(null));
+    }
+
+    [Test]
+    public void ITypedListGetItemProperties()
+    {
+      JProperty p1 = new JProperty("Test1", 1);
+      JProperty p2 = new JProperty("Test2", "Two");
+      ITypedList l = new JObject(p1, p2);
+
+      PropertyDescriptorCollection propertyDescriptors = l.GetItemProperties(null);
+      Assert.IsNull(propertyDescriptors);
+    }
+
+    [Test]
+    public void ListChanged()
+    {
+      JProperty p1 = new JProperty("Test1", 1);
+      JProperty p2 = new JProperty("Test2", "Two");
+      JObject o = new JObject(p1, p2);
+
+      ListChangedType? changedType = null;
+      int? index = null;
+      
+      o.ListChanged += (s, a) =>
+        {
+          changedType = a.ListChangedType;
+          index = a.NewIndex;
+        };
+
+      JProperty p3 = new JProperty("Test3", "III");
+
+      o.Add(p3);
+      Assert.AreEqual(changedType, ListChangedType.ItemAdded);
+      Assert.AreEqual(index, 2);
+      Assert.AreEqual(p3, ((IList<JToken>)o)[index.Value]);
+
+      JProperty p4 = new JProperty("Test4", "IV");
+
+      ((IList<JToken>) o)[index.Value] = p4;
+      Assert.AreEqual(changedType, ListChangedType.ItemChanged);
+      Assert.AreEqual(index, 2);
+      Assert.AreEqual(p4, ((IList<JToken>)o)[index.Value]);
+      Assert.IsFalse(((IList<JToken>)o).Contains(p3));
+      Assert.IsTrue(((IList<JToken>)o).Contains(p4));
+
+      o["Test1"] = 2;
+      Assert.AreEqual(changedType, ListChangedType.ItemChanged);
+      Assert.AreEqual(index, 0);
+      Assert.AreEqual(2, (int)o["Test1"]);
+    }
+#endif
+#if SILVERLIGHT || !(NET20 || NET35)
+    [Test]
+    public void CollectionChanged()
+    {
+      JProperty p1 = new JProperty("Test1", 1);
+      JProperty p2 = new JProperty("Test2", "Two");
+      JObject o = new JObject(p1, p2);
+
+      NotifyCollectionChangedAction? changedType = null;
+      int? index = null;
+
+      o.CollectionChanged += (s, a) =>
+      {
+        changedType = a.Action;
+        index = a.NewStartingIndex;
+      };
+
+      JProperty p3 = new JProperty("Test3", "III");
+
+      o.Add(p3);
+      Assert.AreEqual(changedType, NotifyCollectionChangedAction.Add);
+      Assert.AreEqual(index, 2);
+      Assert.AreEqual(p3, ((IList<JToken>)o)[index.Value]);
+
+      JProperty p4 = new JProperty("Test4", "IV");
+
+      ((IList<JToken>)o)[index.Value] = p4;
+      Assert.AreEqual(changedType, NotifyCollectionChangedAction.Replace);
+      Assert.AreEqual(index, 2);
+      Assert.AreEqual(p4, ((IList<JToken>)o)[index.Value]);
+      Assert.IsFalse(((IList<JToken>)o).Contains(p3));
+      Assert.IsTrue(((IList<JToken>)o).Contains(p4));
+
+      o["Test1"] = 2;
+      Assert.AreEqual(changedType, NotifyCollectionChangedAction.Replace);
+      Assert.AreEqual(index, 0);
+      Assert.AreEqual(2, (int)o["Test1"]);
+    }
+#endif
+
+    [Test]
+    public void GetGeocodeAddress()
+    {
+      string json = @"{
+  ""name"": ""Address: 435 North Mulford Road Rockford, IL 61107"",
+  ""Status"": {
+    ""code"": 200,
+    ""request"": ""geocode""
+  },
+  ""Placemark"": [ {
+    ""id"": ""p1"",
+    ""address"": ""435 N Mulford Rd, Rockford, IL 61107, USA"",
+    ""AddressDetails"": {
+   ""Accuracy"" : 8,
+   ""Country"" : {
+      ""AdministrativeArea"" : {
+         ""AdministrativeAreaName"" : ""IL"",
+         ""SubAdministrativeArea"" : {
+            ""Locality"" : {
+               ""LocalityName"" : ""Rockford"",
+               ""PostalCode"" : {
+                  ""PostalCodeNumber"" : ""61107""
+               },
+               ""Thoroughfare"" : {
+                  ""ThoroughfareName"" : ""435 N Mulford Rd""
+               }
+            },
+            ""SubAdministrativeAreaName"" : ""Winnebago""
+         }
+      },
+      ""CountryName"" : ""USA"",
+      ""CountryNameCode"" : ""US""
+   }
+},
+    ""ExtendedData"": {
+      ""LatLonBox"": {
+        ""north"": 42.2753076,
+        ""south"": 42.2690124,
+        ""east"": -88.9964645,
+        ""west"": -89.0027597
+      }
+    },
+    ""Point"": {
+      ""coordinates"": [ -88.9995886, 42.2721596, 0 ]
+    }
+  } ]
+}";
+
+      JObject o = JObject.Parse(json);
+
+      string searchAddress = (string)o["Placemark"][0]["AddressDetails"]["Country"]["AdministrativeArea"]["SubAdministrativeArea"]["Locality"]["Thoroughfare"]["ThoroughfareName"];
+      Assert.AreEqual("435 N Mulford Rd", searchAddress);
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Set JObject values with invalid key value: 0. Object property name expected.")]
+    public void SetValueWithInvalidPropertyName()
+    {
+      JObject o = new JObject();
+      o[0] = new JValue(3);
+    }
+
+    [Test]
+    public void SetValue()
+    {
+      object key = "TestKey";
+
+      JObject o = new JObject();
+      o[key] = new JValue(3);
+
+      Assert.AreEqual(3, (int)o[key]);
+    }
+
+    [Test]
+    public void ParseMultipleProperties()
+    {
+      string json = @"{
+        ""Name"": ""Name1"",
+        ""Name"": ""Name2""
+      }";
+
+      JObject o = JObject.Parse(json);
+      string value = (string)o["Name"];
+
+      Assert.AreEqual("Name2", value);
+    }
+
+    [Test]
+    public void WriteObjectNullDBNullValue()
+    {
+      DBNull dbNull = DBNull.Value;
+      JValue v = new JValue(dbNull);
+      Assert.AreEqual(DBNull.Value, v.Value);
+      Assert.AreEqual(JTokenType.Null, v.Type);
+
+      JObject o = new JObject();
+      o["title"] = v;
+
+      string output = o.ToString();
+      
+      Assert.AreEqual(@"{
+  ""title"": null
+}", output);
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Can not convert Object to String.")]
+    public void InvalidValueCastExceptionMessage()
+    {
+      string json = @"{
+  ""responseData"": {}, 
+  ""responseDetails"": null, 
+  ""responseStatus"": 200
+}";
+
+      JObject o = JObject.Parse(json);
+
+      string name = (string)o["responseData"];
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Can not convert Object to String.")]
+    public void InvalidPropertyValueCastExceptionMessage()
+    {
+      string json = @"{
+  ""responseData"": {}, 
+  ""responseDetails"": null, 
+  ""responseStatus"": 200
+}";
+
+      JObject o = JObject.Parse(json);
+
+      string name = (string)o.Property("responseData");
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonReaderException), ExpectedMessage = "JSON integer 307953220000517141511 is too large or small for an Int64.")]
+    public void NumberTooBigForInt64()
+    {
+      string json = @"{""code"": 307953220000517141511}";
+
+      JObject.Parse(json);
+    }
+
+    [Test]
+    [ExpectedException(typeof(Exception), ExpectedMessage = "Unexpected end of content while loading JObject.")]
+    public void ParseIncomplete()
+    {
+      JObject.Parse("{ foo:");
+    }
+
+    [Test]
+    public void LoadFromNestedObject()
+    {
+      string jsonText = @"{
+  ""short"":
+  {
+    ""error"":
+    {
+      ""code"":0,
+      ""msg"":""No action taken""
+    }
+  }
+}";
+
+      JsonReader reader = new JsonTextReader(new StringReader(jsonText));
+      reader.Read();
+      reader.Read();
+      reader.Read();
+      reader.Read();
+      reader.Read();
+
+      JObject o = (JObject)JToken.ReadFrom(reader);
+      Assert.IsNotNull(o);
+      Assert.AreEqual(@"{
+  ""code"": 0,
+  ""msg"": ""No action taken""
+}", o.ToString(Formatting.Indented));
+    }
+
+    [Test]
+    [ExpectedException(typeof(Exception), ExpectedMessage = "Unexpected end of content while loading JObject.")]
+    public void LoadFromNestedObjectIncomplete()
+    {
+      string jsonText = @"{
+  ""short"":
+  {
+    ""error"":
+    {
+      ""code"":0";
+
+      JsonReader reader = new JsonTextReader(new StringReader(jsonText));
+      reader.Read();
+      reader.Read();
+      reader.Read();
+      reader.Read();
+      reader.Read();
+
+      JToken.ReadFrom(reader);
+    }
+
+#if !SILVERLIGHT
+    [Test]
+    public void GetProperties()
+    {
+      JObject o = JObject.Parse("{'prop1':12,'prop2':'hi!','prop3':null,'prop4':[1,2,3]}");
+
+      ICustomTypeDescriptor descriptor = o;
+
+      PropertyDescriptorCollection properties = descriptor.GetProperties();
+      Assert.AreEqual(4, properties.Count);
+
+      PropertyDescriptor prop1 = properties[0];
+      Assert.AreEqual("prop1", prop1.Name);
+      Assert.AreEqual(typeof(long), prop1.PropertyType);
+      Assert.AreEqual(typeof(JObject), prop1.ComponentType);
+      Assert.AreEqual(false, prop1.CanResetValue(o));
+      Assert.AreEqual(false, prop1.ShouldSerializeValue(o));
+
+      PropertyDescriptor prop2 = properties[1];
+      Assert.AreEqual("prop2", prop2.Name);
+      Assert.AreEqual(typeof(string), prop2.PropertyType);
+      Assert.AreEqual(typeof(JObject), prop2.ComponentType);
+      Assert.AreEqual(false, prop2.CanResetValue(o));
+      Assert.AreEqual(false, prop2.ShouldSerializeValue(o));
+
+      PropertyDescriptor prop3 = properties[2];
+      Assert.AreEqual("prop3", prop3.Name);
+      Assert.AreEqual(typeof(object), prop3.PropertyType);
+      Assert.AreEqual(typeof(JObject), prop3.ComponentType);
+      Assert.AreEqual(false, prop3.CanResetValue(o));
+      Assert.AreEqual(false, prop3.ShouldSerializeValue(o));
+
+      PropertyDescriptor prop4 = properties[3];
+      Assert.AreEqual("prop4", prop4.Name);
+      Assert.AreEqual(typeof(JArray), prop4.PropertyType);
+      Assert.AreEqual(typeof(JObject), prop4.ComponentType);
+      Assert.AreEqual(false, prop4.CanResetValue(o));
+      Assert.AreEqual(false, prop4.ShouldSerializeValue(o));
+    }
+#endif
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JPathTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JPathTests.cs
new file mode 100644 (file)
index 0000000..b5eeefd
--- /dev/null
@@ -0,0 +1,322 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Tests.TestObjects;
+using NUnit.Framework;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Converters;
+using System.IO;
+using System.Collections;
+
+namespace Newtonsoft.Json.Tests.Linq
+{
+  public class JPathTests : TestFixtureBase
+  {
+    [Test]
+    public void SingleProperty()
+    {
+      JPath path = new JPath("Blah");
+      Assert.AreEqual(1, path.Parts.Count);
+      Assert.AreEqual("Blah", path.Parts[0]);
+    }
+
+    [Test]
+    public void TwoProperties()
+    {
+      JPath path = new JPath("Blah.Two");
+      Assert.AreEqual(2, path.Parts.Count);
+      Assert.AreEqual("Blah", path.Parts[0]);
+      Assert.AreEqual("Two", path.Parts[1]);
+    }
+
+    [Test]
+    public void SinglePropertyAndIndexer()
+    {
+      JPath path = new JPath("Blah[0]");
+      Assert.AreEqual(2, path.Parts.Count);
+      Assert.AreEqual("Blah", path.Parts[0]);
+      Assert.AreEqual(0, path.Parts[1]);
+    }
+
+    [Test]
+    public void MultiplePropertiesAndIndexers()
+    {
+      JPath path = new JPath("Blah[0].Two.Three[1].Four");
+      Assert.AreEqual(6, path.Parts.Count);
+      Assert.AreEqual("Blah", path.Parts[0]);
+      Assert.AreEqual(0, path.Parts[1]);
+      Assert.AreEqual("Two", path.Parts[2]);
+      Assert.AreEqual("Three", path.Parts[3]);
+      Assert.AreEqual(1, path.Parts[4]);
+      Assert.AreEqual("Four", path.Parts[5]);
+    }
+
+    [Test]
+    [ExpectedException(typeof(Exception), ExpectedMessage = @"Unexpected character while parsing path indexer: [")]
+    public void BadCharactersInIndexer()
+    {
+      new JPath("Blah[[0]].Two.Three[1].Four");
+    }
+
+    [Test]
+    [ExpectedException(typeof(Exception), ExpectedMessage = @"Path ended with open indexer. Expected ]")]
+    public void UnclosedIndexer()
+    {
+      new JPath("Blah[0");
+    }
+
+    [Test]
+    public void AdditionalDots()
+    {
+      JPath path = new JPath(".Blah..[0]..Two.Three....[1].Four.");
+      Assert.AreEqual(6, path.Parts.Count);
+      Assert.AreEqual("Blah", path.Parts[0]);
+      Assert.AreEqual(0, path.Parts[1]);
+      Assert.AreEqual("Two", path.Parts[2]);
+      Assert.AreEqual("Three", path.Parts[3]);
+      Assert.AreEqual(1, path.Parts[4]);
+      Assert.AreEqual("Four", path.Parts[5]);
+    }
+
+    [Test]
+    public void IndexerOnly()
+    {
+      JPath path = new JPath("[111119990]");
+      Assert.AreEqual(1, path.Parts.Count);
+      Assert.AreEqual(111119990, path.Parts[0]);
+    }
+
+    [Test]
+    [ExpectedException(typeof(Exception), ExpectedMessage = "Empty path indexer.")]
+    public void EmptyIndexer()
+    {
+      new JPath("[]");
+    }
+
+    [Test]
+    [ExpectedException(typeof(Exception), ExpectedMessage = "Unexpected character while parsing path: ]")]
+    public void IndexerCloseInProperty()
+    {
+      new JPath("]");
+    }
+
+    [Test]
+    public void AdjacentIndexers()
+    {
+      JPath path = new JPath("[1][0][0][" + int.MaxValue + "]");
+      Assert.AreEqual(4, path.Parts.Count);
+      Assert.AreEqual(1, path.Parts[0]);
+      Assert.AreEqual(0, path.Parts[1]);
+      Assert.AreEqual(0, path.Parts[2]);
+      Assert.AreEqual(int.MaxValue, path.Parts[3]);
+    }
+
+    [Test]
+    [ExpectedException(typeof(Exception), ExpectedMessage = "Unexpected character following indexer: B")]
+    public void MissingDotAfterIndexer()
+    {
+      new JPath("[1]Blah");
+    }
+
+    [Test]
+    public void EvaluateSingleProperty()
+    {
+      JObject o = new JObject(
+        new JProperty("Blah", 1));
+
+      JToken t = o.SelectToken("Blah");
+      Assert.IsNotNull(t);
+      Assert.AreEqual(JTokenType.Integer, t.Type);
+      Assert.AreEqual(1, (int)t);
+    }
+
+    [Test]
+    public void EvaluateMissingProperty()
+    {
+      JObject o = new JObject(
+        new JProperty("Blah", 1));
+
+      JToken t = o.SelectToken("Missing[1]");
+      Assert.IsNull(t);
+    }
+
+    [Test]
+    public void EvaluateIndexerOnObject()
+    {
+      JObject o = new JObject(
+        new JProperty("Blah", 1));
+
+      JToken t = o.SelectToken("[1]");
+      Assert.IsNull(t);
+    }
+
+    [Test]
+    [ExpectedException(typeof(Exception), ExpectedMessage = @"Index 1 not valid on JObject.")]
+    public void EvaluateIndexerOnObjectWithError()
+    {
+      JObject o = new JObject(
+        new JProperty("Blah", 1));
+
+      o.SelectToken("[1]", true);
+    }
+
+    [Test]
+    public void EvaluatePropertyOnArray()
+    {
+      JArray a = new JArray(1, 2, 3, 4, 5);
+
+      JToken t = a.SelectToken("BlahBlah");
+      Assert.IsNull(t);
+    }
+
+    [Test]
+    [ExpectedException(typeof(Exception), ExpectedMessage = @"Property 'BlahBlah' not valid on JArray.")]
+    public void EvaluatePropertyOnArrayWithError()
+    {
+      JArray a = new JArray(1, 2, 3, 4, 5);
+
+      a.SelectToken("BlahBlah", true);
+    }
+
+    [Test]
+    [ExpectedException(typeof(Exception), ExpectedMessage = @"Index 1 not valid on JConstructor.")]
+    public void EvaluateIndexerOnConstructorWithError()
+    {
+      JConstructor c = new JConstructor("Blah");
+
+      c.SelectToken("[1]", true);
+    }
+
+    [Test]
+    [ExpectedException(typeof(Exception), ExpectedMessage = "Property 'Missing' does not exist on JObject.")]
+    public void EvaluateMissingPropertyWithError()
+    {
+      JObject o = new JObject(
+        new JProperty("Blah", 1));
+
+      o.SelectToken("Missing", true);
+    }
+
+    [Test]
+    public void EvaluateOutOfBoundsIndxer()
+    {
+      JArray a = new JArray(1, 2, 3, 4, 5);
+
+      JToken t = a.SelectToken("[1000].Ha");
+      Assert.IsNull(t);
+    }
+
+    [Test]
+    [ExpectedException(typeof(IndexOutOfRangeException), ExpectedMessage = "Index 1000 outside the bounds of JArray.")]
+    public void EvaluateOutOfBoundsIndxerWithError()
+    {
+      JArray a = new JArray(1, 2, 3, 4, 5);
+
+      a.SelectToken("[1000].Ha", true);
+    }
+
+    [Test]
+    public void EvaluateArray()
+    {
+      JArray a = new JArray(1, 2, 3, 4);
+
+      JToken t = a.SelectToken("[1]");
+      Assert.IsNotNull(t);
+      Assert.AreEqual(JTokenType.Integer, t.Type);
+      Assert.AreEqual(2, (int)t);
+    }
+
+    [Test]
+    public void EvaluateSinglePropertyReturningArray()
+    {
+      JObject o = new JObject(
+        new JProperty("Blah", new [] { 1, 2, 3 }));
+
+      JToken t = o.SelectToken("Blah");
+      Assert.IsNotNull(t);
+      Assert.AreEqual(JTokenType.Array, t.Type);
+
+      t = o.SelectToken("Blah[2]");
+      Assert.AreEqual(JTokenType.Integer, t.Type);
+      Assert.AreEqual(3, (int)t);
+    }
+
+    [Test]
+    public void EvaluateLastSingleCharacterProperty()
+    {
+      JObject o2 = JObject.Parse("{'People':[{'N':'Jeff'}]}");
+      string a2 = (string)o2.SelectToken("People[0].N");
+
+      Assert.AreEqual("Jeff", a2);
+    }
+
+    [Test]
+    public void Example()
+    {
+      JObject o = JObject.Parse(@"{
+        ""Stores"": [
+          ""Lambton Quay"",
+          ""Willis Street""
+        ],
+        ""Manufacturers"": [
+          {
+            ""Name"": ""Acme Co"",
+            ""Products"": [
+              {
+                ""Name"": ""Anvil"",
+                ""Price"": 50
+              }
+            ]
+          },
+          {
+            ""Name"": ""Contoso"",
+            ""Products"": [
+              {
+                ""Name"": ""Elbow Grease"",
+                ""Price"": 99.95
+              },
+              {
+                ""Name"": ""Headlight Fluid"",
+                ""Price"": 4
+              }
+            ]
+          }
+        ]
+      }");
+
+      string name = (string)o.SelectToken("Manufacturers[0].Name");
+      // Acme Co
+
+      decimal productPrice = (decimal)o.SelectToken("Manufacturers[0].Products[0].Price");
+      // 50
+
+      string productName = (string)o.SelectToken("Manufacturers[1].Products[0].Name");
+      // Elbow Grease
+
+      Assert.AreEqual("Acme Co", name);
+      Assert.AreEqual(50m, productPrice);
+      Assert.AreEqual("Elbow Grease", productName);
+
+      IList<string> storeNames = o.SelectToken("Stores").Select(s => (string)s).ToList();
+      // Lambton Quay
+      // Willis Street
+
+      IList<string> firstProductNames = o["Manufacturers"].Select(m => (string)m.SelectToken("Products[1].Name")).ToList();
+      // null
+      // Headlight Fluid
+
+      decimal totalPrice = o["Manufacturers"].Sum(m => (decimal)m.SelectToken("Products[0].Price"));
+      // 149.95
+
+      Assert.AreEqual(2, storeNames.Count);
+      Assert.AreEqual("Lambton Quay", storeNames[0]);
+      Assert.AreEqual("Willis Street", storeNames[1]);
+      Assert.AreEqual(2, firstProductNames.Count);
+      Assert.AreEqual(null, firstProductNames[0]);
+      Assert.AreEqual("Headlight Fluid", firstProductNames[1]);
+      Assert.AreEqual(149.95m, totalPrice);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JPropertyTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JPropertyTests.cs
new file mode 100644 (file)
index 0000000..693d21e
--- /dev/null
@@ -0,0 +1,139 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Linq;
+using NUnit.Framework;
+using System.IO;
+
+namespace Newtonsoft.Json.Tests.Linq
+{
+  public class JPropertyTests : TestFixtureBase
+  {
+    [Test]
+    public void NullValue()
+    {
+      JProperty p = new JProperty("TestProperty", null);
+      Assert.IsNotNull(p.Value);
+      Assert.AreEqual(JTokenType.Null, p.Value.Type);
+      Assert.AreEqual(p, p.Value.Parent);
+
+      p.Value = null;
+      Assert.IsNotNull(p.Value);
+      Assert.AreEqual(JTokenType.Null, p.Value.Type);
+      Assert.AreEqual(p, p.Value.Parent);
+    }
+
+#if !SILVERLIGHT
+    [Test]
+    public void ListChanged()
+    {
+      JProperty p = new JProperty("TestProperty", null);
+      IBindingList l = p;
+
+      ListChangedType? listChangedType = null;
+      int? index = null;
+
+      l.ListChanged += (sender, args) =>
+      {
+        listChangedType = args.ListChangedType;
+        index = args.NewIndex;
+      };
+
+      p.Value = 1;
+
+      Assert.AreEqual(ListChangedType.ItemChanged, listChangedType.Value);
+      Assert.AreEqual(0, index.Value); 
+    }
+#endif
+
+    [Test]
+    public void IListCount()
+    {
+      JProperty p = new JProperty("TestProperty", null);
+      IList l = p;
+
+      Assert.AreEqual(1, l.Count);
+    }
+
+    [Test]
+    [ExpectedException(typeof(Exception), ExpectedMessage = "Cannot add or remove items from Newtonsoft.Json.Linq.JProperty.")]
+    public void IListClear()
+    {
+      JProperty p = new JProperty("TestProperty", null);
+      IList l = p;
+
+      l.Clear();
+    }
+
+    [Test]
+    [ExpectedException(typeof(Exception), ExpectedMessage = "Newtonsoft.Json.Linq.JProperty cannot have multiple values.")]
+    public void IListAdd()
+    {
+      JProperty p = new JProperty("TestProperty", null);
+      IList l = p;
+
+      l.Add(null);
+    }
+
+    [Test]
+    [ExpectedException(typeof(Exception), ExpectedMessage = "Cannot add or remove items from Newtonsoft.Json.Linq.JProperty.")]
+    public void IListRemove()
+    {
+      JProperty p = new JProperty("TestProperty", null);
+      IList l = p;
+
+      l.Remove(p.Value);
+    }
+
+    [Test]
+    public void Load()
+    {
+      JsonReader reader = new JsonTextReader(new StringReader("{'propertyname':['value1']}"));
+      reader.Read();
+
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+      reader.Read();
+
+      JProperty property = JProperty.Load(reader);
+      Assert.AreEqual("propertyname", property.Name);
+      Assert.IsTrue(JToken.DeepEquals(JArray.Parse("['value1']"), property.Value));
+
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+      reader = new JsonTextReader(new StringReader("{'propertyname':null}"));
+      reader.Read();
+
+      Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+      reader.Read();
+
+      property = JProperty.Load(reader);
+      Assert.AreEqual("propertyname", property.Name);
+      Assert.IsTrue(JToken.DeepEquals(new JValue(null, JTokenType.Null), property.Value));
+
+      Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+    }
+
+    [Test]
+    public void MultiContentConstructor()
+    {
+      JProperty p = new JProperty("error", new List<string> { "one", "two" });
+      JArray a = (JArray) p.Value;
+
+      Assert.AreEqual(a.Count, 2);
+      Assert.AreEqual("one", (string)a[0]);
+      Assert.AreEqual("two", (string)a[1]);
+    }
+
+    [Test]
+    [ExpectedException(typeof(Exception), ExpectedMessage = "Newtonsoft.Json.Linq.JProperty cannot have multiple values.")]
+    public void IListGenericAdd()
+    {
+      IList<JToken> t = new JProperty("error", new List<string> { "one", "two" });
+      t.Add(1);
+      t.Add(2);
+    }
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JRawTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JRawTests.cs
new file mode 100644 (file)
index 0000000..1cd8c74
--- /dev/null
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using Newtonsoft.Json.Linq;
+
+namespace Newtonsoft.Json.Tests.Linq
+{
+  public class JRawTests : TestFixtureBase
+  {
+    [Test]
+    public void RawEquals()
+    {
+      JRaw r1 = new JRaw("raw1");
+      JRaw r2 = new JRaw("raw1");
+      JRaw r3 = new JRaw("raw2");
+
+      Assert.IsTrue(JToken.DeepEquals(r1, r2));
+      Assert.IsFalse(JToken.DeepEquals(r1, r3));
+    }
+
+    [Test]
+    public void RawClone()
+    {
+      JRaw r1 = new JRaw("raw1");
+      JToken r2 = r1.CloneToken();
+
+      Assert.IsInstanceOfType(typeof(JRaw), r2);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JTokenEqualityComparerTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JTokenEqualityComparerTests.cs
new file mode 100644 (file)
index 0000000..30a0e41
--- /dev/null
@@ -0,0 +1,60 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using Newtonsoft.Json.Linq;
+
+namespace Newtonsoft.Json.Tests.Linq
+{
+  public class JTokenEqualityComparerTests : TestFixtureBase
+  {
+    [Test]
+    public void JValueDictionary()
+    {
+      Dictionary<JToken, int> dic = new Dictionary<JToken, int>(JToken.EqualityComparer);
+      JValue v11 = new JValue(1);
+      JValue v12 = new JValue(1);
+
+      dic[v11] = 1;
+      dic[v12] += 1;
+      Assert.AreEqual(2, dic[v11]);
+    }
+
+    [Test]
+    public void JArrayDictionary()
+    {
+      Dictionary<JToken, int> dic = new Dictionary<JToken, int>(JToken.EqualityComparer);
+      JArray v11 = new JArray();
+      JArray v12 = new JArray();
+
+      dic[v11] = 1;
+      dic[v12] += 1;
+      Assert.AreEqual(2, dic[v11]);
+    }
+
+    [Test]
+    public void JObjectDictionary()
+    {
+      Dictionary<JToken, int> dic = new Dictionary<JToken, int>(JToken.EqualityComparer);
+      JObject v11 = new JObject() { { "Test", new JValue(1) }, { "Test1", new JValue(1) } };
+      JObject v12 = new JObject() { { "Test", new JValue(1) }, { "Test1", new JValue(1) } };
+
+      dic[v11] = 1;
+      dic[v12] += 1;
+      Assert.AreEqual(2, dic[v11]);
+    }
+
+    [Test]
+    public void JConstructorDictionary()
+    {
+      Dictionary<JToken, int> dic = new Dictionary<JToken, int>(JToken.EqualityComparer);
+      JConstructor v11 = new JConstructor("ConstructorValue");
+      JConstructor v12 = new JConstructor("ConstructorValue");
+
+      dic[v11] = 1;
+      dic[v12] += 1;
+      Assert.AreEqual(2, dic[v11]);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JTokenReaderTest.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JTokenReaderTest.cs
new file mode 100644 (file)
index 0000000..d881c8d
--- /dev/null
@@ -0,0 +1,309 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using NUnit.Framework;
+using Newtonsoft.Json;
+using System.IO;
+using Newtonsoft.Json.Linq;
+
+namespace Newtonsoft.Json.Tests.Linq
+{
+  public class JTokenReaderTest : TestFixtureBase
+  {
+#if !PocketPC && !NET20
+    [Test]
+    public void YahooFinance()
+    {
+      JObject o =
+        new JObject(
+          new JProperty("Test1", new DateTime(2000, 10, 15, 5, 5, 5, DateTimeKind.Utc)),
+          new JProperty("Test2", new DateTimeOffset(2000, 10, 15, 5, 5, 5, new TimeSpan(11, 11, 0))),
+          new JProperty("Test3", "Test3Value"),
+          new JProperty("Test4", null)
+        );
+
+      using (JTokenReader jsonReader = new JTokenReader(o))
+      {
+        IJsonLineInfo lineInfo = jsonReader;
+
+        jsonReader.Read();
+        Assert.AreEqual(JsonToken.StartObject, jsonReader.TokenType);
+        Assert.AreEqual(false, lineInfo.HasLineInfo());
+
+        jsonReader.Read();
+        Assert.AreEqual(JsonToken.PropertyName, jsonReader.TokenType);
+        Assert.AreEqual("Test1", jsonReader.Value);
+        Assert.AreEqual(false, lineInfo.HasLineInfo());
+
+        jsonReader.Read();
+        Assert.AreEqual(JsonToken.Date, jsonReader.TokenType);
+        Assert.AreEqual(new DateTime(2000, 10, 15, 5, 5, 5, DateTimeKind.Utc), jsonReader.Value);
+        Assert.AreEqual(false, lineInfo.HasLineInfo());
+        Assert.AreEqual(0, lineInfo.LinePosition);
+        Assert.AreEqual(0, lineInfo.LineNumber);
+
+        jsonReader.Read();
+        Assert.AreEqual(JsonToken.PropertyName, jsonReader.TokenType);
+        Assert.AreEqual("Test2", jsonReader.Value);
+
+        jsonReader.Read();
+        Assert.AreEqual(JsonToken.Date, jsonReader.TokenType);
+        Assert.AreEqual(new DateTimeOffset(2000, 10, 15, 5, 5, 5, new TimeSpan(11, 11, 0)), jsonReader.Value);
+
+        jsonReader.Read();
+        Assert.AreEqual(JsonToken.PropertyName, jsonReader.TokenType);
+        Assert.AreEqual("Test3", jsonReader.Value);
+
+        jsonReader.Read();
+        Assert.AreEqual(JsonToken.String, jsonReader.TokenType);
+        Assert.AreEqual("Test3Value", jsonReader.Value);
+
+        jsonReader.Read();
+        Assert.AreEqual(JsonToken.PropertyName, jsonReader.TokenType);
+        Assert.AreEqual("Test4", jsonReader.Value);
+
+        jsonReader.Read();
+        Assert.AreEqual(JsonToken.Null, jsonReader.TokenType);
+        Assert.AreEqual(null, jsonReader.Value);
+
+        Assert.IsTrue(jsonReader.Read());
+        Assert.AreEqual(JsonToken.EndObject, jsonReader.TokenType);
+
+        Assert.IsFalse(jsonReader.Read());
+      }
+
+      using (JsonReader jsonReader = new JTokenReader(o.Property("Test2")))
+      {
+        Assert.IsTrue(jsonReader.Read());
+        Assert.AreEqual(JsonToken.PropertyName, jsonReader.TokenType);
+        Assert.AreEqual("Test2", jsonReader.Value);
+
+        Assert.IsTrue(jsonReader.Read());
+        Assert.AreEqual(JsonToken.Date, jsonReader.TokenType);
+        Assert.AreEqual(new DateTimeOffset(2000, 10, 15, 5, 5, 5, new TimeSpan(11, 11, 0)), jsonReader.Value);
+
+        Assert.IsFalse(jsonReader.Read());
+      }
+    }
+#endif
+
+    [Test]
+    public void ReadLineInfo()
+    {
+      string input = @"{
+  CPU: 'Intel',
+  Drives: [
+    'DVD read/writer',
+    ""500 gigabyte hard drive""
+  ]
+}";
+
+      StringReader sr = new StringReader(input);
+
+      JObject o = JObject.Parse(input);
+
+      using (JTokenReader jsonReader = new JTokenReader(o))
+      {
+        IJsonLineInfo lineInfo = jsonReader;
+
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.None);
+        Assert.AreEqual(0, lineInfo.LineNumber);
+        Assert.AreEqual(0, lineInfo.LinePosition);
+        Assert.AreEqual(false, lineInfo.HasLineInfo());
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.StartObject);
+        Assert.AreEqual(1, lineInfo.LineNumber);
+        Assert.AreEqual(1, lineInfo.LinePosition);
+        Assert.AreEqual(true, lineInfo.HasLineInfo());
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.PropertyName);
+        Assert.AreEqual(jsonReader.Value, "CPU");
+        Assert.AreEqual(2, lineInfo.LineNumber);
+        Assert.AreEqual(6, lineInfo.LinePosition);
+        Assert.AreEqual(true, lineInfo.HasLineInfo());
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.String);
+        Assert.AreEqual(jsonReader.Value, "Intel");
+        Assert.AreEqual(2, lineInfo.LineNumber);
+        Assert.AreEqual(14, lineInfo.LinePosition);
+        Assert.AreEqual(true, lineInfo.HasLineInfo());
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.PropertyName);
+        Assert.AreEqual(jsonReader.Value, "Drives");
+        Assert.AreEqual(3, lineInfo.LineNumber);
+        Assert.AreEqual(9, lineInfo.LinePosition);
+        Assert.AreEqual(true, lineInfo.HasLineInfo());
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.StartArray);
+        Assert.AreEqual(3, lineInfo.LineNumber);
+        Assert.AreEqual(11, lineInfo.LinePosition);
+        Assert.AreEqual(true, lineInfo.HasLineInfo());
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.String);
+        Assert.AreEqual(jsonReader.Value, "DVD read/writer");
+        Assert.AreEqual(4, lineInfo.LineNumber);
+        Assert.AreEqual(21, lineInfo.LinePosition);
+        Assert.AreEqual(true, lineInfo.HasLineInfo());
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.String);
+        Assert.AreEqual(jsonReader.Value, "500 gigabyte hard drive");
+        Assert.AreEqual(5, lineInfo.LineNumber);
+        Assert.AreEqual(29, lineInfo.LinePosition);
+        Assert.AreEqual(true, lineInfo.HasLineInfo());
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.EndArray);
+        Assert.AreEqual(0, lineInfo.LineNumber);
+        Assert.AreEqual(0, lineInfo.LinePosition);
+        Assert.AreEqual(false, lineInfo.HasLineInfo());
+
+        jsonReader.Read();
+        Assert.AreEqual(jsonReader.TokenType, JsonToken.EndObject);
+        Assert.AreEqual(0, lineInfo.LineNumber);
+        Assert.AreEqual(0, lineInfo.LinePosition);
+        Assert.AreEqual(false, lineInfo.HasLineInfo());
+      }
+    }
+
+    [Test]
+    public void ReadBytes()
+    {
+      byte[] data = Encoding.UTF8.GetBytes("Hello world!");
+
+      JObject o =
+        new JObject(
+          new JProperty("Test1", data)
+        );
+
+      using (JTokenReader jsonReader = new JTokenReader(o))
+      {
+        jsonReader.Read();
+        Assert.AreEqual(JsonToken.StartObject, jsonReader.TokenType);
+
+        jsonReader.Read();
+        Assert.AreEqual(JsonToken.PropertyName, jsonReader.TokenType);
+        Assert.AreEqual("Test1", jsonReader.Value);
+
+        byte[] readBytes = jsonReader.ReadAsBytes();
+        Assert.AreEqual(data, readBytes);
+
+        Assert.IsTrue(jsonReader.Read());
+        Assert.AreEqual(JsonToken.EndObject, jsonReader.TokenType);
+
+        Assert.IsFalse(jsonReader.Read());
+      }
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonReaderException), ExpectedMessage = "Error reading bytes. Expected bytes but got Integer.")]
+    public void ReadBytesFailure()
+    {
+      JObject o =
+        new JObject(
+          new JProperty("Test1", 1)
+        );
+
+      using (JTokenReader jsonReader = new JTokenReader(o))
+      {
+        jsonReader.Read();
+        Assert.AreEqual(JsonToken.StartObject, jsonReader.TokenType);
+
+        jsonReader.Read();
+        Assert.AreEqual(JsonToken.PropertyName, jsonReader.TokenType);
+        Assert.AreEqual("Test1", jsonReader.Value);
+
+        jsonReader.ReadAsBytes();
+      }
+    }
+
+    public class HasBytes
+    {
+      public byte[] Bytes { get; set; }
+    }
+
+    [Test]
+    public void ReadBytesFromString()
+    {
+      var bytes = new HasBytes { Bytes = new byte[] { 1, 2, 3, 4 } };
+      var json = JsonConvert.SerializeObject(bytes);
+
+      TextReader textReader = new StringReader(json);
+      JsonReader jsonReader = new JsonTextReader(textReader);
+
+      var jToken = JToken.ReadFrom(jsonReader);
+
+      jsonReader = new JTokenReader(jToken);
+
+      var result2 = (HasBytes)JsonSerializer.Create(null)
+                 .Deserialize(jsonReader, typeof(HasBytes));
+
+      Assert.AreEqual(new byte[] { 1, 2, 3, 4 }, result2.Bytes);
+    }
+
+    [Test]
+    public void ReadBytesFromEmptyString()
+    {
+      var bytes = new HasBytes { Bytes = new byte[0] };
+      var json = JsonConvert.SerializeObject(bytes);
+
+      TextReader textReader = new StringReader(json);
+      JsonReader jsonReader = new JsonTextReader(textReader);
+
+      var jToken = JToken.ReadFrom(jsonReader);
+
+      jsonReader = new JTokenReader(jToken);
+
+      var result2 = (HasBytes)JsonSerializer.Create(null)
+                 .Deserialize(jsonReader, typeof(HasBytes));
+
+      Assert.AreEqual(new byte[0], result2.Bytes);
+    }
+
+    public class ReadAsBytesTestObject
+    {
+      public byte[] Data;
+    }
+
+    [Test]
+    public void ReadAsBytesNull()
+    {
+      JsonSerializer s = new JsonSerializer();
+
+      JToken nullToken = JToken.ReadFrom(new JsonTextReader(new StringReader("{ Data: null }")));
+      ReadAsBytesTestObject x = s.Deserialize<ReadAsBytesTestObject>(new JTokenReader(nullToken));
+      Assert.IsNull(x.Data);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs
new file mode 100644 (file)
index 0000000..7d6947b
--- /dev/null
@@ -0,0 +1,740 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Converters;
+using NUnit.Framework;
+using Newtonsoft.Json.Linq;
+using System.IO;
+
+namespace Newtonsoft.Json.Tests.Linq
+{
+  public class JTokenTests : TestFixtureBase
+  {
+    [Test]
+    public void ReadFrom()
+    {
+      JObject o = (JObject)JToken.ReadFrom(new JsonTextReader(new StringReader("{'pie':true}")));
+      Assert.AreEqual(true, (bool)o["pie"]);
+
+      JArray a = (JArray)JToken.ReadFrom(new JsonTextReader(new StringReader("[1,2,3]")));
+      Assert.AreEqual(1, (int)a[0]);
+      Assert.AreEqual(2, (int)a[1]);
+      Assert.AreEqual(3, (int)a[2]);
+
+      JsonReader reader = new JsonTextReader(new StringReader("{'pie':true}"));
+      reader.Read();
+      reader.Read();
+
+      JProperty p = (JProperty)JToken.ReadFrom(reader);
+      Assert.AreEqual("pie", p.Name);
+      Assert.AreEqual(true, (bool)p.Value);
+
+      JConstructor c = (JConstructor)JToken.ReadFrom(new JsonTextReader(new StringReader("new Date(1)")));
+      Assert.AreEqual("Date", c.Name);
+      Assert.IsTrue(JToken.DeepEquals(new JValue(1), c.Values().ElementAt(0)));
+
+      JValue v;
+
+      v = (JValue)JToken.ReadFrom(new JsonTextReader(new StringReader(@"""stringvalue""")));
+      Assert.AreEqual("stringvalue", (string)v);
+
+      v = (JValue)JToken.ReadFrom(new JsonTextReader(new StringReader(@"1")));
+      Assert.AreEqual(1, (int)v);
+
+      v = (JValue)JToken.ReadFrom(new JsonTextReader(new StringReader(@"1.1")));
+      Assert.AreEqual(1.1, (double)v);
+    }
+
+    [Test]
+    public void Load()
+    {
+      JObject o = (JObject)JToken.Load(new JsonTextReader(new StringReader("{'pie':true}")));
+      Assert.AreEqual(true, (bool)o["pie"]);
+    }
+
+    [Test]
+    public void Parse()
+    {
+      JObject o = (JObject)JToken.Parse("{'pie':true}");
+      Assert.AreEqual(true, (bool)o["pie"]);
+    }
+
+    [Test]
+    public void Parent()
+    {
+      JArray v = new JArray(new JConstructor("TestConstructor"), new JValue(new DateTime(2000, 12, 20)));
+
+      Assert.AreEqual(null, v.Parent);
+
+      JObject o =
+        new JObject(
+          new JProperty("Test1", v),
+          new JProperty("Test2", "Test2Value"),
+          new JProperty("Test3", "Test3Value"),
+          new JProperty("Test4", null)
+        );
+
+      Assert.AreEqual(o.Property("Test1"), v.Parent);
+
+      JProperty p = new JProperty("NewProperty", v);
+
+      // existing value should still have same parent
+      Assert.AreEqual(o.Property("Test1"), v.Parent);
+
+      // new value should be cloned
+      Assert.AreNotSame(p.Value, v);
+
+      Assert.AreEqual((DateTime)((JValue)p.Value[1]).Value, (DateTime)((JValue)v[1]).Value);
+
+      Assert.AreEqual(v, o["Test1"]);
+
+      Assert.AreEqual(null, o.Parent);
+      JProperty o1 = new JProperty("O1", o);
+      Assert.AreEqual(o, o1.Value);
+
+      Assert.AreNotEqual(null, o.Parent);
+      JProperty o2 = new JProperty("O2", o);
+
+      Assert.AreNotSame(o1.Value, o2.Value);
+      Assert.AreEqual(o1.Value.Children().Count(), o2.Value.Children().Count());
+      Assert.AreEqual(false, JToken.DeepEquals(o1, o2));
+      Assert.AreEqual(true, JToken.DeepEquals(o1.Value, o2.Value));
+    }
+
+    [Test]
+    public void Next()
+    {
+      JArray a =
+        new JArray(
+          5,
+          6,
+          new JArray(7, 8),
+          new JArray(9, 10)
+        );
+
+      JToken next = a[0].Next;
+      Assert.AreEqual(6, (int)next);
+
+      next = next.Next;
+      Assert.IsTrue(JToken.DeepEquals(new JArray(7, 8), next));
+      next = next.Next;
+      Assert.IsTrue(JToken.DeepEquals(new JArray(9, 10), next));
+
+      next = next.Next;
+      Assert.IsNull(next);
+    }
+
+    [Test]
+    public void Previous()
+    {
+      JArray a =
+        new JArray(
+          5,
+          6,
+          new JArray(7, 8),
+          new JArray(9, 10)
+        );
+
+      JToken previous = a[3].Previous;
+      Assert.IsTrue(JToken.DeepEquals(new JArray(7, 8), previous));
+
+      previous = previous.Previous;
+      Assert.AreEqual(6, (int)previous);
+
+      previous = previous.Previous;
+      Assert.AreEqual(5, (int)previous);
+
+      previous = previous.Previous;
+      Assert.IsNull(previous);
+    }
+
+    [Test]
+    public void Children()
+    {
+      JArray a =
+        new JArray(
+          5,
+          new JArray(1),
+          new JArray(1, 2),
+          new JArray(1, 2, 3)
+        );
+
+      Assert.AreEqual(4, a.Count());
+      Assert.AreEqual(3, a.Children<JArray>().Count());
+    }
+
+    [Test]
+    public void BeforeAfter()
+    {
+      JArray a =
+        new JArray(
+          5,
+          new JArray(1, 2, 3),
+          new JArray(1, 2, 3),
+          new JArray(1, 2, 3)
+        );
+
+      Assert.AreEqual(5, (int)a[1].Previous);
+      Assert.AreEqual(2, a[2].BeforeSelf().Count());
+      //Assert.AreEqual(2, a[2].AfterSelf().Count());
+    }
+
+    [Test]
+    public void Casting()
+    {
+      Assert.AreEqual(new DateTime(2000, 12, 20), (DateTime)new JValue(new DateTime(2000, 12, 20)));
+#if !PocketPC && !NET20
+      Assert.AreEqual(new DateTimeOffset(2000, 12, 20, 23, 50, 10, TimeSpan.Zero), (DateTimeOffset)new JValue(new DateTimeOffset(2000, 12, 20, 23, 50, 10, TimeSpan.Zero)));
+      Assert.AreEqual(null, (DateTimeOffset?)new JValue((DateTimeOffset?)null));
+      Assert.AreEqual(null, (DateTimeOffset?)(JValue)null);
+#endif
+      Assert.AreEqual(true, (bool)new JValue(true));
+      Assert.AreEqual(true, (bool?)new JValue(true));
+      Assert.AreEqual(null, (bool?)((JValue)null));
+      Assert.AreEqual(null, (bool?)new JValue((object)null));
+      Assert.AreEqual(10, (long)new JValue(10));
+      Assert.AreEqual(null, (long?)new JValue((long?)null));
+      Assert.AreEqual(null, (long?)(JValue)null);
+      Assert.AreEqual(null, (int?)new JValue((int?)null));
+      Assert.AreEqual(null, (int?)(JValue)null);
+      Assert.AreEqual(null, (DateTime?)new JValue((DateTime?)null));
+      Assert.AreEqual(null, (DateTime?)(JValue)null);
+      Assert.AreEqual(null, (short?)new JValue((short?)null));
+      Assert.AreEqual(null, (short?)(JValue)null);
+      Assert.AreEqual(null, (float?)new JValue((float?)null));
+      Assert.AreEqual(null, (float?)(JValue)null);
+      Assert.AreEqual(null, (double?)new JValue((double?)null));
+      Assert.AreEqual(null, (double?)(JValue)null);
+      Assert.AreEqual(null, (decimal?)new JValue((decimal?)null));
+      Assert.AreEqual(null, (decimal?)(JValue)null);
+      Assert.AreEqual(null, (uint?)new JValue((uint?)null));
+      Assert.AreEqual(null, (uint?)(JValue)null);
+      Assert.AreEqual(null, (sbyte?)new JValue((sbyte?)null));
+      Assert.AreEqual(null, (sbyte?)(JValue)null);
+      Assert.AreEqual(null, (ulong?)new JValue((ulong?)null));
+      Assert.AreEqual(null, (ulong?)(JValue)null);
+      Assert.AreEqual(null, (uint?)new JValue((uint?)null));
+      Assert.AreEqual(null, (uint?)(JValue)null);
+      Assert.AreEqual(11.1f, (float)new JValue(11.1));
+      Assert.AreEqual(float.MinValue, (float)new JValue(float.MinValue));
+      Assert.AreEqual(1.1, (double)new JValue(1.1));
+      Assert.AreEqual(uint.MaxValue, (uint)new JValue(uint.MaxValue));
+      Assert.AreEqual(ulong.MaxValue, (ulong)new JValue(ulong.MaxValue));
+      Assert.AreEqual(ulong.MaxValue, (ulong)new JProperty("Test", new JValue(ulong.MaxValue)));
+      Assert.AreEqual(null, (string)new JValue((string)null));
+      Assert.AreEqual(5m, (decimal)(new JValue(5L)));
+      Assert.AreEqual(5m, (decimal?)(new JValue(5L)));
+      Assert.AreEqual(5f, (float)(new JValue(5L)));
+      Assert.AreEqual(5f, (float)(new JValue(5m)));
+      Assert.AreEqual(5f, (float?)(new JValue(5m)));
+
+      byte[] data = new byte[0];
+      Assert.AreEqual(data, (byte[])(new JValue(data)));
+
+      Assert.AreEqual(5, (int)(new JValue(StringComparison.OrdinalIgnoreCase)));
+    }
+
+    [Test]
+    public void ImplicitCastingTo()
+    {
+      Assert.IsTrue(JToken.DeepEquals(new JValue(new DateTime(2000, 12, 20)), (JValue)new DateTime(2000, 12, 20)));
+#if !PocketPC && !NET20
+      Assert.IsTrue(JToken.DeepEquals(new JValue(new DateTimeOffset(2000, 12, 20, 23, 50, 10, TimeSpan.Zero)), (JValue)new DateTimeOffset(2000, 12, 20, 23, 50, 10, TimeSpan.Zero)));
+      Assert.IsTrue(JToken.DeepEquals(new JValue((DateTimeOffset?)null), (JValue)(DateTimeOffset?)null));
+#endif
+
+      Assert.IsTrue(JToken.DeepEquals(new JValue(true), (JValue)true));
+      Assert.IsTrue(JToken.DeepEquals(new JValue(true), (JValue)(bool?)true));
+      Assert.IsTrue(JToken.DeepEquals(new JValue((bool?)null), (JValue)(bool?)null));
+      Assert.IsTrue(JToken.DeepEquals(new JValue(10), (JValue)10));
+      Assert.IsTrue(JToken.DeepEquals(new JValue((long?)null), (JValue)(long?)null));
+      Assert.IsTrue(JToken.DeepEquals(new JValue((DateTime?)null), (JValue)(DateTime?)null));
+      Assert.IsTrue(JToken.DeepEquals(new JValue(long.MaxValue), (JValue)long.MaxValue));
+      Assert.IsTrue(JToken.DeepEquals(new JValue((int?)null), (JValue)(int?)null));
+      Assert.IsTrue(JToken.DeepEquals(new JValue((short?)null), (JValue)(short?)null));
+      Assert.IsTrue(JToken.DeepEquals(new JValue((double?)null), (JValue)(double?)null));
+      Assert.IsTrue(JToken.DeepEquals(new JValue((uint?)null), (JValue)(uint?)null));
+      Assert.IsTrue(JToken.DeepEquals(new JValue((decimal?)null), (JValue)(decimal?)null));
+      Assert.IsTrue(JToken.DeepEquals(new JValue((ulong?)null), (JValue)(ulong?)null));
+      Assert.IsTrue(JToken.DeepEquals(new JValue((sbyte?)null), (JValue)(sbyte?)null));
+      Assert.IsTrue(JToken.DeepEquals(new JValue((ushort?)null), (JValue)(ushort?)null));
+      Assert.IsTrue(JToken.DeepEquals(new JValue(ushort.MaxValue), (JValue)ushort.MaxValue));
+      Assert.IsTrue(JToken.DeepEquals(new JValue(11.1f), (JValue)11.1f));
+      Assert.IsTrue(JToken.DeepEquals(new JValue(float.MinValue), (JValue)float.MinValue));
+      Assert.IsTrue(JToken.DeepEquals(new JValue(double.MinValue), (JValue)double.MinValue));
+      Assert.IsTrue(JToken.DeepEquals(new JValue(uint.MaxValue), (JValue)uint.MaxValue));
+      Assert.IsTrue(JToken.DeepEquals(new JValue(ulong.MaxValue), (JValue)ulong.MaxValue));
+      Assert.IsTrue(JToken.DeepEquals(new JValue(ulong.MinValue), (JValue)ulong.MinValue));
+      Assert.IsTrue(JToken.DeepEquals(new JValue((string)null), (JValue)(string)null));
+      Assert.IsTrue(JToken.DeepEquals(new JValue((DateTime?)null), (JValue)(DateTime?)null));
+      Assert.IsTrue(JToken.DeepEquals(new JValue(decimal.MaxValue), (JValue)decimal.MaxValue));
+      Assert.IsTrue(JToken.DeepEquals(new JValue(decimal.MaxValue), (JValue)(decimal?)decimal.MaxValue));
+      Assert.IsTrue(JToken.DeepEquals(new JValue(decimal.MinValue), (JValue)decimal.MinValue));
+      Assert.IsTrue(JToken.DeepEquals(new JValue(float.MaxValue), (JValue)(float?)float.MaxValue));
+      Assert.IsTrue(JToken.DeepEquals(new JValue(double.MaxValue), (JValue)(double?)double.MaxValue));
+      Assert.IsTrue(JToken.DeepEquals(new JValue((object)null), (JValue)(double?)null));
+
+      Assert.IsFalse(JToken.DeepEquals(new JValue(true), (JValue)(bool?)null));
+      Assert.IsFalse(JToken.DeepEquals(new JValue((object)null), (JValue)(object)null));
+
+      byte[] emptyData = new byte[0];
+      Assert.IsTrue(JToken.DeepEquals(new JValue(emptyData), (JValue)emptyData));
+      Assert.IsFalse(JToken.DeepEquals(new JValue(emptyData), (JValue)new byte[1]));
+      Assert.IsTrue(JToken.DeepEquals(new JValue(Encoding.UTF8.GetBytes("Hi")), (JValue)Encoding.UTF8.GetBytes("Hi")));
+    }
+
+    [Test]
+    public void Root()
+    {
+      JArray a =
+        new JArray(
+          5,
+          6,
+          new JArray(7, 8),
+          new JArray(9, 10)
+        );
+
+      Assert.AreEqual(a, a.Root);
+      Assert.AreEqual(a, a[0].Root);
+      Assert.AreEqual(a, ((JArray)a[2])[0].Root);
+    }
+
+    [Test]
+    public void Remove()
+    {
+      JToken t;
+      JArray a =
+        new JArray(
+          5,
+          6,
+          new JArray(7, 8),
+          new JArray(9, 10)
+        );
+
+      a[0].Remove();
+
+      Assert.AreEqual(6, (int)a[0]);
+
+      a[1].Remove();
+
+      Assert.AreEqual(6, (int)a[0]);
+      Assert.IsTrue(JToken.DeepEquals(new JArray(9, 10), a[1]));
+      Assert.AreEqual(2, a.Count());
+
+      t = a[1];
+      t.Remove();
+      Assert.AreEqual(6, (int)a[0]);
+      Assert.IsNull(t.Next);
+      Assert.IsNull(t.Previous);
+      Assert.IsNull(t.Parent);
+
+      t = a[0];
+      t.Remove();
+      Assert.AreEqual(0, a.Count());
+
+      Assert.IsNull(t.Next);
+      Assert.IsNull(t.Previous);
+      Assert.IsNull(t.Parent);
+    }
+
+    [Test]
+    public void AfterSelf()
+    {
+      JArray a =
+        new JArray(
+          5,
+          new JArray(1),
+          new JArray(1, 2),
+          new JArray(1, 2, 3)
+        );
+
+      JToken t = a[1];
+      List<JToken> afterTokens = t.AfterSelf().ToList();
+
+      Assert.AreEqual(2, afterTokens.Count);
+      Assert.IsTrue(JToken.DeepEquals(new JArray(1, 2), afterTokens[0]));
+      Assert.IsTrue(JToken.DeepEquals(new JArray(1, 2, 3), afterTokens[1]));
+    }
+
+    [Test]
+    public void BeforeSelf()
+    {
+      JArray a =
+        new JArray(
+          5,
+          new JArray(1),
+          new JArray(1, 2),
+          new JArray(1, 2, 3)
+        );
+
+      JToken t = a[2];
+      List<JToken> beforeTokens = t.BeforeSelf().ToList();
+
+      Assert.AreEqual(2, beforeTokens.Count);
+      Assert.IsTrue(JToken.DeepEquals(new JValue(5), beforeTokens[0]));
+      Assert.IsTrue(JToken.DeepEquals(new JArray(1), beforeTokens[1]));
+    }
+
+    [Test]
+    public void HasValues()
+    {
+      JArray a =
+        new JArray(
+          5,
+          new JArray(1),
+          new JArray(1, 2),
+          new JArray(1, 2, 3)
+        );
+
+      Assert.IsTrue(a.HasValues);
+    }
+
+    [Test]
+    public void Ancestors()
+    {
+      JArray a =
+        new JArray(
+          5,
+          new JArray(1),
+          new JArray(1, 2),
+          new JArray(1, 2, 3)
+        );
+
+      JToken t = a[1][0];
+      List<JToken> ancestors = t.Ancestors().ToList();
+      Assert.AreEqual(2, ancestors.Count());
+      Assert.AreEqual(a[1], ancestors[0]);
+      Assert.AreEqual(a, ancestors[1]);
+    }
+
+    [Test]
+    public void Descendants()
+    {
+      JArray a =
+        new JArray(
+          5,
+          new JArray(1),
+          new JArray(1, 2),
+          new JArray(1, 2, 3)
+        );
+
+      List<JToken> descendants = a.Descendants().ToList();
+      Assert.AreEqual(10, descendants.Count());
+      Assert.AreEqual(5, (int)descendants[0]);
+      Assert.IsTrue(JToken.DeepEquals(new JArray(1, 2, 3), descendants[descendants.Count - 4]));
+      Assert.AreEqual(1, (int)descendants[descendants.Count - 3]);
+      Assert.AreEqual(2, (int)descendants[descendants.Count - 2]);
+      Assert.AreEqual(3, (int)descendants[descendants.Count - 1]);
+    }
+
+    [Test]
+    public void CreateWriter()
+    {
+      JArray a =
+        new JArray(
+          5,
+          new JArray(1),
+          new JArray(1, 2),
+          new JArray(1, 2, 3)
+        );
+
+      JsonWriter writer = a.CreateWriter();
+      Assert.IsNotNull(writer);
+      Assert.AreEqual(4, a.Count());
+
+      writer.WriteValue("String");
+      Assert.AreEqual(5, a.Count());
+      Assert.AreEqual("String", (string)a[4]);
+
+      writer.WriteStartObject();
+      writer.WritePropertyName("Property");
+      writer.WriteValue("PropertyValue");
+      writer.WriteEnd();
+
+      Assert.AreEqual(6, a.Count());
+      Assert.IsTrue(JToken.DeepEquals(new JObject(new JProperty("Property", "PropertyValue")), a[5]));
+    }
+
+    [Test]
+    public void AddFirst()
+    {
+      JArray a =
+        new JArray(
+          5,
+          new JArray(1),
+          new JArray(1, 2),
+          new JArray(1, 2, 3)
+        );
+
+      a.AddFirst("First");
+
+      Assert.AreEqual("First", (string)a[0]);
+      Assert.AreEqual(a, a[0].Parent);
+      Assert.AreEqual(a[1], a[0].Next);
+      Assert.AreEqual(5, a.Count());
+
+      a.AddFirst("NewFirst");
+      Assert.AreEqual("NewFirst", (string)a[0]);
+      Assert.AreEqual(a, a[0].Parent);
+      Assert.AreEqual(a[1], a[0].Next);
+      Assert.AreEqual(6, a.Count());
+
+      Assert.AreEqual(a[0], a[0].Next.Previous);
+    }
+
+    [Test]
+    public void RemoveAll()
+    {
+      JArray a =
+        new JArray(
+          5,
+          new JArray(1),
+          new JArray(1, 2),
+          new JArray(1, 2, 3)
+        );
+
+      JToken first = a.First;
+      Assert.AreEqual(5, (int)first);
+
+      a.RemoveAll();
+      Assert.AreEqual(0, a.Count());
+
+      Assert.IsNull(first.Parent);
+      Assert.IsNull(first.Next);
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Can not add Newtonsoft.Json.Linq.JProperty to Newtonsoft.Json.Linq.JArray.")]
+    public void AddPropertyToArray()
+    {
+      JArray a = new JArray();
+      a.Add(new JProperty("PropertyName"));
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject.")]
+    public void AddValueToObject()
+    {
+      JObject o = new JObject();
+      o.Add(5);
+    }
+
+    [Test]
+    public void Replace()
+    {
+      JArray a =
+        new JArray(
+          5,
+          new JArray(1),
+          new JArray(1, 2),
+          new JArray(1, 2, 3)
+        );
+
+      a[0].Replace(new JValue(int.MaxValue));
+      Assert.AreEqual(int.MaxValue, (int)a[0]);
+      Assert.AreEqual(4, a.Count());
+
+      a[1][0].Replace(new JValue("Test"));
+      Assert.AreEqual("Test", (string)a[1][0]);
+
+      a[2].Replace(new JValue(int.MaxValue));
+      Assert.AreEqual(int.MaxValue, (int)a[2]);
+      Assert.AreEqual(4, a.Count());
+
+      Assert.IsTrue(JToken.DeepEquals(new JArray(int.MaxValue, new JArray("Test"), int.MaxValue, new JArray(1, 2, 3)), a));
+    }
+
+    [Test]
+    public void ToStringWithConverters()
+    {
+      JArray a =
+        new JArray(
+          new JValue(new DateTime(2009, 2, 15, 0, 0, 0, DateTimeKind.Utc))
+        );
+
+      string json = a.ToString(Formatting.Indented, new IsoDateTimeConverter());
+
+      Assert.AreEqual(@"[
+  ""2009-02-15T00:00:00Z""
+]", json);
+
+      json = JsonConvert.SerializeObject(a, new IsoDateTimeConverter());
+
+      Assert.AreEqual(@"[""2009-02-15T00:00:00Z""]", json);
+    }
+
+    [Test]
+    public void ToStringWithNoIndenting()
+    {
+      JArray a =
+        new JArray(
+          new JValue(new DateTime(2009, 2, 15, 0, 0, 0, DateTimeKind.Utc))
+        );
+
+      string json = a.ToString(Formatting.None, new IsoDateTimeConverter());
+
+      Assert.AreEqual(@"[""2009-02-15T00:00:00Z""]", json);
+    }
+
+    [Test]
+    public void AddAfterSelf()
+    {
+      JArray a =
+        new JArray(
+          5,
+          new JArray(1),
+          new JArray(1, 2),
+          new JArray(1, 2, 3)
+        );
+
+      a[1].AddAfterSelf("pie");
+
+      Assert.AreEqual(5, (int)a[0]);
+      Assert.AreEqual(1, a[1].Count());
+      Assert.AreEqual("pie", (string)a[2]);
+      Assert.AreEqual(5, a.Count());
+
+      a[4].AddAfterSelf("lastpie");
+
+      Assert.AreEqual("lastpie", (string)a[5]);
+      Assert.AreEqual("lastpie", (string)a.Last);
+    }
+
+    [Test]
+    public void AddBeforeSelf()
+    {
+      JArray a =
+        new JArray(
+          5,
+          new JArray(1),
+          new JArray(1, 2),
+          new JArray(1, 2, 3)
+        );
+
+      a[1].AddBeforeSelf("pie");
+
+      Assert.AreEqual(5, (int)a[0]);
+      Assert.AreEqual("pie", (string)a[1]);
+      Assert.AreEqual(a, a[1].Parent);
+      Assert.AreEqual(a[2], a[1].Next);
+      Assert.AreEqual(5, a.Count());
+
+      a[0].AddBeforeSelf("firstpie");
+
+      Assert.AreEqual("firstpie", (string)a[0]);
+      Assert.AreEqual(5, (int)a[1]);
+      Assert.AreEqual("pie", (string)a[2]);
+      Assert.AreEqual(a, a[0].Parent);
+      Assert.AreEqual(a[1], a[0].Next);
+      Assert.AreEqual(6, a.Count());
+
+      a.Last.AddBeforeSelf("secondlastpie");
+
+      Assert.AreEqual("secondlastpie", (string)a[5]);
+      Assert.AreEqual(7, a.Count());
+    }
+
+    [Test]
+    public void DeepClone()
+    {
+      JArray a =
+        new JArray(
+          5,
+          new JArray(1),
+          new JArray(1, 2),
+          new JArray(1, 2, 3),
+          new JObject(
+            new JProperty("First", new JValue(Encoding.UTF8.GetBytes("Hi"))),
+            new JProperty("Second", 1),
+            new JProperty("Third", null),
+            new JProperty("Fourth", new JConstructor("Date", 12345)),
+            new JProperty("Fifth", double.PositiveInfinity),
+            new JProperty("Sixth", double.NaN)
+            )
+        );
+
+      JArray a2 = (JArray)a.DeepClone();
+
+      Console.WriteLine(a2.ToString(Formatting.Indented));
+
+      Assert.IsTrue(a.DeepEquals(a2));
+    }
+
+#if !SILVERLIGHT
+    [Test]
+    public void Clone()
+    {
+      JArray a =
+        new JArray(
+          5,
+          new JArray(1),
+          new JArray(1, 2),
+          new JArray(1, 2, 3),
+          new JObject(
+            new JProperty("First", new JValue(Encoding.UTF8.GetBytes("Hi"))),
+            new JProperty("Second", 1),
+            new JProperty("Third", null),
+            new JProperty("Fourth", new JConstructor("Date", 12345)),
+            new JProperty("Fifth", double.PositiveInfinity),
+            new JProperty("Sixth", double.NaN)
+            )
+        );
+
+      ICloneable c = a;
+
+      JArray a2 = (JArray) c.Clone();
+
+      Assert.IsTrue(a.DeepEquals(a2));
+    }
+#endif
+
+    [Test]
+    public void DoubleDeepEquals()
+    {
+      JArray a =
+        new JArray(
+          double.NaN,
+          double.PositiveInfinity,
+          double.NegativeInfinity
+        );
+
+      JArray a2 = (JArray)a.DeepClone();
+
+      Assert.IsTrue(a.DeepEquals(a2));
+
+      double d = 1 + 0.1 + 0.1 + 0.1;
+
+      JValue v1 = new JValue(d);
+      JValue v2 = new JValue(1.3);
+
+      Assert.IsTrue(v1.DeepEquals(v2));
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JTokenWriterTest.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JTokenWriterTest.cs
new file mode 100644 (file)
index 0000000..52c4e49
--- /dev/null
@@ -0,0 +1,167 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using NUnit.Framework;
+using Newtonsoft.Json;
+using System.IO;
+using Newtonsoft.Json.Linq;
+using System.Linq;
+
+namespace Newtonsoft.Json.Tests.Linq
+{
+  public class JTokenWriterTest : TestFixtureBase
+  {
+    [Test]
+    public void ValueFormatting()
+    {
+      byte[] data = Encoding.UTF8.GetBytes("Hello world.");
+
+      JToken root;
+      using (JTokenWriter jsonWriter = new JTokenWriter())
+      {
+        jsonWriter.WriteStartArray();
+        jsonWriter.WriteValue('@');
+        jsonWriter.WriteValue("\r\n\t\f\b?{\\r\\n\"\'");
+        jsonWriter.WriteValue(true);
+        jsonWriter.WriteValue(10);
+        jsonWriter.WriteValue(10.99);
+        jsonWriter.WriteValue(0.99);
+        jsonWriter.WriteValue(0.000000000000000001d);
+        jsonWriter.WriteValue(0.000000000000000001m);
+        jsonWriter.WriteValue((string)null);
+        jsonWriter.WriteValue("This is a string.");
+        jsonWriter.WriteNull();
+        jsonWriter.WriteUndefined();
+        jsonWriter.WriteValue(data);
+        jsonWriter.WriteEndArray();
+
+        root = jsonWriter.Token;
+      }
+
+      Assert.IsInstanceOfType(typeof(JArray), root);
+      Assert.AreEqual(13, root.Children().Count());
+      Assert.AreEqual("@", (string)root[0]);
+      Assert.AreEqual("\r\n\t\f\b?{\\r\\n\"\'", (string)root[1]);
+      Assert.AreEqual(true, (bool)root[2]);
+      Assert.AreEqual(10, (int)root[3]);
+      Assert.AreEqual(10.99, (double)root[4]);
+      Assert.AreEqual(0.99, (double)root[5]);
+      Assert.AreEqual(0.000000000000000001d, (double)root[6]);
+      Assert.AreEqual(0.000000000000000001m, (decimal)root[7]);
+      Assert.AreEqual(string.Empty, (string)root[8]);
+      Assert.AreEqual("This is a string.", (string)root[9]);
+      Assert.AreEqual(null, ((JValue)root[10]).Value);
+      Assert.AreEqual(null, ((JValue)root[11]).Value);
+      Assert.AreEqual(data, (byte[])root[12]);
+    }
+
+    [Test]
+    public void State()
+    {
+      using (JsonWriter jsonWriter = new JTokenWriter())
+      {
+        Assert.AreEqual(WriteState.Start, jsonWriter.WriteState);
+
+        jsonWriter.WriteStartObject();
+        Assert.AreEqual(WriteState.Object, jsonWriter.WriteState);
+
+        jsonWriter.WritePropertyName("CPU");
+        Assert.AreEqual(WriteState.Property, jsonWriter.WriteState);
+
+        jsonWriter.WriteValue("Intel");
+        Assert.AreEqual(WriteState.Object, jsonWriter.WriteState);
+
+        jsonWriter.WritePropertyName("Drives");
+        Assert.AreEqual(WriteState.Property, jsonWriter.WriteState);
+
+        jsonWriter.WriteStartArray();
+        Assert.AreEqual(WriteState.Array, jsonWriter.WriteState);
+
+        jsonWriter.WriteValue("DVD read/writer");
+        Assert.AreEqual(WriteState.Array, jsonWriter.WriteState);
+
+        jsonWriter.WriteValue(new byte[0]);
+        Assert.AreEqual(WriteState.Array, jsonWriter.WriteState);
+
+        jsonWriter.WriteEnd();
+        Assert.AreEqual(WriteState.Object, jsonWriter.WriteState);
+
+        jsonWriter.WriteEndObject();
+        Assert.AreEqual(WriteState.Start, jsonWriter.WriteState);
+      }
+    }
+
+    [Test]
+    public void WriteComment()
+    {
+      JTokenWriter writer = new JTokenWriter();
+
+      writer.WriteStartArray();
+      writer.WriteComment("fail");
+      writer.WriteEndArray();
+
+      Assert.AreEqual(@"[
+  /*fail*/]", writer.Token.ToString());
+    }
+
+    [Test]
+    public void WriteRaw()
+    {
+      JTokenWriter writer = new JTokenWriter();
+
+      writer.WriteStartArray();
+      writer.WriteRaw("fail");
+      writer.WriteRaw("fail");
+      writer.WriteEndArray();
+
+      // this is a bug. write raw shouldn't be autocompleting like this
+      // hard to fix without introducing Raw and RawValue token types
+      // meh
+      Assert.AreEqual(@"[
+  fail,
+  fail
+]", writer.Token.ToString());
+    }
+
+    [Test]
+    public void WriteRawValue()
+    {
+      JTokenWriter writer = new JTokenWriter();
+
+      writer.WriteStartArray();
+      writer.WriteRawValue("fail");
+      writer.WriteRawValue("fail");
+      writer.WriteEndArray();
+
+      Assert.AreEqual(@"[
+  fail,
+  fail
+]", writer.Token.ToString());
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs
new file mode 100644 (file)
index 0000000..74126d9
--- /dev/null
@@ -0,0 +1,242 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using Newtonsoft.Json.Linq;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Tests.Linq
+{
+  public class JValueTests : TestFixtureBase
+  {
+    [Test]
+    public void ChangeValue()
+    {
+      JValue v = new JValue(true);
+      Assert.AreEqual(true, v.Value);
+      Assert.AreEqual(JTokenType.Boolean, v.Type);
+
+      v.Value = "Pie";
+      Assert.AreEqual("Pie", v.Value);
+      Assert.AreEqual(JTokenType.String, v.Type);
+
+      v.Value = null;
+      Assert.AreEqual(null, v.Value);
+      Assert.AreEqual(JTokenType.Null, v.Type);
+
+      v.Value = (int?)null;
+      Assert.AreEqual(null, v.Value);
+      Assert.AreEqual(JTokenType.Null, v.Type);
+
+      v.Value = "Pie";
+      Assert.AreEqual("Pie", v.Value);
+      Assert.AreEqual(JTokenType.String, v.Type);
+
+      v.Value = DBNull.Value;
+      Assert.AreEqual(DBNull.Value, v.Value);
+      Assert.AreEqual(JTokenType.Null, v.Type);
+
+      byte[] data = new byte[0];
+      v.Value = data;
+
+      Assert.AreEqual(data, v.Value);
+      Assert.AreEqual(JTokenType.Bytes, v.Type);
+
+      v.Value = StringComparison.OrdinalIgnoreCase;
+      Assert.AreEqual(StringComparison.OrdinalIgnoreCase, v.Value);
+      Assert.AreEqual(JTokenType.Integer, v.Type);
+    }
+
+    [Test]
+    public void CreateComment()
+    {
+      JValue commentValue = JValue.CreateComment(null);
+      Assert.AreEqual(null, commentValue.Value);
+      Assert.AreEqual(JTokenType.Comment, commentValue.Type);
+
+      commentValue.Value = "Comment";
+      Assert.AreEqual("Comment", commentValue.Value);
+      Assert.AreEqual(JTokenType.Comment, commentValue.Type);
+    }
+
+    [Test]
+    public void CreateString()
+    {
+      JValue stringValue = JValue.CreateString(null);
+      Assert.AreEqual(null, stringValue.Value);
+      Assert.AreEqual(JTokenType.String, stringValue.Type);
+    }
+
+    [Test]
+    public void ToString()
+    {
+      JValue v;
+
+      v = new JValue(true);
+      Assert.AreEqual("True", v.ToString());
+
+      v = new JValue(Encoding.UTF8.GetBytes("Blah"));
+      Assert.AreEqual("System.Byte[]", v.ToString(null, CultureInfo.InvariantCulture));
+
+      v = new JValue("I am a string!");
+      Assert.AreEqual("I am a string!", v.ToString());
+
+      v = new JValue(null, JTokenType.Null);
+      Assert.AreEqual("", v.ToString());
+
+      v = new JValue(null, JTokenType.Null);
+      Assert.AreEqual("", v.ToString(null, CultureInfo.InvariantCulture));
+
+      v = new JValue(new DateTime(2000, 12, 12, 20, 59, 59, DateTimeKind.Utc), JTokenType.Date);
+      Assert.AreEqual("12/12/2000 20:59:59", v.ToString(null, CultureInfo.InvariantCulture));
+    }
+
+    [Test]
+    [ExpectedException(typeof(InvalidOperationException), ExpectedMessage = "Cannot access child value on Newtonsoft.Json.Linq.JValue.")]
+    public void Last()
+    {
+      JValue v = new JValue(true);
+      JToken last = v.Last;
+    }
+
+    [Test]
+    [ExpectedException(typeof(InvalidOperationException), ExpectedMessage = "Cannot access child value on Newtonsoft.Json.Linq.JValue.")]
+    public void Children()
+    {
+      JValue v = new JValue(true);
+      var c = v.Children();
+    }
+
+    [Test]
+    [ExpectedException(typeof(InvalidOperationException), ExpectedMessage = "Cannot access child value on Newtonsoft.Json.Linq.JValue.")]
+    public void First()
+    {
+      JValue v = new JValue(true);
+      JToken first = v.First;
+    }
+
+    [Test]
+    [ExpectedException(typeof(InvalidOperationException), ExpectedMessage = "Cannot access child value on Newtonsoft.Json.Linq.JValue.")]
+    public void Item()
+    {
+      JValue v = new JValue(true);
+      JToken first = v[0];
+    }
+
+    [Test]
+    [ExpectedException(typeof(InvalidOperationException), ExpectedMessage = "Cannot access child value on Newtonsoft.Json.Linq.JValue.")]
+    public void Values()
+    {
+      JValue v = new JValue(true);
+      v.Values<int>();
+    }
+
+    [Test]
+    [ExpectedException(typeof(InvalidOperationException), ExpectedMessage = "The parent is missing.")]
+    public void RemoveParentNull()
+    {
+      JValue v = new JValue(true);
+      v.Remove();
+    }
+
+    [Test]
+    public void Root()
+    {
+      JValue v = new JValue(true);
+      Assert.AreEqual(v, v.Root);
+    }
+
+    [Test]
+    public void Previous()
+    {
+      JValue v = new JValue(true);
+      Assert.IsNull(v.Previous);
+    }
+
+    [Test]
+    public void Next()
+    {
+      JValue v = new JValue(true);
+      Assert.IsNull(v.Next);
+    }
+
+    [Test]
+    public void DeepEquals()
+    {
+      Assert.IsTrue(JToken.DeepEquals(new JValue(5L), new JValue(5)));
+      Assert.IsFalse(JToken.DeepEquals(new JValue(5M), new JValue(5)));
+      Assert.IsTrue(JToken.DeepEquals(new JValue((ulong)long.MaxValue), new JValue(long.MaxValue)));
+    }
+
+    [Test]
+    public void HasValues()
+    {
+      Assert.IsFalse((new JValue(5L)).HasValues);
+    }
+
+    [Test]
+    [ExpectedException(typeof(InvalidOperationException), ExpectedMessage = "Cannot set child value on Newtonsoft.Json.Linq.JValue.")]
+    public void SetValue()
+    {
+      JToken t = new JValue(5L);
+      t[0] = new JValue(3);
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Can not convert Null to Int32.")]
+    public void CastNullValueToNonNullable()
+    {
+      JValue v = new JValue((object)null);
+      int i = (int) v;
+    }
+
+    [Test]
+    public void ConvertValueToCompatibleType()
+    {
+      IComparable c = (new JValue(1).Value<IComparable>());
+      Assert.AreEqual(1, c);
+    }
+
+    [Test]
+    public void Ordering()
+    {
+      JObject o = new JObject(
+        new JProperty("Integer", new JValue(1)),
+        new JProperty("Float", new JValue(1.2d)),
+        new JProperty("Decimal", new JValue(1.1m))
+        );
+
+      IList<object> orderedValues = o.Values().Cast<JValue>().OrderBy(v => v).Select(v => v.Value).ToList();
+
+      Assert.AreEqual(1, orderedValues[0]);
+      Assert.AreEqual(1.1, orderedValues[1]);
+      Assert.AreEqual(1.2, orderedValues[2]);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/LinqToJsonTest.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Linq/LinqToJsonTest.cs
new file mode 100644 (file)
index 0000000..ae47b57
--- /dev/null
@@ -0,0 +1,786 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using Newtonsoft.Json.Linq;
+using System.Xml;
+using System.IO;
+using Newtonsoft.Json.Converters;
+using Newtonsoft.Json.Tests.TestObjects;
+
+namespace Newtonsoft.Json.Tests.Linq
+{
+  public class LinqToJsonTest : TestFixtureBase
+  {
+    [Test]
+    public void DoubleValue()
+    {
+      JArray j = JArray.Parse("[-1E+4,100.0e-2]");
+
+      double value = (double)j[0];
+      Assert.AreEqual(-10000d, value);
+
+      value = (double)j[1];
+      Assert.AreEqual(1d, value);
+    }
+
+    [Test]
+    public void Manual()
+    {
+      JArray array = new JArray();
+      JValue text = new JValue("Manual text");
+      JValue date = new JValue(new DateTime(2000, 5, 23));
+
+      array.Add(text);
+      array.Add(date);
+
+      string json = array.ToString();
+      // [
+      //   "Manual text",
+      //   "\/Date(958996800000+1200)\/"
+      // ]
+    }
+
+    [Test]
+    public void LinqToJsonDeserialize()
+    {
+      JObject o = new JObject(
+        new JProperty("Name", "John Smith"),
+        new JProperty("BirthDate", new DateTime(1983, 3, 20))
+        );
+
+      JsonSerializer serializer = new JsonSerializer();
+      Person p = (Person)serializer.Deserialize(new JTokenReader(o), typeof(Person));
+
+      // John Smith
+      Console.WriteLine(p.Name);
+    }
+
+    [Test]
+    public void ObjectParse()
+    {
+      string json = @"{
+        CPU: 'Intel',
+        Drives: [
+          'DVD read/writer',
+          ""500 gigabyte hard drive""
+        ]
+      }";
+
+      JObject o = JObject.Parse(json);
+      IList<JProperty> properties = o.Properties().ToList();
+
+      Assert.AreEqual("CPU", properties[0].Name);
+      Assert.AreEqual("Intel", (string)properties[0].Value);
+      Assert.AreEqual("Drives", properties[1].Name);
+
+      JArray list = (JArray)properties[1].Value;
+      Assert.AreEqual(2, list.Children().Count());
+      Assert.AreEqual("DVD read/writer", (string)list.Children().ElementAt(0));
+      Assert.AreEqual("500 gigabyte hard drive", (string)list.Children().ElementAt(1));
+
+      List<object> parameterValues =
+        (from p in o.Properties()
+         where p.Value is JValue
+         select ((JValue)p.Value).Value).ToList();
+
+      Assert.AreEqual(1, parameterValues.Count);
+      Assert.AreEqual("Intel", parameterValues[0]);
+    }
+
+    [Test]
+    public void CreateLongArray()
+    {
+      string json = @"[0,1,2,3,4,5,6,7,8,9]";
+
+      JArray a = JArray.Parse(json);
+      List<int> list = a.Values<int>().ToList();
+
+      List<int> expected = new List<int>() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+
+      CollectionAssert.AreEqual(expected, list);
+    }
+
+    [Test]
+    public void GoogleSearchAPI()
+    {
+      #region GoogleJson
+      string json = @"{
+    results:
+        [
+            {
+                GsearchResultClass:""GwebSearch"",
+                unescapedUrl : ""http://www.google.com/"",
+                url : ""http://www.google.com/"",
+                visibleUrl : ""www.google.com"",
+                cacheUrl : 
+""http://www.google.com/search?q=cache:zhool8dxBV4J:www.google.com"",
+                title : ""Google"",
+                titleNoFormatting : ""Google"",
+                content : ""Enables users to search the Web, Usenet, and 
+images. Features include PageRank,   caching and translation of 
+results, and an option to find similar pages.""
+            },
+            {
+                GsearchResultClass:""GwebSearch"",
+                unescapedUrl : ""http://news.google.com/"",
+                url : ""http://news.google.com/"",
+                visibleUrl : ""news.google.com"",
+                cacheUrl : 
+""http://www.google.com/search?q=cache:Va_XShOz_twJ:news.google.com"",
+                title : ""Google News"",
+                titleNoFormatting : ""Google News"",
+                content : ""Aggregated headlines and a search engine of many of the world's news sources.""
+            },
+            
+            {
+                GsearchResultClass:""GwebSearch"",
+                unescapedUrl : ""http://groups.google.com/"",
+                url : ""http://groups.google.com/"",
+                visibleUrl : ""groups.google.com"",
+                cacheUrl : 
+""http://www.google.com/search?q=cache:x2uPD3hfkn0J:groups.google.com"",
+                title : ""Google Groups"",
+                titleNoFormatting : ""Google Groups"",
+                content : ""Enables users to search and browse the Usenet 
+archives which consist of over 700   million messages, and post new 
+comments.""
+            },
+            
+            {
+                GsearchResultClass:""GwebSearch"",
+                unescapedUrl : ""http://maps.google.com/"",
+                url : ""http://maps.google.com/"",
+                visibleUrl : ""maps.google.com"",
+                cacheUrl : 
+""http://www.google.com/search?q=cache:dkf5u2twBXIJ:maps.google.com"",
+                title : ""Google Maps"",
+                titleNoFormatting : ""Google Maps"",
+                content : ""Provides directions, interactive maps, and 
+satellite/aerial imagery of the United   States. Can also search by 
+keyword such as type of business.""
+            }
+        ],
+        
+    adResults:
+        [
+            {
+                GsearchResultClass:""GwebSearch.ad"",
+                title : ""Gartner Symposium/ITxpo"",
+                content1 : ""Meet brilliant Gartner IT analysts"",
+                content2 : ""20-23 May 2007- Barcelona, Spain"",
+                url : 
+""http://www.google.com/url?sa=L&ai=BVualExYGRo3hD5ianAPJvejjD8-s6ye7kdTwArbI4gTAlrECEAEYASDXtMMFOAFQubWAjvr_____AWDXw_4EiAEBmAEAyAEBgAIB&num=1&q=http://www.gartner.com/it/sym/2007/spr8/spr8.jsp%3Fsrc%3D_spain_07_%26WT.srch%3D1&usg=__CxRH06E4Xvm9Muq13S4MgMtnziY="", 
+
+                impressionUrl : 
+""http://www.google.com/uds/css/ad-indicator-on.gif?ai=BVualExYGRo3hD5ianAPJvejjD8-s6ye7kdTwArbI4gTAlrECEAEYASDXtMMFOAFQubWAjvr_____AWDXw_4EiAEBmAEAyAEBgAIB"", 
+
+                unescapedUrl : 
+""http://www.google.com/url?sa=L&ai=BVualExYGRo3hD5ianAPJvejjD8-s6ye7kdTwArbI4gTAlrECEAEYASDXtMMFOAFQubWAjvr_____AWDXw_4EiAEBmAEAyAEBgAIB&num=1&q=http://www.gartner.com/it/sym/2007/spr8/spr8.jsp%3Fsrc%3D_spain_07_%26WT.srch%3D1&usg=__CxRH06E4Xvm9Muq13S4MgMtnziY="", 
+
+                visibleUrl : ""www.gartner.com""
+            }
+        ]
+}
+";
+      #endregion
+
+      JObject o = JObject.Parse(json);
+
+      List<JObject> resultObjects = o["results"].Children<JObject>().ToList();
+
+      Assert.AreEqual(32, resultObjects.Properties().Count());
+
+      Assert.AreEqual(32, resultObjects.Cast<JToken>().Values().Count());
+
+      Assert.AreEqual(4, resultObjects.Cast<JToken>().Values("GsearchResultClass").Count());
+
+      Assert.AreEqual(5, o.PropertyValues().Cast<JArray>().Children().Count());
+
+      List<string> resultUrls = o["results"].Children().Values<string>("url").ToList();
+
+      List<string> expectedUrls = new List<string>() { "http://www.google.com/", "http://news.google.com/", "http://groups.google.com/", "http://maps.google.com/" };
+
+      CollectionAssert.AreEqual(expectedUrls, resultUrls);
+
+      List<JToken> descendants = o.Descendants().ToList();
+      Assert.AreEqual(89, descendants.Count);
+    }
+
+    [Test]
+    public void JTokenToString()
+    {
+      string json = @"{
+  CPU: 'Intel',
+  Drives: [
+    'DVD read/writer',
+    ""500 gigabyte hard drive""
+  ]
+}";
+
+      JObject o = JObject.Parse(json);
+
+      Assert.AreEqual(@"{
+  ""CPU"": ""Intel"",
+  ""Drives"": [
+    ""DVD read/writer"",
+    ""500 gigabyte hard drive""
+  ]
+}", o.ToString());
+
+      JArray list = o.Value<JArray>("Drives");
+
+      Assert.AreEqual(@"[
+  ""DVD read/writer"",
+  ""500 gigabyte hard drive""
+]", list.ToString());
+
+      JProperty cpuProperty = o.Property("CPU");
+      Assert.AreEqual(@"""CPU"": ""Intel""", cpuProperty.ToString());
+
+      JProperty drivesProperty = o.Property("Drives");
+      Assert.AreEqual(@"""Drives"": [
+  ""DVD read/writer"",
+  ""500 gigabyte hard drive""
+]", drivesProperty.ToString());
+    }
+
+    [Test]
+    public void JTokenToStringTypes()
+    {
+      string json = @"{""Color"":2,""Establised"":new Date(1264118400000),""Width"":1.1,""Employees"":999,""RoomsPerFloor"":[1,2,3,4,5,6,7,8,9],""Open"":false,""Symbol"":""@"",""Mottos"":[""Hello World"",""öäüÖÄÜ\\'{new Date(12345);}[222]_µ@²³~"",null,"" ""],""Cost"":100980.1,""Escape"":""\r\n\t\f\b?{\\r\\n\""'"",""product"":[{""Name"":""Rocket"",""ExpiryDate"":new Date(949532490000),""Price"":0},{""Name"":""Alien"",""ExpiryDate"":new Date(-62135596800000),""Price"":0}]}";
+
+      JObject o = JObject.Parse(json);
+
+      Assert.AreEqual(@"""Establised"": new Date(
+  1264118400000
+)", o.Property("Establised").ToString());
+      Assert.AreEqual(@"new Date(
+  1264118400000
+)", o.Property("Establised").Value.ToString());
+      Assert.AreEqual(@"""Width"": 1.1", o.Property("Width").ToString());
+      Assert.AreEqual(@"1.1", ((JValue)o.Property("Width").Value).ToString(CultureInfo.InvariantCulture));
+      Assert.AreEqual(@"""Open"": false", o.Property("Open").ToString());
+      Assert.AreEqual(@"False", o.Property("Open").Value.ToString());
+
+      json = @"[null,undefined]";
+
+      JArray a = JArray.Parse(json);
+      Assert.AreEqual(@"[
+  null,
+  undefined
+]", a.ToString());
+      Assert.AreEqual(@"", a.Children().ElementAt(0).ToString());
+      Assert.AreEqual(@"", a.Children().ElementAt(1).ToString());
+    }
+
+    [Test]
+    public void CreateJTokenTree()
+    {
+      JObject o =
+        new JObject(
+          new JProperty("Test1", "Test1Value"),
+          new JProperty("Test2", "Test2Value"),
+          new JProperty("Test3", "Test3Value"),
+          new JProperty("Test4", null)
+        );
+
+      Assert.AreEqual(4, o.Properties().Count());
+
+      Assert.AreEqual(@"{
+  ""Test1"": ""Test1Value"",
+  ""Test2"": ""Test2Value"",
+  ""Test3"": ""Test3Value"",
+  ""Test4"": null
+}", o.ToString());
+
+      JArray a =
+        new JArray(
+          o,
+          new DateTime(2000, 10, 10, 0, 0, 0, DateTimeKind.Utc),
+          55,
+          new JArray(
+            "1",
+            2,
+            3.0,
+            new DateTime(4, 5, 6, 7, 8, 9, DateTimeKind.Utc)
+          ),
+          new JConstructor(
+            "ConstructorName",
+            "param1",
+            2,
+            3.0
+          )
+        );
+
+      Assert.AreEqual(5, a.Count());
+      Assert.AreEqual(@"[
+  {
+    ""Test1"": ""Test1Value"",
+    ""Test2"": ""Test2Value"",
+    ""Test3"": ""Test3Value"",
+    ""Test4"": null
+  },
+  ""\/Date(971136000000)\/"",
+  55,
+  [
+    ""1"",
+    2,
+    3.0,
+    ""\/Date(-62030076711000)\/""
+  ],
+  new ConstructorName(
+    ""param1"",
+    2,
+    3.0
+  )
+]", a.ToString());
+    }
+
+    private class Post
+    {
+      public string Title { get; set; }
+      public string Description { get; set; }
+      public string Link { get; set; }
+      public IList<string> Categories { get; set; }
+    }
+
+    private List<Post> GetPosts()
+    {
+      return new List<Post>()
+      {
+        new Post()
+        {
+          Title = "LINQ to JSON beta",
+          Description = "Annoucing LINQ to JSON",
+          Link = "http://james.newtonking.com/projects/json-net.aspx",
+          Categories = new List<string>() { "Json.NET", "LINQ" }
+        },
+        new Post()
+        {
+          Title = "Json.NET 1.3 + New license + Now on CodePlex",
+          Description = "Annoucing the release of Json.NET 1.3, the MIT license and the source being available on CodePlex",
+          Link = "http://james.newtonking.com/projects/json-net.aspx",
+          Categories = new List<string>() { "Json.NET", "CodePlex" }
+        }
+      };
+    }
+
+    [Test]
+    public void CreateJTokenTreeNested()
+    {
+      List<Post> posts = GetPosts();
+
+      JObject rss =
+        new JObject(
+          new JProperty("channel",
+            new JObject(
+              new JProperty("title", "James Newton-King"),
+              new JProperty("link", "http://james.newtonking.com"),
+              new JProperty("description", "James Newton-King's blog."),
+              new JProperty("item",
+                new JArray(
+                  from p in posts
+                  orderby p.Title
+                  select new JObject(
+                    new JProperty("title", p.Title),
+                    new JProperty("description", p.Description),
+                    new JProperty("link", p.Link),
+                    new JProperty("category",
+                      new JArray(
+                        from c in p.Categories
+                        select new JValue(c)))))))));
+
+      Console.WriteLine(rss.ToString());
+
+      //{
+      //  "channel": {
+      //    "title": "James Newton-King",
+      //    "link": "http://james.newtonking.com",
+      //    "description": "James Newton-King's blog.",
+      //    "item": [
+      //      {
+      //        "title": "Json.NET 1.3 + New license + Now on CodePlex",
+      //        "description": "Annoucing the release of Json.NET 1.3, the MIT license and the source being available on CodePlex",
+      //        "link": "http://james.newtonking.com/projects/json-net.aspx",
+      //        "category": [
+      //          "Json.NET",
+      //          "CodePlex"
+      //        ]
+      //      },
+      //      {
+      //        "title": "LINQ to JSON beta",
+      //        "description": "Annoucing LINQ to JSON",
+      //        "link": "http://james.newtonking.com/projects/json-net.aspx",
+      //        "category": [
+      //          "Json.NET",
+      //          "LINQ"
+      //        ]
+      //      }
+      //    ]
+      //  }
+      //}
+
+      var postTitles =
+        from p in rss["channel"]["item"]
+        select p.Value<string>("title");
+
+      foreach (var item in postTitles)
+      {
+        Console.WriteLine(item);
+      }
+
+      //LINQ to JSON beta
+      //Json.NET 1.3 + New license + Now on CodePlex
+
+      var categories =
+        from c in rss["channel"]["item"].Children()["category"].Values<string>()
+        group c by c into g
+        orderby g.Count() descending
+        select new { Category = g.Key, Count = g.Count() };
+
+      foreach (var c in categories)
+      {
+        Console.WriteLine(c.Category + " - Count: " + c.Count);
+      }
+
+      //Json.NET - Count: 2
+      //LINQ - Count: 1
+      //CodePlex - Count: 1
+    }
+
+    [Test]
+    public void BasicQuerying()
+    {
+      string json = @"{
+                        ""channel"": {
+                          ""title"": ""James Newton-King"",
+                          ""link"": ""http://james.newtonking.com"",
+                          ""description"": ""James Newton-King's blog."",
+                          ""item"": [
+                            {
+                              ""title"": ""Json.NET 1.3 + New license + Now on CodePlex"",
+                              ""description"": ""Annoucing the release of Json.NET 1.3, the MIT license and the source being available on CodePlex"",
+                              ""link"": ""http://james.newtonking.com/projects/json-net.aspx"",
+                              ""category"": [
+                                ""Json.NET"",
+                                ""CodePlex""
+                              ]
+                            },
+                            {
+                              ""title"": ""LINQ to JSON beta"",
+                              ""description"": ""Annoucing LINQ to JSON"",
+                              ""link"": ""http://james.newtonking.com/projects/json-net.aspx"",
+                              ""category"": [
+                                ""Json.NET"",
+                                ""LINQ""
+                              ]
+                            }
+                          ]
+                        }
+                      }";
+
+      JObject o = JObject.Parse(json);
+
+      Assert.AreEqual(null, o["purple"]);
+      Assert.AreEqual(null, o.Value<string>("purple"));
+
+      Assert.IsInstanceOfType(typeof(JArray), o["channel"]["item"]);
+
+      Assert.AreEqual(2, o["channel"]["item"].Children()["title"].Count());
+      Assert.AreEqual(0, o["channel"]["item"].Children()["monkey"].Count());
+
+      Assert.AreEqual("Json.NET 1.3 + New license + Now on CodePlex", (string)o["channel"]["item"][0]["title"]);
+
+      CollectionAssert.AreEqual(new string[] { "Json.NET 1.3 + New license + Now on CodePlex", "LINQ to JSON beta" }, o["channel"]["item"].Children().Values<string>("title").ToArray());
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Accessed JObject values with invalid key value: 0. Object property name expected.")]
+    public void JObjectIntIndex()
+    {
+      JObject o = new JObject();
+      Assert.AreEqual(null, o[0]);
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentException), ExpectedMessage = @"Accessed JArray values with invalid key value: ""purple"". Array position index expected.")]
+    public void JArrayStringIndex()
+    {
+      JArray a = new JArray();
+      Assert.AreEqual(null, a["purple"]);
+    }
+
+    [Test]
+    [ExpectedException(typeof(ArgumentException), ExpectedMessage = @"Accessed JConstructor values with invalid key value: ""purple"". Argument position index expected.")]
+    public void JConstructorStringIndex()
+    {
+      JConstructor c = new JConstructor("ConstructorValue");
+      Assert.AreEqual(null, c["purple"]);
+    }
+
+#if !PocketPC && !NET20
+    [Test]
+    public void ToStringJsonConverter()
+    {
+      JObject o =
+        new JObject(
+          new JProperty("Test1", new DateTime(2000, 10, 15, 5, 5, 5, DateTimeKind.Utc)),
+          new JProperty("Test2", new DateTimeOffset(2000, 10, 15, 5, 5, 5, new TimeSpan(11, 11, 0))),
+          new JProperty("Test3", "Test3Value"),
+          new JProperty("Test4", null)
+        );
+
+      JsonSerializer serializer = new JsonSerializer();
+      serializer.Converters.Add(new JavaScriptDateTimeConverter());
+      StringWriter sw = new StringWriter();
+      JsonWriter writer = new JsonTextWriter(sw);
+      writer.Formatting = Formatting.Indented;
+      serializer.Serialize(writer, o);
+
+      string json = sw.ToString();
+
+      Assert.AreEqual(@"{
+  ""Test1"": new Date(
+    971586305000
+  ),
+  ""Test2"": new Date(
+    971546045000
+  ),
+  ""Test3"": ""Test3Value"",
+  ""Test4"": null
+}", json);
+    }
+
+    [Test]
+    public void DateTimeOffset()
+    {
+      List<DateTimeOffset> testDates = new List<DateTimeOffset> {
+        new DateTimeOffset(new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Utc)),
+        new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero),
+        new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(13)),
+        new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(-3.5)),
+      };
+
+      JsonSerializer jsonSerializer = new JsonSerializer();
+
+      JTokenWriter jsonWriter;
+      using (jsonWriter = new JTokenWriter())
+      {
+        jsonSerializer.Serialize(jsonWriter, testDates);
+      }
+
+      Assert.AreEqual(4, jsonWriter.Token.Children().Count());
+    }
+#endif
+
+    [Test]
+    public void FromObject()
+    {
+      List<Post> posts = GetPosts();
+
+      JObject o = JObject.FromObject(new
+      {
+        channel = new
+        {
+          title = "James Newton-King",
+          link = "http://james.newtonking.com",
+          description = "James Newton-King's blog.",
+          item =
+              from p in posts
+              orderby p.Title
+              select new
+              {
+                title = p.Title,
+                description = p.Description,
+                link = p.Link,
+                category = p.Categories
+              }
+        }
+      });
+
+      Console.WriteLine(o.ToString());
+      Assert.IsInstanceOfType(typeof(JObject), o);
+      Assert.IsInstanceOfType(typeof(JObject), o["channel"]);
+      Assert.AreEqual("James Newton-King", (string)o["channel"]["title"]);
+      Assert.AreEqual(2, o["channel"]["item"].Children().Count());
+
+      JArray a = JArray.FromObject(new List<int>() { 0, 1, 2, 3, 4 });
+      Assert.IsInstanceOfType(typeof(JArray), a);
+      Assert.AreEqual(5, a.Count());
+    }
+
+    [Test]
+    public void FromAnonDictionary()
+    {
+      List<Post> posts = GetPosts();
+
+      JObject o = JObject.FromObject(new
+      {
+        channel = new Dictionary<string, object>
+        {
+          { "title", "James Newton-King" },
+          { "link", "http://james.newtonking.com" },
+          { "description", "James Newton-King's blog." },
+          { "item", 
+                  (from p in posts
+                  orderby p.Title
+                  select new
+                  {
+                    title = p.Title,
+                    description = p.Description,
+                    link = p.Link,
+                    category = p.Categories
+                  })
+          }
+        }
+      });
+
+      Console.WriteLine(o.ToString());
+      Assert.IsInstanceOfType(typeof(JObject), o);
+      Assert.IsInstanceOfType(typeof(JObject), o["channel"]);
+      Assert.AreEqual("James Newton-King", (string)o["channel"]["title"]);
+      Assert.AreEqual(2, o["channel"]["item"].Children().Count());
+
+      JArray a = JArray.FromObject(new List<int>() { 0, 1, 2, 3, 4 });
+      Assert.IsInstanceOfType(typeof(JArray), a);
+      Assert.AreEqual(5, a.Count());
+    }
+
+    [Test]
+    public void AsJEnumerable()
+    {
+      JObject o = null;
+      IJEnumerable<JToken> enumerable = null;
+
+      enumerable = o.AsJEnumerable();
+      Assert.IsNull(enumerable);
+    
+      o =
+        new JObject(
+          new JProperty("Test1", new DateTime(2000, 10, 15, 5, 5, 5, DateTimeKind.Utc)),
+          new JProperty("Test2", "Test2Value"),
+          new JProperty("Test3", null)
+        );
+
+      enumerable = o.AsJEnumerable();
+      Assert.IsNotNull(enumerable);
+      Assert.AreEqual(o, enumerable);
+
+      DateTime d = enumerable["Test1"].Value<DateTime>();
+
+      Assert.AreEqual(new DateTime(2000, 10, 15, 5, 5, 5, DateTimeKind.Utc), d);
+    }
+
+#if !(NET20 || NET35 || SILVERLIGHT)
+    [Test]
+    public void CovariantIJEnumerable()
+    {
+      IEnumerable<JObject> o = new[]
+        {
+          JObject.FromObject(new {First = 1, Second = 2}),
+          JObject.FromObject(new {First = 1, Second = 2})
+        };
+
+      IJEnumerable<JToken> values = o.Properties();
+      Assert.AreEqual(4, values.Count());
+    }
+#endif
+
+    [Test]
+    public void ChildrenExtension()
+    {
+      string json = @"[
+                        {
+                          ""title"": ""James Newton-King"",
+                          ""link"": ""http://james.newtonking.com"",
+                          ""description"": ""James Newton-King's blog."",
+                          ""item"": [
+                            {
+                              ""title"": ""Json.NET 1.3 + New license + Now on CodePlex"",
+                              ""description"": ""Annoucing the release of Json.NET 1.3, the MIT license and the source being available on CodePlex"",
+                              ""link"": ""http://james.newtonking.com/projects/json-net.aspx"",
+                              ""category"": [
+                                ""Json.NET"",
+                                ""CodePlex""
+                              ]
+                            },
+                            {
+                              ""title"": ""LINQ to JSON beta"",
+                              ""description"": ""Annoucing LINQ to JSON"",
+                              ""link"": ""http://james.newtonking.com/projects/json-net.aspx"",
+                              ""category"": [
+                                ""Json.NET"",
+                                ""LINQ""
+                              ]
+                            }
+                          ]
+                        },
+                        {
+                          ""title"": ""James Newton-King"",
+                          ""link"": ""http://james.newtonking.com"",
+                          ""description"": ""James Newton-King's blog."",
+                          ""item"": [
+                            {
+                              ""title"": ""Json.NET 1.3 + New license + Now on CodePlex"",
+                              ""description"": ""Annoucing the release of Json.NET 1.3, the MIT license and the source being available on CodePlex"",
+                              ""link"": ""http://james.newtonking.com/projects/json-net.aspx"",
+                              ""category"": [
+                                ""Json.NET"",
+                                ""CodePlex""
+                              ]
+                            },
+                            {
+                              ""title"": ""LINQ to JSON beta"",
+                              ""description"": ""Annoucing LINQ to JSON"",
+                              ""link"": ""http://james.newtonking.com/projects/json-net.aspx"",
+                              ""category"": [
+                                ""Json.NET"",
+                                ""LINQ""
+                              ]
+                            }
+                          ]
+                        }
+                      ]";
+
+      JArray o = JArray.Parse(json);
+
+      Assert.AreEqual(4, o.Children()["item"].Children()["title"].Count());
+      CollectionAssert.AreEqual(new string[]
+        {
+          "Json.NET 1.3 + New license + Now on CodePlex",
+          "LINQ to JSON beta",
+          "Json.NET 1.3 + New license + Now on CodePlex",
+          "LINQ to JSON beta"
+        },
+        o.Children()["item"].Children()["title"].Values<string>().ToArray());
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/LinqToSql/Department.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/LinqToSql/Department.cs
new file mode 100644 (file)
index 0000000..99b8f52
--- /dev/null
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Data.Linq;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Tests.LinqToSql
+{
+  [MetadataType(typeof(DepartmentMetadata))]
+  public partial class Department
+  {
+    [JsonConverter(typeof(DepartmentConverter))]
+    public class DepartmentMetadata
+    {
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/LinqToSql/DepartmentConverter.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/LinqToSql/DepartmentConverter.cs
new file mode 100644 (file)
index 0000000..3aee048
--- /dev/null
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Linq;
+
+namespace Newtonsoft.Json.Tests.LinqToSql
+{
+  public class DepartmentConverter : JsonConverter
+  {
+    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+    {
+      Department department = (Department)value;
+
+      JObject o = new JObject();
+      o["DepartmentId"] = new JValue(department.DepartmentId.ToString());
+      o["Name"] = new JValue(new string(department.Name.Reverse().ToArray()));
+
+      o.WriteTo(writer);
+    }
+
+    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+    {
+      JObject o = JObject.Load(reader);
+
+      Department department = new Department();
+      department.DepartmentId = new Guid((string)o["DepartmentId"]);
+      department.Name = new string(((string) o["Name"]).Reverse().ToArray());
+
+      return department;
+    }
+
+    public override bool CanConvert(Type objectType)
+    {
+      return (objectType == typeof (Department));
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/LinqToSql/GuidByteArrayConverter.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/LinqToSql/GuidByteArrayConverter.cs
new file mode 100644 (file)
index 0000000..a52c69f
--- /dev/null
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Tests.LinqToSql
+{
+  public class GuidByteArrayConverter : JsonConverter
+  {
+    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+    {
+      Guid guid = (Guid) value;
+      writer.WriteValue(Convert.ToBase64String(guid.ToByteArray()));
+    }
+
+    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+    {
+      string encodedData = (string) reader.Value;
+      byte[] data = Convert.FromBase64String(encodedData);
+      return new Guid(data);
+    }
+
+    public override bool CanConvert(Type objectType)
+    {
+      return (objectType == typeof (Guid));
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClasses.dbml b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClasses.dbml
new file mode 100644 (file)
index 0000000..4929619
--- /dev/null
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?><Database EntityNamespace="Newtonsoft.Json.Tests.LinqToSql" ContextNamespace="Newtonsoft.Json.Tests.LinqToSql" Class="LinqToSqlClassesDataContext" xmlns="http://schemas.microsoft.com/linqtosql/dbml/2007">
+  <Table Name="" Member="Persons">
+    <Type Name="Person">
+      <Column Name="FirstName" Type="System.String" CanBeNull="false" />
+      <Column Name="LastName" Type="System.String" CanBeNull="false" />
+      <Column Name="PersonId" Type="System.Guid" IsPrimaryKey="true" CanBeNull="false" />
+      <Column Name="DepartmentId" Type="System.Guid" CanBeNull="false" />
+      <Association Name="Person_PersonRole" Member="PersonRoles" ThisKey="PersonId" OtherKey="PersonId" Type="PersonRole" />
+      <Association Name="Department_Person" Member="Department" ThisKey="DepartmentId" OtherKey="DepartmentId" Type="Department" IsForeignKey="true" />
+    </Type>
+  </Table>
+  <Table Name="" Member="Roles">
+    <Type Name="Role">
+      <Column Name="Name" Type="System.String" CanBeNull="false" />
+      <Column Name="RoleId" Type="System.Guid" IsPrimaryKey="true" CanBeNull="false" />
+      <Association Name="Role_PersonRole" Member="PersonRoles" ThisKey="RoleId" OtherKey="RoleId" Type="PersonRole" />
+    </Type>
+  </Table>
+  <Table Name="" Member="PersonRoles">
+    <Type Name="PersonRole">
+      <Column Name="PersonId" Type="System.Guid" CanBeNull="false" />
+      <Column Name="RoleId" Type="System.Guid" CanBeNull="false" />
+      <Column Name="PersonRoleId" Type="System.Guid" IsPrimaryKey="true" CanBeNull="false" />
+      <Association Name="Person_PersonRole" Member="Person" ThisKey="PersonId" OtherKey="PersonId" Type="Person" IsForeignKey="true" />
+      <Association Name="Role_PersonRole" Member="Role" ThisKey="RoleId" OtherKey="RoleId" Type="Role" IsForeignKey="true" />
+    </Type>
+  </Table>
+  <Table Name="" Member="Departments">
+    <Type Name="Department">
+      <Column Name="DepartmentId" Type="System.Guid" IsPrimaryKey="true" CanBeNull="false" />
+      <Column Name="Name" Type="System.String" CanBeNull="false" />
+      <Association Name="Department_Person" Member="Persons" ThisKey="DepartmentId" OtherKey="DepartmentId" Type="Person" />
+    </Type>
+  </Table>
+</Database>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClasses.dbml.layout b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClasses.dbml.layout
new file mode 100644 (file)
index 0000000..36b0ff0
--- /dev/null
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ordesignerObjectsDiagram dslVersion="1.0.0.0" absoluteBounds="0, 0, 11, 8.5" name="LinqToSqlClasses">
+  <DataContextMoniker Name="/LinqToSqlClassesDataContext" />
+  <nestedChildShapes>
+    <classShape Id="be91ec15-4a64-4976-9358-2e01309ef584" absoluteBounds="0.875, 1.875, 2, 1.5785953776041666">
+      <DataClassMoniker Name="/LinqToSqlClassesDataContext/Person" />
+      <nestedChildShapes>
+        <elementListCompartment Id="e16e186c-b29e-45ca-a2ab-93cb3de05143" absoluteBounds="0.8899999999999999, 2.335, 1.9700000000000002, 1.0185953776041665" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="b1b861bb-382c-4c65-bdb1-7a3e2df873a2" absoluteBounds="3.625, 4.625, 2, 1.1939925130208333">
+      <DataClassMoniker Name="/LinqToSqlClassesDataContext/Role" />
+      <nestedChildShapes>
+        <elementListCompartment Id="11d870c0-0ec3-4fba-bb69-43a96fa05670" absoluteBounds="3.6399999999999997, 5.085, 1.9700000000000002, 0.63399251302083326" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="1eb138a4-9f12-4a20-b6b7-d1e23984b857" absoluteBounds="3.75, 2.25, 2, 1.3862939453125">
+      <DataClassMoniker Name="/LinqToSqlClassesDataContext/PersonRole" />
+      <nestedChildShapes>
+        <elementListCompartment Id="6865be45-c748-47ff-be37-534064fc2e80" absoluteBounds="3.7649999999999997, 2.71, 1.9700000000000002, 0.8262939453125" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <associationConnector edgePoints="[(2.875 : 2.85179768880208); (3.75 : 2.85179768880208)]" fixedFrom="NotFixed" fixedTo="NotFixed">
+      <AssociationMoniker Name="/LinqToSqlClassesDataContext/Person/Person_PersonRole" />
+      <nodes>
+        <classShapeMoniker Id="be91ec15-4a64-4976-9358-2e01309ef584" />
+        <classShapeMoniker Id="1eb138a4-9f12-4a20-b6b7-d1e23984b857" />
+      </nodes>
+    </associationConnector>
+    <associationConnector edgePoints="[(4.6875 : 4.625); (4.6875 : 3.6362939453125)]" fixedFrom="NotFixed" fixedTo="NotFixed">
+      <AssociationMoniker Name="/LinqToSqlClassesDataContext/Role/Role_PersonRole" />
+      <nodes>
+        <classShapeMoniker Id="b1b861bb-382c-4c65-bdb1-7a3e2df873a2" />
+        <classShapeMoniker Id="1eb138a4-9f12-4a20-b6b7-d1e23984b857" />
+      </nodes>
+    </associationConnector>
+    <classShape Id="b96fa86b-7f23-489f-8eb2-44ca2af1551b" absoluteBounds="0.875, 4.5, 2, 1.1939925130208327">
+      <DataClassMoniker Name="/LinqToSqlClassesDataContext/Department" />
+      <nestedChildShapes>
+        <elementListCompartment Id="46cdd558-04c5-4c77-82ce-fe92cda427fe" absoluteBounds="0.89, 4.96, 1.9700000000000002, 0.63399251302083326" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <associationConnector edgePoints="[(1.875 : 4.5); (1.875 : 3.45359537760417)]" fixedFrom="NotFixed" fixedTo="NotFixed">
+      <AssociationMoniker Name="/LinqToSqlClassesDataContext/Department/Department_Person" />
+      <nodes>
+        <classShapeMoniker Id="b96fa86b-7f23-489f-8eb2-44ca2af1551b" />
+        <classShapeMoniker Id="be91ec15-4a64-4976-9358-2e01309ef584" />
+      </nodes>
+    </associationConnector>
+  </nestedChildShapes>
+</ordesignerObjectsDiagram>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClasses.designer.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClasses.designer.cs
new file mode 100644 (file)
index 0000000..7ffc689
--- /dev/null
@@ -0,0 +1,726 @@
+#pragma warning disable 1591
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.1
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Newtonsoft.Json.Tests.LinqToSql
+{
+       using System.Data.Linq;
+       using System.Data.Linq.Mapping;
+       using System.Data;
+       using System.Collections.Generic;
+       using System.Reflection;
+       using System.Linq;
+       using System.Linq.Expressions;
+       using System.ComponentModel;
+       using System;
+       
+       
+       public partial class LinqToSqlClassesDataContext : System.Data.Linq.DataContext
+       {
+               
+               private static System.Data.Linq.Mapping.MappingSource mappingSource = new AttributeMappingSource();
+               
+    #region Extensibility Method Definitions
+    partial void OnCreated();
+    partial void InsertPerson(Person instance);
+    partial void UpdatePerson(Person instance);
+    partial void DeletePerson(Person instance);
+    partial void InsertRole(Role instance);
+    partial void UpdateRole(Role instance);
+    partial void DeleteRole(Role instance);
+    partial void InsertPersonRole(PersonRole instance);
+    partial void UpdatePersonRole(PersonRole instance);
+    partial void DeletePersonRole(PersonRole instance);
+    partial void InsertDepartment(Department instance);
+    partial void UpdateDepartment(Department instance);
+    partial void DeleteDepartment(Department instance);
+    #endregion
+               
+               public LinqToSqlClassesDataContext(string connection) : 
+                               base(connection, mappingSource)
+               {
+                       OnCreated();
+               }
+               
+               public LinqToSqlClassesDataContext(System.Data.IDbConnection connection) : 
+                               base(connection, mappingSource)
+               {
+                       OnCreated();
+               }
+               
+               public LinqToSqlClassesDataContext(string connection, System.Data.Linq.Mapping.MappingSource mappingSource) : 
+                               base(connection, mappingSource)
+               {
+                       OnCreated();
+               }
+               
+               public LinqToSqlClassesDataContext(System.Data.IDbConnection connection, System.Data.Linq.Mapping.MappingSource mappingSource) : 
+                               base(connection, mappingSource)
+               {
+                       OnCreated();
+               }
+               
+               public System.Data.Linq.Table<Person> Persons
+               {
+                       get
+                       {
+                               return this.GetTable<Person>();
+                       }
+               }
+               
+               public System.Data.Linq.Table<Role> Roles
+               {
+                       get
+                       {
+                               return this.GetTable<Role>();
+                       }
+               }
+               
+               public System.Data.Linq.Table<PersonRole> PersonRoles
+               {
+                       get
+                       {
+                               return this.GetTable<PersonRole>();
+                       }
+               }
+               
+               public System.Data.Linq.Table<Department> Departments
+               {
+                       get
+                       {
+                               return this.GetTable<Department>();
+                       }
+               }
+       }
+       
+       [global::System.Data.Linq.Mapping.TableAttribute(Name="")]
+       public partial class Person : INotifyPropertyChanging, INotifyPropertyChanged
+       {
+               
+               private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+               
+               private string _FirstName;
+               
+               private string _LastName;
+               
+               private System.Guid _PersonId;
+               
+               private System.Guid _DepartmentId;
+               
+               private EntitySet<PersonRole> _PersonRoles;
+               
+               private EntityRef<Department> _Department;
+               
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnFirstNameChanging(string value);
+    partial void OnFirstNameChanged();
+    partial void OnLastNameChanging(string value);
+    partial void OnLastNameChanged();
+    partial void OnPersonIdChanging(System.Guid value);
+    partial void OnPersonIdChanged();
+    partial void OnDepartmentIdChanging(System.Guid value);
+    partial void OnDepartmentIdChanged();
+    #endregion
+               
+               public Person()
+               {
+                       this._PersonRoles = new EntitySet<PersonRole>(new Action<PersonRole>(this.attach_PersonRoles), new Action<PersonRole>(this.detach_PersonRoles));
+                       this._Department = default(EntityRef<Department>);
+                       OnCreated();
+               }
+               
+               [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_FirstName", CanBeNull=false)]
+               public string FirstName
+               {
+                       get
+                       {
+                               return this._FirstName;
+                       }
+                       set
+                       {
+                               if ((this._FirstName != value))
+                               {
+                                       this.OnFirstNameChanging(value);
+                                       this.SendPropertyChanging();
+                                       this._FirstName = value;
+                                       this.SendPropertyChanged("FirstName");
+                                       this.OnFirstNameChanged();
+                               }
+                       }
+               }
+               
+               [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_LastName", CanBeNull=false)]
+               public string LastName
+               {
+                       get
+                       {
+                               return this._LastName;
+                       }
+                       set
+                       {
+                               if ((this._LastName != value))
+                               {
+                                       this.OnLastNameChanging(value);
+                                       this.SendPropertyChanging();
+                                       this._LastName = value;
+                                       this.SendPropertyChanged("LastName");
+                                       this.OnLastNameChanged();
+                               }
+                       }
+               }
+               
+               [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_PersonId", IsPrimaryKey=true)]
+               public System.Guid PersonId
+               {
+                       get
+                       {
+                               return this._PersonId;
+                       }
+                       set
+                       {
+                               if ((this._PersonId != value))
+                               {
+                                       this.OnPersonIdChanging(value);
+                                       this.SendPropertyChanging();
+                                       this._PersonId = value;
+                                       this.SendPropertyChanged("PersonId");
+                                       this.OnPersonIdChanged();
+                               }
+                       }
+               }
+               
+               [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_DepartmentId")]
+               public System.Guid DepartmentId
+               {
+                       get
+                       {
+                               return this._DepartmentId;
+                       }
+                       set
+                       {
+                               if ((this._DepartmentId != value))
+                               {
+                                       if (this._Department.HasLoadedOrAssignedValue)
+                                       {
+                                               throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+                                       }
+                                       this.OnDepartmentIdChanging(value);
+                                       this.SendPropertyChanging();
+                                       this._DepartmentId = value;
+                                       this.SendPropertyChanged("DepartmentId");
+                                       this.OnDepartmentIdChanged();
+                               }
+                       }
+               }
+               
+               [global::System.Data.Linq.Mapping.AssociationAttribute(Name="Person_PersonRole", Storage="_PersonRoles", ThisKey="PersonId", OtherKey="PersonId")]
+               public EntitySet<PersonRole> PersonRoles
+               {
+                       get
+                       {
+                               return this._PersonRoles;
+                       }
+                       set
+                       {
+                               this._PersonRoles.Assign(value);
+                       }
+               }
+               
+               [global::System.Data.Linq.Mapping.AssociationAttribute(Name="Department_Person", Storage="_Department", ThisKey="DepartmentId", OtherKey="DepartmentId", IsForeignKey=true)]
+               public Department Department
+               {
+                       get
+                       {
+                               return this._Department.Entity;
+                       }
+                       set
+                       {
+                               Department previousValue = this._Department.Entity;
+                               if (((previousValue != value) 
+                                                       || (this._Department.HasLoadedOrAssignedValue == false)))
+                               {
+                                       this.SendPropertyChanging();
+                                       if ((previousValue != null))
+                                       {
+                                               this._Department.Entity = null;
+                                               previousValue.Persons.Remove(this);
+                                       }
+                                       this._Department.Entity = value;
+                                       if ((value != null))
+                                       {
+                                               value.Persons.Add(this);
+                                               this._DepartmentId = value.DepartmentId;
+                                       }
+                                       else
+                                       {
+                                               this._DepartmentId = default(System.Guid);
+                                       }
+                                       this.SendPropertyChanged("Department");
+                               }
+                       }
+               }
+               
+               public event PropertyChangingEventHandler PropertyChanging;
+               
+               public event PropertyChangedEventHandler PropertyChanged;
+               
+               protected virtual void SendPropertyChanging()
+               {
+                       if ((this.PropertyChanging != null))
+                       {
+                               this.PropertyChanging(this, emptyChangingEventArgs);
+                       }
+               }
+               
+               protected virtual void SendPropertyChanged(String propertyName)
+               {
+                       if ((this.PropertyChanged != null))
+                       {
+                               this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+                       }
+               }
+               
+               private void attach_PersonRoles(PersonRole entity)
+               {
+                       this.SendPropertyChanging();
+                       entity.Person = this;
+               }
+               
+               private void detach_PersonRoles(PersonRole entity)
+               {
+                       this.SendPropertyChanging();
+                       entity.Person = null;
+               }
+       }
+       
+       [global::System.Data.Linq.Mapping.TableAttribute(Name="")]
+       public partial class Role : INotifyPropertyChanging, INotifyPropertyChanged
+       {
+               
+               private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+               
+               private string _Name;
+               
+               private System.Guid _RoleId;
+               
+               private EntitySet<PersonRole> _PersonRoles;
+               
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnNameChanging(string value);
+    partial void OnNameChanged();
+    partial void OnRoleIdChanging(System.Guid value);
+    partial void OnRoleIdChanged();
+    #endregion
+               
+               public Role()
+               {
+                       this._PersonRoles = new EntitySet<PersonRole>(new Action<PersonRole>(this.attach_PersonRoles), new Action<PersonRole>(this.detach_PersonRoles));
+                       OnCreated();
+               }
+               
+               [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Name", CanBeNull=false)]
+               public string Name
+               {
+                       get
+                       {
+                               return this._Name;
+                       }
+                       set
+                       {
+                               if ((this._Name != value))
+                               {
+                                       this.OnNameChanging(value);
+                                       this.SendPropertyChanging();
+                                       this._Name = value;
+                                       this.SendPropertyChanged("Name");
+                                       this.OnNameChanged();
+                               }
+                       }
+               }
+               
+               [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_RoleId", IsPrimaryKey=true)]
+               public System.Guid RoleId
+               {
+                       get
+                       {
+                               return this._RoleId;
+                       }
+                       set
+                       {
+                               if ((this._RoleId != value))
+                               {
+                                       this.OnRoleIdChanging(value);
+                                       this.SendPropertyChanging();
+                                       this._RoleId = value;
+                                       this.SendPropertyChanged("RoleId");
+                                       this.OnRoleIdChanged();
+                               }
+                       }
+               }
+               
+               [global::System.Data.Linq.Mapping.AssociationAttribute(Name="Role_PersonRole", Storage="_PersonRoles", ThisKey="RoleId", OtherKey="RoleId")]
+               public EntitySet<PersonRole> PersonRoles
+               {
+                       get
+                       {
+                               return this._PersonRoles;
+                       }
+                       set
+                       {
+                               this._PersonRoles.Assign(value);
+                       }
+               }
+               
+               public event PropertyChangingEventHandler PropertyChanging;
+               
+               public event PropertyChangedEventHandler PropertyChanged;
+               
+               protected virtual void SendPropertyChanging()
+               {
+                       if ((this.PropertyChanging != null))
+                       {
+                               this.PropertyChanging(this, emptyChangingEventArgs);
+                       }
+               }
+               
+               protected virtual void SendPropertyChanged(String propertyName)
+               {
+                       if ((this.PropertyChanged != null))
+                       {
+                               this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+                       }
+               }
+               
+               private void attach_PersonRoles(PersonRole entity)
+               {
+                       this.SendPropertyChanging();
+                       entity.Role = this;
+               }
+               
+               private void detach_PersonRoles(PersonRole entity)
+               {
+                       this.SendPropertyChanging();
+                       entity.Role = null;
+               }
+       }
+       
+       [global::System.Data.Linq.Mapping.TableAttribute(Name="")]
+       public partial class PersonRole : INotifyPropertyChanging, INotifyPropertyChanged
+       {
+               
+               private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+               
+               private System.Guid _PersonId;
+               
+               private System.Guid _RoleId;
+               
+               private System.Guid _PersonRoleId;
+               
+               private EntityRef<Person> _Person;
+               
+               private EntityRef<Role> _Role;
+               
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnPersonIdChanging(System.Guid value);
+    partial void OnPersonIdChanged();
+    partial void OnRoleIdChanging(System.Guid value);
+    partial void OnRoleIdChanged();
+    partial void OnPersonRoleIdChanging(System.Guid value);
+    partial void OnPersonRoleIdChanged();
+    #endregion
+               
+               public PersonRole()
+               {
+                       this._Person = default(EntityRef<Person>);
+                       this._Role = default(EntityRef<Role>);
+                       OnCreated();
+               }
+               
+               [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_PersonId")]
+               public System.Guid PersonId
+               {
+                       get
+                       {
+                               return this._PersonId;
+                       }
+                       set
+                       {
+                               if ((this._PersonId != value))
+                               {
+                                       if (this._Person.HasLoadedOrAssignedValue)
+                                       {
+                                               throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+                                       }
+                                       this.OnPersonIdChanging(value);
+                                       this.SendPropertyChanging();
+                                       this._PersonId = value;
+                                       this.SendPropertyChanged("PersonId");
+                                       this.OnPersonIdChanged();
+                               }
+                       }
+               }
+               
+               [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_RoleId")]
+               public System.Guid RoleId
+               {
+                       get
+                       {
+                               return this._RoleId;
+                       }
+                       set
+                       {
+                               if ((this._RoleId != value))
+                               {
+                                       if (this._Role.HasLoadedOrAssignedValue)
+                                       {
+                                               throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+                                       }
+                                       this.OnRoleIdChanging(value);
+                                       this.SendPropertyChanging();
+                                       this._RoleId = value;
+                                       this.SendPropertyChanged("RoleId");
+                                       this.OnRoleIdChanged();
+                               }
+                       }
+               }
+               
+               [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_PersonRoleId", IsPrimaryKey=true)]
+               public System.Guid PersonRoleId
+               {
+                       get
+                       {
+                               return this._PersonRoleId;
+                       }
+                       set
+                       {
+                               if ((this._PersonRoleId != value))
+                               {
+                                       this.OnPersonRoleIdChanging(value);
+                                       this.SendPropertyChanging();
+                                       this._PersonRoleId = value;
+                                       this.SendPropertyChanged("PersonRoleId");
+                                       this.OnPersonRoleIdChanged();
+                               }
+                       }
+               }
+               
+               [global::System.Data.Linq.Mapping.AssociationAttribute(Name="Person_PersonRole", Storage="_Person", ThisKey="PersonId", OtherKey="PersonId", IsForeignKey=true)]
+               public Person Person
+               {
+                       get
+                       {
+                               return this._Person.Entity;
+                       }
+                       set
+                       {
+                               Person previousValue = this._Person.Entity;
+                               if (((previousValue != value) 
+                                                       || (this._Person.HasLoadedOrAssignedValue == false)))
+                               {
+                                       this.SendPropertyChanging();
+                                       if ((previousValue != null))
+                                       {
+                                               this._Person.Entity = null;
+                                               previousValue.PersonRoles.Remove(this);
+                                       }
+                                       this._Person.Entity = value;
+                                       if ((value != null))
+                                       {
+                                               value.PersonRoles.Add(this);
+                                               this._PersonId = value.PersonId;
+                                       }
+                                       else
+                                       {
+                                               this._PersonId = default(System.Guid);
+                                       }
+                                       this.SendPropertyChanged("Person");
+                               }
+                       }
+               }
+               
+               [global::System.Data.Linq.Mapping.AssociationAttribute(Name="Role_PersonRole", Storage="_Role", ThisKey="RoleId", OtherKey="RoleId", IsForeignKey=true)]
+               public Role Role
+               {
+                       get
+                       {
+                               return this._Role.Entity;
+                       }
+                       set
+                       {
+                               Role previousValue = this._Role.Entity;
+                               if (((previousValue != value) 
+                                                       || (this._Role.HasLoadedOrAssignedValue == false)))
+                               {
+                                       this.SendPropertyChanging();
+                                       if ((previousValue != null))
+                                       {
+                                               this._Role.Entity = null;
+                                               previousValue.PersonRoles.Remove(this);
+                                       }
+                                       this._Role.Entity = value;
+                                       if ((value != null))
+                                       {
+                                               value.PersonRoles.Add(this);
+                                               this._RoleId = value.RoleId;
+                                       }
+                                       else
+                                       {
+                                               this._RoleId = default(System.Guid);
+                                       }
+                                       this.SendPropertyChanged("Role");
+                               }
+                       }
+               }
+               
+               public event PropertyChangingEventHandler PropertyChanging;
+               
+               public event PropertyChangedEventHandler PropertyChanged;
+               
+               protected virtual void SendPropertyChanging()
+               {
+                       if ((this.PropertyChanging != null))
+                       {
+                               this.PropertyChanging(this, emptyChangingEventArgs);
+                       }
+               }
+               
+               protected virtual void SendPropertyChanged(String propertyName)
+               {
+                       if ((this.PropertyChanged != null))
+                       {
+                               this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+                       }
+               }
+       }
+       
+       [global::System.Data.Linq.Mapping.TableAttribute(Name="")]
+       public partial class Department : INotifyPropertyChanging, INotifyPropertyChanged
+       {
+               
+               private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+               
+               private System.Guid _DepartmentId;
+               
+               private string _Name;
+               
+               private EntitySet<Person> _Persons;
+               
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnDepartmentIdChanging(System.Guid value);
+    partial void OnDepartmentIdChanged();
+    partial void OnNameChanging(string value);
+    partial void OnNameChanged();
+    #endregion
+               
+               public Department()
+               {
+                       this._Persons = new EntitySet<Person>(new Action<Person>(this.attach_Persons), new Action<Person>(this.detach_Persons));
+                       OnCreated();
+               }
+               
+               [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_DepartmentId", IsPrimaryKey=true)]
+               public System.Guid DepartmentId
+               {
+                       get
+                       {
+                               return this._DepartmentId;
+                       }
+                       set
+                       {
+                               if ((this._DepartmentId != value))
+                               {
+                                       this.OnDepartmentIdChanging(value);
+                                       this.SendPropertyChanging();
+                                       this._DepartmentId = value;
+                                       this.SendPropertyChanged("DepartmentId");
+                                       this.OnDepartmentIdChanged();
+                               }
+                       }
+               }
+               
+               [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Name", CanBeNull=false)]
+               public string Name
+               {
+                       get
+                       {
+                               return this._Name;
+                       }
+                       set
+                       {
+                               if ((this._Name != value))
+                               {
+                                       this.OnNameChanging(value);
+                                       this.SendPropertyChanging();
+                                       this._Name = value;
+                                       this.SendPropertyChanged("Name");
+                                       this.OnNameChanged();
+                               }
+                       }
+               }
+               
+               [global::System.Data.Linq.Mapping.AssociationAttribute(Name="Department_Person", Storage="_Persons", ThisKey="DepartmentId", OtherKey="DepartmentId")]
+               public EntitySet<Person> Persons
+               {
+                       get
+                       {
+                               return this._Persons;
+                       }
+                       set
+                       {
+                               this._Persons.Assign(value);
+                       }
+               }
+               
+               public event PropertyChangingEventHandler PropertyChanging;
+               
+               public event PropertyChangedEventHandler PropertyChanged;
+               
+               protected virtual void SendPropertyChanging()
+               {
+                       if ((this.PropertyChanging != null))
+                       {
+                               this.PropertyChanging(this, emptyChangingEventArgs);
+                       }
+               }
+               
+               protected virtual void SendPropertyChanged(String propertyName)
+               {
+                       if ((this.PropertyChanged != null))
+                       {
+                               this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+                       }
+               }
+               
+               private void attach_Persons(Person entity)
+               {
+                       this.SendPropertyChanging();
+                       entity.Department = this;
+               }
+               
+               private void detach_Persons(Person entity)
+               {
+                       this.SendPropertyChanging();
+                       entity.Department = null;
+               }
+       }
+}
+#pragma warning restore 1591
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClassesSerializationTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClassesSerializationTests.cs
new file mode 100644 (file)
index 0000000..08bc646
--- /dev/null
@@ -0,0 +1,110 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Tests.LinqToSql;
+using NUnit.Framework;
+using System.Reflection;
+using System.ComponentModel;
+using Newtonsoft.Json.Serialization;
+using System.Data.Linq.Mapping;
+
+namespace Newtonsoft.Json.Tests.LinqToSql
+{
+  public class LinqToSqlClassesSerializationTests : TestFixtureBase
+  {
+    [Test]
+    public void Serialize()
+    {
+      Role role = new Role();
+      role.Name = "Role1";
+      role.RoleId = new Guid("67EA92B7-4BD3-4718-BD75-3C7EDF800B34");
+
+      Person person = new Person();
+      person.FirstName = "FirstName!";
+      person.LastName = "LastName!";
+      person.PersonId = new Guid("7AA027AA-C995-4986-908D-999D8063599F");
+      person.PersonRoles.Add(new PersonRole
+                               {
+                                 PersonRoleId = new Guid("B012DD41-71DF-4839-B8D5-D1333FB886BC"),
+                                 Role = role
+                               });
+
+      person.Department = new Department
+                               {
+                                 DepartmentId = new Guid("08F68BF9-929B-4434-BC47-C9489D22112B"),
+                                 Name = "Name!"
+                               };
+
+      string json = JsonConvert.SerializeObject(person, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
+
+      Assert.AreEqual(@"{
+  ""first_name"": ""FirstName!"",
+  ""LastName"": ""LastName!"",
+  ""PersonId"": ""7aa027aa-c995-4986-908d-999d8063599f"",
+  ""DepartmentId"": ""08f68bf9-929b-4434-bc47-c9489d22112b"",
+  ""PersonRoles"": [
+    {
+      ""PersonId"": ""7aa027aa-c995-4986-908d-999d8063599f"",
+      ""RoleId"": ""67ea92b7-4bd3-4718-bd75-3c7edf800b34"",
+      ""PersonRoleId"": ""b012dd41-71df-4839-b8d5-d1333fb886bc"",
+      ""Role"": {
+        ""Name"": ""Role1"",
+        ""RoleId"": ""t5LqZ9NLGEe9dTx+34ALNA==""
+      }
+    }
+  ],
+  ""Department"": {
+    ""DepartmentId"": ""08f68bf9-929b-4434-bc47-c9489d22112b"",
+    ""Name"": ""!emaN""
+  }
+}", json);
+    }
+
+    [Test]
+    public void Deserialize()
+    {
+      string json = @"{
+  ""first_name"": ""FirstName!"",
+  ""LastName"": ""LastName!"",
+  ""PersonId"": ""7aa027aa-c995-4986-908d-999d8063599f"",
+  ""PersonRoles"": [
+    {
+      ""PersonId"": ""7aa027aa-c995-4986-908d-999d8063599f"",
+      ""RoleId"": ""67ea92b7-4bd3-4718-bd75-3c7edf800b34"",
+      ""PersonRoleId"": ""b012dd41-71df-4839-b8d5-d1333fb886bc"",
+      ""Role"": {
+        ""Name"": ""Role1"",
+        ""RoleId"": ""t5LqZ9NLGEe9dTx+34ALNA==""
+      }
+    }
+  ],
+  ""Department"": {
+    ""DepartmentId"": ""08f68bf9-929b-4434-bc47-c9489d22112b"",
+    ""Name"": ""!emaN""
+  }
+}";
+
+      Person person = JsonConvert.DeserializeObject<Person>(json);
+      Assert.IsNotNull(person);
+
+      Assert.AreEqual(new Guid("7AA027AA-C995-4986-908D-999D8063599F"), person.PersonId);
+      Assert.AreEqual("FirstName!", person.FirstName);
+      Assert.AreEqual("LastName!", person.LastName);
+      Assert.AreEqual(1, person.PersonRoles.Count);
+      Assert.AreEqual(person.PersonId, person.PersonRoles[0].PersonId);
+      Assert.AreEqual(new Guid("67EA92B7-4BD3-4718-BD75-3C7EDF800B34"), person.PersonRoles[0].RoleId);
+      Assert.IsNotNull(person.PersonRoles[0].Role);
+      Assert.AreEqual(1, person.PersonRoles[0].Role.PersonRoles.Count);
+
+      Assert.AreEqual("Name!", person.Department.Name);
+
+      TableAttribute tableAttribute = JsonTypeReflector.GetAttribute<TableAttribute>(typeof(Person));
+      Assert.AreEqual("", tableAttribute.Name);
+
+      ColumnAttribute columnAttribute = JsonTypeReflector.GetAttribute<ColumnAttribute>(typeof(Person).GetProperty("FirstName"));
+      Assert.AreEqual("_FirstName", columnAttribute.Storage);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/LinqToSql/Person.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/LinqToSql/Person.cs
new file mode 100644 (file)
index 0000000..57ec3dc
--- /dev/null
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Tests.LinqToSql
+{
+  [MetadataType(typeof(PersonMetadata))]
+  public partial class Person
+  {
+    public class PersonMetadata
+    {
+      [JsonProperty("first_name")]
+      public string FirstName { get; set; }
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/LinqToSql/Role.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/LinqToSql/Role.cs
new file mode 100644 (file)
index 0000000..b7108ed
--- /dev/null
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Data.Linq;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Tests.LinqToSql
+{
+  [MetadataType(typeof(RoleMetadata))]
+  public partial class Role
+  {
+    public class RoleMetadata
+    {
+      [JsonConverter(typeof(GuidByteArrayConverter))]
+      public Guid RoleId { get; set; }
+      [JsonIgnore]
+      public EntitySet<PersonRole> PersonRoles { get; set; }
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj
new file mode 100644 (file)
index 0000000..44b5612
--- /dev/null
@@ -0,0 +1,262 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{3E6E2335-B079-4B5B-A65A-9D586914BCBB}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Newtonsoft.Json.Tests</RootNamespace>
+    <AssemblyName>Newtonsoft.Json.Tests.Net20</AssemblyName>
+    <SccProjectName>
+    </SccProjectName>
+    <SccLocalPath>
+    </SccLocalPath>
+    <SccAuxPath>
+    </SccAuxPath>
+    <SccProvider>
+    </SccProvider>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+    <SignAssembly>false</SignAssembly>
+    <AssemblyOriginatorKeyFile>
+    </AssemblyOriginatorKeyFile>
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\Net20\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;NET20</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\Net20\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="LinqBridge, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c2b14eb747628076, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\Lib\LinqBridge.dll</HintPath>
+    </Reference>
+    <Reference Include="nunit.framework, Version=2.4.3.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\Lib\NUnit\DotNet\nunit.framework.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Security" />
+    <Reference Include="System.Web" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Bson\BsonReaderTests.cs" />
+    <Compile Include="Bson\BsonWriterTests.cs" />
+    <Compile Include="Converters\BinaryConverterTests.cs" />
+    <Compile Include="Converters\CustomCreationConverterTests.cs" />
+    <Compile Include="Converters\DataSetConverterTests.cs" />
+    <Compile Include="Converters\DataTableConverterTests.cs" />
+    <Compile Include="Converters\ObjectIdConverterTests.cs" />
+    <Compile Include="Converters\RegexConverterTests.cs" />
+    <Compile Include="Converters\StringEnumConverterTests.cs" />
+    <Compile Include="JsonArrayAttributeTests.cs" />
+    <Compile Include="ExceptionTests.cs" />
+    <Compile Include="JsonValidatingReaderTests.cs" />
+    <Compile Include="Linq\ComponentModel\BindingTests.cs" />
+    <Compile Include="Linq\ComponentModel\JPropertyDescriptorTests.cs" />
+    <Compile Include="Linq\JPathTests.cs" />
+    <Compile Include="Linq\JRawTests.cs" />
+    <Compile Include="Serialization\ConstructorHandlingTests.cs" />
+    <Compile Include="TestObjects\Bar.cs" />
+    <Compile Include="TestObjects\Car.cs" />
+    <Compile Include="TestObjects\Computer.cs" />
+    <Compile Include="TestObjects\ConstructorReadonlyFields.cs" />
+    <Compile Include="TestObjects\Container.cs" />
+    <Compile Include="TestObjects\Content.cs" />
+    <Compile Include="TestObjects\ContentBaseClass.cs" />
+    <Compile Include="TestObjects\ContentSubClass.cs" />
+    <Compile Include="TestObjects\DictionaryInterfaceClass.cs" />
+    <Compile Include="Serialization\EntitiesSerializationTests.cs" />
+    <Compile Include="TestObjects\Event.cs" />
+    <Compile Include="TestObjects\Foo.cs" />
+    <Compile Include="TestObjects\GoogleMapGeocoderStructure.cs" />
+    <Compile Include="TestObjects\HolderClass.cs" />
+    <Compile Include="TestObjects\InterfacePropertyTestClass.cs" />
+    <Compile Include="TestObjects\JsonPropertyClass.cs" />
+    <Compile Include="Serialization\JsonSerializerTest.cs" />
+    <Compile Include="TestObjects\ListOfIds.cs" />
+    <Compile Include="TestObjects\ListTestClass.cs" />
+    <Compile Include="TestObjects\LogEntry.cs" />
+    <Compile Include="Serialization\MissingMemberHandlingTests.cs" />
+    <Compile Include="TestObjects\Movie.cs" />
+    <Compile Include="TestObjects\NonRequest.cs" />
+    <Compile Include="TestObjects\ObjectArrayPropertyTest.cs" />
+    <Compile Include="Serialization\PopulateTests.cs" />
+    <Compile Include="TestObjects\PersonError.cs" />
+    <Compile Include="TestObjects\PersonPropertyClass.cs" />
+    <Compile Include="TestObjects\PrivateConstructorTestClass.cs" />
+    <Compile Include="TestObjects\PrivateConstructorWithPublicParametizedConstructorTestClass.cs" />
+    <Compile Include="TestObjects\PropertyCase.cs" />
+    <Compile Include="TestObjects\RequestOnly.cs" />
+    <Compile Include="TestObjects\RoleTransfer.cs" />
+    <Compile Include="Serialization\SerializationErrorHandlingTests.cs" />
+    <Compile Include="Serialization\SerializationEventAttributeTests.cs" />
+    <Compile Include="Schema\ExtensionsTests.cs" />
+    <Compile Include="Schema\JsonSchemaModelBuilderTests.cs" />
+    <Compile Include="Schema\JsonSchemaNodeTests.cs" />
+    <Compile Include="Serialization\CamelCasePropertyNamesContractResolverTests.cs" />
+    <Compile Include="Serialization\PreserveReferencesHandlingTests.cs" />
+    <Compile Include="TestObjects\SearchResult.cs" />
+    <Compile Include="TestObjects\SetOnlyPropertyClass2.cs" />
+    <Compile Include="TestObjects\StructTest.cs" />
+    <Compile Include="TestObjects\SubKlass.cs" />
+    <Compile Include="TestObjects\SuperKlass.cs" />
+    <Compile Include="Serialization\TypeNameHandlingTests.cs" />
+    <Compile Include="TestObjects\AbstractGenericBase.cs" />
+    <Compile Include="TestObjects\ArgumentConverterPrecedenceClassConverter.cs" />
+    <Compile Include="TestObjects\BadJsonPropertyClass.cs" />
+    <Compile Include="TestObjects\CircularReferenceClass.cs" />
+    <Compile Include="TestObjects\ClassAndMemberConverterClass.cs" />
+    <Compile Include="TestObjects\ClassConverterPrecedenceClassConverter.cs" />
+    <Compile Include="TestObjects\ConstructorCaseSensitivityClass.cs" />
+    <Compile Include="TestObjects\ConverterPrecedenceClass.cs" />
+    <Compile Include="TestObjects\ConverterPrecedenceClassConverter.cs" />
+    <Compile Include="TestObjects\CircularReferenceWithIdClass.cs" />
+    <Compile Include="TestObjects\DateTimeErrorObjectCollection.cs" />
+    <Compile Include="TestObjects\EmployeeReference.cs" />
+    <Compile Include="TestObjects\JsonPropertyWithHandlingValues.cs" />
+    <Compile Include="TestObjects\DefaultValueAttributeTestClass.cs" />
+    <Compile Include="TestObjects\DoubleClass.cs" />
+    <Compile Include="TestObjects\GenericImpl.cs" />
+    <Compile Include="TestObjects\GenericListAndDictionaryInterfaceProperties.cs" />
+    <Compile Include="TestObjects\GetOnlyPropertyClass.cs" />
+    <Compile Include="TestObjects\IncompatibleJsonAttributeClass.cs" />
+    <Compile Include="TestObjects\Invoice.cs" />
+    <Compile Include="TestObjects\JsonIgnoreAttributeTestClass.cs" />
+    <Compile Include="TestObjects\ListErrorObject.cs" />
+    <Compile Include="TestObjects\ListErrorObjectCollection.cs" />
+    <Compile Include="TestObjects\MemberConverterPrecedenceClassConverter.cs" />
+    <Compile Include="TestObjects\MethodExecutorObject.cs" />
+    <Compile Include="TestObjects\JaggedArray.cs" />
+    <Compile Include="TestObjects\MyClass.cs" />
+    <Compile Include="TestObjects\Name.cs" />
+    <Compile Include="TestObjects\NullableDateTimeTestClass.cs" />
+    <Compile Include="TestObjects\PersonRaw.cs" />
+    <Compile Include="TestObjects\PhoneNumber.cs" />
+    <Compile Include="TestObjects\PrivateMembersClass.cs" />
+    <Compile Include="TestObjects\RequiredMembersClass.cs" />
+    <Compile Include="TestObjects\SerializationEventTestDictionary.cs" />
+    <Compile Include="TestObjects\SerializationEventTestList.cs" />
+    <Compile Include="TestObjects\SerializationEventTestObject.cs" />
+    <Compile Include="TestObjects\SerializationEventTestObjectWithConstructor.cs" />
+    <Compile Include="TestObjects\SetOnlyPropertyClass.cs" />
+    <Compile Include="TestObjects\Article.cs" />
+    <Compile Include="TestObjects\ArticleCollection.cs" />
+    <Compile Include="TestObjects\ClassWithArray.cs" />
+    <Compile Include="TestObjects\ClassWithGuid.cs" />
+    <Compile Include="TestObjects\ConverableMembers.cs" />
+    <Compile Include="TestObjects\JsonIgnoreAttributeOnClassTestClass.cs" />
+    <Compile Include="Linq\JConstructorTests.cs" />
+    <Compile Include="Linq\JPropertyTests.cs" />
+    <Compile Include="TestObjects\MemberConverterClass.cs" />
+    <Compile Include="TestObjects\Product.cs" />
+    <Compile Include="TestObjects\ProductCollection.cs" />
+    <Compile Include="TestObjects\ProductShort.cs" />
+    <Compile Include="TestObjects\Shortie.cs" />
+    <Compile Include="TestObjects\Store.cs" />
+    <Compile Include="TestObjects\StoreColor.cs" />
+    <Compile Include="TestObjects\Person.cs" />
+    <Compile Include="Schema\JsonSchemaBuilderTests.cs" />
+    <Compile Include="Schema\JsonSchemaGeneratorTests.cs" />
+    <Compile Include="Schema\JsonSchemaTests.cs" />
+    <Compile Include="TestObjects\DateTimeTestClass.cs" />
+    <Compile Include="Converters\IsoDateTimeConverterTests.cs" />
+    <Compile Include="JsonConvertTest.cs" />
+    <Compile Include="Converters\JavaScriptDateTimeConverterTests.cs" />
+    <Compile Include="JsonTextReaderTest.cs" />
+    <Compile Include="JsonTextWriterTest.cs" />
+    <Compile Include="Linq\JTokenReaderTest.cs" />
+    <Compile Include="Linq\JTokenWriterTest.cs" />
+    <Compile Include="Linq\JArrayTests.cs" />
+    <Compile Include="Linq\JObjectTests.cs" />
+    <Compile Include="Linq\JTokenEqualityComparerTests.cs" />
+    <Compile Include="Linq\JTokenTests.cs" />
+    <Compile Include="Linq\JValueTests.cs" />
+    <Compile Include="Linq\LinqToJsonTest.cs" />
+    <Compile Include="PerformanceTests.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="SilverlightTests.cs" />
+    <Compile Include="TestFixtureBase.cs" />
+    <Compile Include="Converters\XmlNodeConverterTest.cs" />
+    <Compile Include="TestObjects\TypeClass.cs" />
+    <Compile Include="TestObjects\TypedSubHashtable.cs" />
+    <Compile Include="TestObjects\UserNullable.cs" />
+    <Compile Include="TestObjects\VersionKeyedCollection.cs" />
+    <Compile Include="TestObjects\WagePerson.cs" />
+    <Compile Include="Utilities\DynamicReflectionDelegateFactoryTests.cs" />
+    <Compile Include="Utilities\ReflectionUtilsTests.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Service Include="{3259AA49-8AA1-44D3-9025-A0B520596A8C}" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\Newtonsoft.Json\Newtonsoft.Json.Net20.csproj">
+      <Project>{A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}</Project>
+      <Name>Newtonsoft.Json.Net20</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 3.1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net35.csproj b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net35.csproj
new file mode 100644 (file)
index 0000000..05cb732
--- /dev/null
@@ -0,0 +1,321 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{3E6E2335-B079-4B5B-A65A-9D586914BCBB}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Newtonsoft.Json.Tests.Net35</RootNamespace>
+    <AssemblyName>Newtonsoft.Json.Tests.Net35</AssemblyName>
+    <SccProjectName>
+    </SccProjectName>
+    <SccLocalPath>
+    </SccLocalPath>
+    <SccAuxPath>
+    </SccAuxPath>
+    <SccProvider>
+    </SccProvider>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <SignAssembly>false</SignAssembly>
+    <AssemblyOriginatorKeyFile>
+    </AssemblyOriginatorKeyFile>
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\Net35\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;NET35</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\Net35\</OutputPath>
+    <DefineConstants>TRACE;NET35</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="nunit.framework, Version=2.4.3.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\Lib\NUnit\DotNet\nunit.framework.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.ComponentModel.DataAnnotations">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Data.Entity">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data.Linq">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Runtime.Serialization">
+      <RequiredTargetFramework>3.0</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Security" />
+    <Reference Include="System.ServiceModel">
+      <RequiredTargetFramework>3.0</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.ServiceModel.Web">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Web" />
+    <Reference Include="System.Web.Extensions">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Xml" />
+    <Reference Include="System.Xml.Linq">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Bson\BsonWriterTests.cs" />
+    <Compile Include="Bson\BsonReaderTests.cs" />
+    <Compile Include="Converters\BinaryConverterTests.cs" />
+    <Compile Include="Converters\ExpandoObjectConverterTests.cs" />
+    <Compile Include="Converters\RegexConverterTests.cs" />
+    <Compile Include="Converters\DataTableConverterTests.cs" />
+    <Compile Include="Converters\DataSetConverterTests.cs" />
+    <Compile Include="Converters\CustomCreationConverterTests.cs" />
+    <Compile Include="Converters\ObjectIdConverterTests.cs" />
+    <Compile Include="Converters\StringEnumConverterTests.cs" />
+    <Compile Include="JsonArrayAttributeTests.cs" />
+    <Compile Include="ExceptionTests.cs" />
+    <Compile Include="JsonValidatingReaderTests.cs" />
+    <Compile Include="LinqToSql\Department.cs" />
+    <Compile Include="LinqToSql\DepartmentConverter.cs" />
+    <Compile Include="LinqToSql\GuidByteArrayConverter.cs" />
+    <Compile Include="LinqToSql\Role.cs" />
+    <Compile Include="LinqToSql\LinqToSqlClasses.designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>LinqToSqlClasses.dbml</DependentUpon>
+    </Compile>
+    <Compile Include="LinqToSql\LinqToSqlClassesSerializationTests.cs" />
+    <Compile Include="LinqToSql\Person.cs" />
+    <Compile Include="Linq\ComponentModel\BindingTests.cs" />
+    <Compile Include="Linq\ComponentModel\JPropertyDescriptorTests.cs" />
+    <Compile Include="Linq\DynamicTests.cs" />
+    <Compile Include="Linq\JPathTests.cs" />
+    <Compile Include="Linq\JRawTests.cs" />
+    <Compile Include="Serialization\ConstructorHandlingTests.cs" />
+    <Compile Include="Serialization\ContractResolverTests.cs" />
+    <Compile Include="Serialization\DefaultValueHandlingTests.cs" />
+    <Compile Include="Serialization\DynamicTests.cs" />
+    <Compile Include="Serialization\NullValueHandlingTests.cs" />
+    <Compile Include="TestObjects\Bar.cs" />
+    <Compile Include="TestObjects\Car.cs" />
+    <Compile Include="TestObjects\Computer.cs" />
+    <Compile Include="TestObjects\ConstructorReadonlyFields.cs" />
+    <Compile Include="TestObjects\Container.cs" />
+    <Compile Include="TestObjects\ContentBaseClass.cs" />
+    <Compile Include="TestObjects\ContentSubClass.cs" />
+    <Compile Include="TestObjects\Foo.cs" />
+    <Compile Include="TestObjects\HolderClass.cs" />
+    <Compile Include="TestObjects\ListOfIds.cs" />
+    <Compile Include="TestObjects\Movie.cs" />
+    <Compile Include="TestObjects\PersonError.cs" />
+    <Compile Include="TestObjects\PersonPropertyClass.cs" />
+    <Compile Include="TestObjects\PrivateConstructorTestClass.cs" />
+    <Compile Include="TestObjects\PrivateConstructorWithPublicParametizedConstructorTestClass.cs" />
+    <Compile Include="TestObjects\Content.cs" />
+    <Compile Include="TestObjects\DateTimeErrorObjectCollection.cs" />
+    <Compile Include="Serialization\EntitiesSerializationTests.cs" />
+    <Compile Include="TestObjects\DictionaryInterfaceClass.cs" />
+    <Compile Include="TestObjects\Event.cs" />
+    <Compile Include="TestObjects\GoogleMapGeocoderStructure.cs" />
+    <Compile Include="TestObjects\InterfacePropertyTestClass.cs" />
+    <Compile Include="TestObjects\JsonPropertyClass.cs" />
+    <Compile Include="TestObjects\ListErrorObject.cs" />
+    <Compile Include="TestObjects\ListErrorObjectCollection.cs" />
+    <Compile Include="Serialization\MissingMemberHandlingTests.cs" />
+    <Compile Include="Serialization\PopulateTests.cs" />
+    <Compile Include="Serialization\SerializationErrorHandlingTests.cs" />
+    <Compile Include="Serialization\SerializationEventAttributeTests.cs" />
+    <Compile Include="Schema\ExtensionsTests.cs" />
+    <Compile Include="Schema\JsonSchemaModelBuilderTests.cs" />
+    <Compile Include="Schema\JsonSchemaNodeTests.cs" />
+    <Compile Include="Serialization\CamelCasePropertyNamesContractResolverTests.cs" />
+    <Compile Include="Serialization\PreserveReferencesHandlingTests.cs" />
+    <Compile Include="Serialization\TypeNameHandlingTests.cs" />
+    <Compile Include="TestObjects\ListTestClass.cs" />
+    <Compile Include="TestObjects\LogEntry.cs" />
+    <Compile Include="TestObjects\NonRequest.cs" />
+    <Compile Include="TestObjects\ObjectArrayPropertyTest.cs" />
+    <Compile Include="TestObjects\SearchResult.cs" />
+    <Compile Include="TestObjects\StructTest.cs" />
+    <Compile Include="TestObjects\WagePerson.cs" />
+    <Compile Include="TestObjects\PropertyCase.cs" />
+    <Compile Include="TestObjects\RequestOnly.cs" />
+    <Compile Include="TestObjects\RoleTransfer.cs" />
+    <Compile Include="TestObjects\SetOnlyPropertyClass2.cs" />
+    <Compile Include="TestObjects\SubKlass.cs" />
+    <Compile Include="TestObjects\SuperKlass.cs" />
+    <Compile Include="TestObjects\VersionKeyedCollection.cs" />
+    <Compile Include="TestObjects\AbstractGenericBase.cs" />
+    <Compile Include="TestObjects\ArgumentConverterPrecedenceClassConverter.cs" />
+    <Compile Include="TestObjects\BadJsonPropertyClass.cs" />
+    <Compile Include="TestObjects\CircularReferenceClass.cs" />
+    <Compile Include="TestObjects\ClassAndMemberConverterClass.cs" />
+    <Compile Include="TestObjects\ClassConverterPrecedenceClassConverter.cs" />
+    <Compile Include="TestObjects\ConstructorCaseSensitivityClass.cs" />
+    <Compile Include="TestObjects\ConverterPrecedenceClass.cs" />
+    <Compile Include="TestObjects\ConverterPrecedenceClassConverter.cs" />
+    <Compile Include="TestObjects\CircularReferenceWithIdClass.cs" />
+    <Compile Include="TestObjects\EmployeeReference.cs" />
+    <Compile Include="TestObjects\JsonPropertyWithHandlingValues.cs" />
+    <Compile Include="TestObjects\DefaultValueAttributeTestClass.cs" />
+    <Compile Include="TestObjects\DoubleClass.cs" />
+    <Compile Include="TestObjects\GenericImpl.cs" />
+    <Compile Include="TestObjects\GenericListAndDictionaryInterfaceProperties.cs" />
+    <Compile Include="TestObjects\GetOnlyPropertyClass.cs" />
+    <Compile Include="TestObjects\IncompatibleJsonAttributeClass.cs" />
+    <Compile Include="TestObjects\Invoice.cs" />
+    <Compile Include="TestObjects\JsonIgnoreAttributeTestClass.cs" />
+    <Compile Include="TestObjects\MemberConverterPrecedenceClassConverter.cs" />
+    <Compile Include="TestObjects\MethodExecutorObject.cs" />
+    <Compile Include="TestObjects\JaggedArray.cs" />
+    <Compile Include="TestObjects\MyClass.cs" />
+    <Compile Include="TestObjects\Name.cs" />
+    <Compile Include="TestObjects\PersonRaw.cs" />
+    <Compile Include="TestObjects\PhoneNumber.cs" />
+    <Compile Include="TestObjects\PrivateMembersClass.cs" />
+    <Compile Include="TestObjects\RequiredMembersClass.cs" />
+    <Compile Include="TestObjects\SerializationEventTestDictionary.cs" />
+    <Compile Include="TestObjects\SerializationEventTestList.cs" />
+    <Compile Include="TestObjects\SerializationEventTestObject.cs" />
+    <Compile Include="TestObjects\SerializationEventTestObjectWithConstructor.cs" />
+    <Compile Include="TestObjects\SetOnlyPropertyClass.cs" />
+    <Compile Include="TestObjects\Article.cs" />
+    <Compile Include="TestObjects\ArticleCollection.cs" />
+    <Compile Include="TestObjects\ClassWithArray.cs" />
+    <Compile Include="TestObjects\ClassWithGuid.cs" />
+    <Compile Include="TestObjects\ConverableMembers.cs" />
+    <Compile Include="TestObjects\JsonIgnoreAttributeOnClassTestClass.cs" />
+    <Compile Include="Linq\JConstructorTests.cs" />
+    <Compile Include="Linq\JPropertyTests.cs" />
+    <Compile Include="TestObjects\MemberConverterClass.cs" />
+    <Compile Include="TestObjects\Product.cs" />
+    <Compile Include="TestObjects\ProductCollection.cs" />
+    <Compile Include="TestObjects\ProductShort.cs" />
+    <Compile Include="TestObjects\Shortie.cs" />
+    <Compile Include="TestObjects\Store.cs" />
+    <Compile Include="TestObjects\StoreColor.cs" />
+    <Compile Include="TestObjects\Person.cs" />
+    <Compile Include="Schema\JsonSchemaBuilderTests.cs" />
+    <Compile Include="Schema\JsonSchemaGeneratorTests.cs" />
+    <Compile Include="Schema\JsonSchemaTests.cs" />
+    <Compile Include="TestObjects\NullableDateTimeTestClass.cs" />
+    <Compile Include="TestObjects\DateTimeTestClass.cs" />
+    <Compile Include="Converters\IsoDateTimeConverterTests.cs" />
+    <Compile Include="JsonConvertTest.cs" />
+    <Compile Include="Converters\JavaScriptDateTimeConverterTests.cs" />
+    <Compile Include="Serialization\JsonSerializerTest.cs" />
+    <Compile Include="JsonTextReaderTest.cs" />
+    <Compile Include="JsonTextWriterTest.cs" />
+    <Compile Include="Linq\JTokenReaderTest.cs" />
+    <Compile Include="Linq\JTokenWriterTest.cs" />
+    <Compile Include="Linq\JArrayTests.cs" />
+    <Compile Include="Linq\JObjectTests.cs" />
+    <Compile Include="Linq\JTokenEqualityComparerTests.cs" />
+    <Compile Include="Linq\JTokenTests.cs" />
+    <Compile Include="Linq\JValueTests.cs" />
+    <Compile Include="Linq\LinqToJsonTest.cs" />
+    <Compile Include="PerformanceTests.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="SilverlightTests.cs" />
+    <Compile Include="TestFixtureBase.cs" />
+    <Compile Include="Converters\XmlNodeConverterTest.cs" />
+    <Compile Include="TestObjects\TypeClass.cs" />
+    <Compile Include="TestObjects\TypedSubHashtable.cs" />
+    <Compile Include="TestObjects\UserNullable.cs" />
+    <Compile Include="Utilities\DynamicReflectionDelegateFactoryTests.cs" />
+    <Compile Include="Utilities\ReflectionUtilsTests.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="LinqToSql\LinqToSqlClasses.dbml">
+      <Generator>MSLinqToSQLGenerator</Generator>
+      <LastGenOutput>LinqToSqlClasses.designer.cs</LastGenOutput>
+      <SubType>Designer</SubType>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <Service Include="{3259AA49-8AA1-44D3-9025-A0B520596A8C}" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="LinqToSql\LinqToSqlClasses.dbml.layout">
+      <DependentUpon>LinqToSqlClasses.dbml</DependentUpon>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="bunny_pancake.jpg">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 3.1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\Newtonsoft.Json\Newtonsoft.Json.Net35.csproj">
+      <Project>{A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}</Project>
+      <Name>Newtonsoft.Json.Net35</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj
new file mode 100644 (file)
index 0000000..dbd6848
--- /dev/null
@@ -0,0 +1,291 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup Condition="'$(MSBuildToolsVersion)' == '3.5'">
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+  </PropertyGroup>
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{0D8C3C2E-62C6-4C93-9377-6F74DD6BFD93}</ProjectGuid>
+    <ProjectTypeGuids>{A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Newtonsoft.Json.Tests.Silverlight</RootNamespace>
+    <AssemblyName>Newtonsoft.Json.Tests.Silverlight</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <SilverlightApplication>false</SilverlightApplication>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+    <TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier>
+    <SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+    <TargetFrameworkProfile />
+    <SignManifests>false</SignManifests>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>Bin\Debug\Silverlight\</OutputPath>
+    <DefineConstants>DEBUG;TRACE;SILVERLIGHT</DefineConstants>
+    <NoStdLib>true</NoStdLib>
+    <NoConfig>true</NoConfig>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>Bin\Release\Silverlight\</OutputPath>
+    <DefineConstants>TRACE;SILVERLIGHT</DefineConstants>
+    <NoStdLib>true</NoStdLib>
+    <NoConfig>true</NoConfig>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Microsoft.CSharp, Version=2.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="nunit.framework, Version=2.4.7.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\Lib\NUnit\Silverlight\nunit.framework.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.Net">
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.Runtime.Serialization">
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.ServiceModel.Web">
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.Windows">
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="mscorlib" />
+    <Reference Include="system">
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.Core">
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.Xml">
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.Windows.Browser">
+      <Private>True</Private>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Bson\BsonReaderTests.cs" />
+    <Compile Include="Bson\BsonWriterTests.cs" />
+    <Compile Include="Converters\BinaryConverterTests.cs" />
+    <Compile Include="Converters\CustomCreationConverterTests.cs" />
+    <Compile Include="Converters\DataSetConverterTests.cs" />
+    <Compile Include="Converters\DataTableConverterTests.cs" />
+    <Compile Include="Converters\ExpandoObjectConverterTests.cs" />
+    <Compile Include="Converters\ObjectIdConverterTests.cs" />
+    <Compile Include="Converters\RegexConverterTests.cs" />
+    <Compile Include="Converters\StringEnumConverterTests.cs" />
+    <Compile Include="ExceptionTests.cs" />
+    <Compile Include="JsonArrayAttributeTests.cs" />
+    <Compile Include="Linq\ComponentModel\BindingTests.cs" />
+    <Compile Include="Linq\ComponentModel\JPropertyDescriptorTests.cs" />
+    <Compile Include="Linq\DynamicTests.cs" />
+    <Compile Include="Linq\JPathTests.cs" />
+    <Compile Include="Linq\JRawTests.cs" />
+    <Compile Include="Linq\JTokenReaderTest.cs" />
+    <Compile Include="Linq\JTokenWriterTest.cs" />
+    <Compile Include="JsonValidatingReaderTests.cs" />
+    <Compile Include="Schema\ExtensionsTests.cs" />
+    <Compile Include="Schema\JsonSchemaModelBuilderTests.cs" />
+    <Compile Include="Schema\JsonSchemaNodeTests.cs" />
+    <Compile Include="Serialization\CamelCasePropertyNamesContractResolverTests.cs" />
+    <Compile Include="Serialization\ConstructorHandlingTests.cs" />
+    <Compile Include="Serialization\DynamicTests.cs" />
+    <Compile Include="Serialization\EntitiesSerializationTests.cs" />
+    <Compile Include="Serialization\JsonSerializerTest.cs" />
+    <Compile Include="Serialization\MissingMemberHandlingTests.cs" />
+    <Compile Include="Serialization\PopulateTests.cs" />
+    <Compile Include="Serialization\PreserveReferencesHandlingTests.cs" />
+    <Compile Include="Serialization\SerializationErrorHandlingTests.cs" />
+    <Compile Include="Serialization\SerializationEventAttributeTests.cs" />
+    <Compile Include="Serialization\TypeNameHandlingTests.cs" />
+    <Compile Include="TestObjects\AbstractGenericBase.cs" />
+    <Compile Include="TestObjects\ArgumentConverterPrecedenceClassConverter.cs" />
+    <Compile Include="TestObjects\BadJsonPropertyClass.cs" />
+    <Compile Include="TestObjects\Bar.cs" />
+    <Compile Include="TestObjects\Car.cs" />
+    <Compile Include="TestObjects\CircularReferenceClass.cs" />
+    <Compile Include="TestObjects\ClassAndMemberConverterClass.cs" />
+    <Compile Include="TestObjects\ClassConverterPrecedenceClassConverter.cs" />
+    <Compile Include="TestObjects\Computer.cs" />
+    <Compile Include="TestObjects\ConstructorCaseSensitivityClass.cs" />
+    <Compile Include="TestObjects\ConstructorReadonlyFields.cs" />
+    <Compile Include="TestObjects\Container.cs" />
+    <Compile Include="TestObjects\Content.cs" />
+    <Compile Include="TestObjects\ContentBaseClass.cs" />
+    <Compile Include="TestObjects\ContentSubClass.cs" />
+    <Compile Include="TestObjects\ConverterPrecedenceClass.cs" />
+    <Compile Include="TestObjects\ConverterPrecedenceClassConverter.cs" />
+    <Compile Include="TestObjects\CircularReferenceWithIdClass.cs" />
+    <Compile Include="TestObjects\DateTimeErrorObjectCollection.cs" />
+    <Compile Include="TestObjects\DefaultValueAttributeTestClass.cs" />
+    <Compile Include="TestObjects\DictionaryInterfaceClass.cs" />
+    <Compile Include="TestObjects\DoubleClass.cs" />
+    <Compile Include="TestObjects\EmployeeReference.cs" />
+    <Compile Include="TestObjects\Event.cs" />
+    <Compile Include="TestObjects\Foo.cs" />
+    <Compile Include="TestObjects\GenericImpl.cs" />
+    <Compile Include="TestObjects\GenericListAndDictionaryInterfaceProperties.cs" />
+    <Compile Include="TestObjects\GetOnlyPropertyClass.cs" />
+    <Compile Include="TestObjects\GoogleMapGeocoderStructure.cs" />
+    <Compile Include="TestObjects\HolderClass.cs" />
+    <Compile Include="TestObjects\IncompatibleJsonAttributeClass.cs" />
+    <Compile Include="TestObjects\InterfacePropertyTestClass.cs" />
+    <Compile Include="TestObjects\Invoice.cs" />
+    <Compile Include="TestObjects\JaggedArray.cs" />
+    <Compile Include="TestObjects\JsonIgnoreAttributeTestClass.cs" />
+    <Compile Include="TestObjects\JsonPropertyClass.cs" />
+    <Compile Include="TestObjects\JsonPropertyWithHandlingValues.cs" />
+    <Compile Include="TestObjects\ListErrorObject.cs" />
+    <Compile Include="TestObjects\ListErrorObjectCollection.cs" />
+    <Compile Include="TestObjects\ListOfIds.cs" />
+    <Compile Include="TestObjects\ListTestClass.cs" />
+    <Compile Include="TestObjects\LogEntry.cs" />
+    <Compile Include="TestObjects\MemberConverterPrecedenceClassConverter.cs" />
+    <Compile Include="TestObjects\MethodExecutorObject.cs" />
+    <Compile Include="TestObjects\Movie.cs" />
+    <Compile Include="TestObjects\MyClass.cs" />
+    <Compile Include="TestObjects\Name.cs" />
+    <Compile Include="TestObjects\NonRequest.cs" />
+    <Compile Include="TestObjects\NullableDateTimeTestClass.cs" />
+    <Compile Include="TestObjects\ObjectArrayPropertyTest.cs" />
+    <Compile Include="TestObjects\PersonError.cs" />
+    <Compile Include="TestObjects\PersonPropertyClass.cs" />
+    <Compile Include="TestObjects\PersonRaw.cs" />
+    <Compile Include="TestObjects\PhoneNumber.cs" />
+    <Compile Include="TestObjects\PrivateConstructorTestClass.cs" />
+    <Compile Include="TestObjects\PrivateConstructorWithPublicParametizedConstructorTestClass.cs" />
+    <Compile Include="TestObjects\PrivateMembersClass.cs" />
+    <Compile Include="TestObjects\PropertyCase.cs" />
+    <Compile Include="TestObjects\RequestOnly.cs" />
+    <Compile Include="TestObjects\RequiredMembersClass.cs" />
+    <Compile Include="TestObjects\RoleTransfer.cs" />
+    <Compile Include="TestObjects\SearchResult.cs" />
+    <Compile Include="TestObjects\SerializationEventTestDictionary.cs" />
+    <Compile Include="TestObjects\SerializationEventTestList.cs" />
+    <Compile Include="TestObjects\SerializationEventTestObject.cs" />
+    <Compile Include="TestObjects\SerializationEventTestObjectWithConstructor.cs" />
+    <Compile Include="TestObjects\SetOnlyPropertyClass.cs" />
+    <Compile Include="TestObjects\Article.cs" />
+    <Compile Include="TestObjects\ArticleCollection.cs" />
+    <Compile Include="TestObjects\ClassWithArray.cs" />
+    <Compile Include="TestObjects\ClassWithGuid.cs" />
+    <Compile Include="TestObjects\ConverableMembers.cs" />
+    <Compile Include="TestObjects\JsonIgnoreAttributeOnClassTestClass.cs" />
+    <Compile Include="Linq\JConstructorTests.cs" />
+    <Compile Include="Linq\JPropertyTests.cs" />
+    <Compile Include="TestObjects\MemberConverterClass.cs" />
+    <Compile Include="TestObjects\Product.cs" />
+    <Compile Include="TestObjects\ProductCollection.cs" />
+    <Compile Include="TestObjects\ProductShort.cs" />
+    <Compile Include="TestObjects\SetOnlyPropertyClass2.cs" />
+    <Compile Include="TestObjects\Shortie.cs" />
+    <Compile Include="TestObjects\Store.cs" />
+    <Compile Include="TestObjects\StoreColor.cs" />
+    <Compile Include="TestObjects\Person.cs" />
+    <Compile Include="Schema\JsonSchemaBuilderTests.cs" />
+    <Compile Include="Schema\JsonSchemaGeneratorTests.cs" />
+    <Compile Include="Schema\JsonSchemaTests.cs" />
+    <Compile Include="TestObjects\DateTimeTestClass.cs" />
+    <Compile Include="Converters\IsoDateTimeConverterTests.cs" />
+    <Compile Include="JsonConvertTest.cs" />
+    <Compile Include="Converters\JavaScriptDateTimeConverterTests.cs" />
+    <Compile Include="JsonTextReaderTest.cs" />
+    <Compile Include="JsonTextWriterTest.cs" />
+    <Compile Include="Linq\JArrayTests.cs" />
+    <Compile Include="Linq\JObjectTests.cs" />
+    <Compile Include="Linq\JTokenEqualityComparerTests.cs" />
+    <Compile Include="Linq\JTokenTests.cs" />
+    <Compile Include="Linq\JValueTests.cs" />
+    <Compile Include="Linq\LinqToJsonTest.cs" />
+    <Compile Include="PerformanceTests.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="SilverlightTests.cs" />
+    <Compile Include="TestFixtureBase.cs" />
+    <Compile Include="Converters\XmlNodeConverterTest.cs" />
+    <Compile Include="TestObjects\StructTest.cs" />
+    <Compile Include="TestObjects\SubKlass.cs" />
+    <Compile Include="TestObjects\SuperKlass.cs" />
+    <Compile Include="TestObjects\TypeClass.cs" />
+    <Compile Include="TestObjects\TypedSubHashtable.cs" />
+    <Compile Include="TestObjects\UserNullable.cs" />
+    <Compile Include="TestObjects\VersionKeyedCollection.cs" />
+    <Compile Include="TestObjects\WagePerson.cs" />
+    <Compile Include="Utilities\DynamicReflectionDelegateFactoryTests.cs" />
+    <Compile Include="Utilities\ReflectionUtilsTests.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\Newtonsoft.Json\Newtonsoft.Json.Silverlight.csproj">
+      <Project>{DC3C6F3D-2CA1-4278-9B79-63770FB3EA2D}</Project>
+      <Name>Newtonsoft.Json.Silverlight</Name>
+      <Private>True</Private>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 3.1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+  <ProjectExtensions>
+    <VisualStudio>
+      <FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}">
+        <SilverlightProjectProperties />
+      </FlavorProperties>
+    </VisualStudio>
+  </ProjectExtensions>
+</Project>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.WindowsPhone.csproj b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.WindowsPhone.csproj
new file mode 100644 (file)
index 0000000..a5cfd2c
--- /dev/null
@@ -0,0 +1,230 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>10.0.20506</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{5ED71C8C-D0A6-487C-9A8C-BB855ECEAF75}</ProjectGuid>
+    <ProjectTypeGuids>{C089C8C0-30E0-4E22-80C0-CE093F111A43};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Newtonsoft.Json.Tests.WindowsPhone</RootNamespace>
+    <AssemblyName>Newtonsoft.Json.Tests.WindowsPhone</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>
+    <TargetFrameworkProfile>WindowsPhone</TargetFrameworkProfile>
+    <TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier>
+    <SilverlightApplication>false</SilverlightApplication>
+    <ValidateXaml>true</ValidateXaml>
+    <ThrowErrorsInValidation>true</ThrowErrorsInValidation>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>Bin\Debug\WindowsPhone\</OutputPath>
+    <DefineConstants>DEBUG;TRACE;SILVERLIGHT;WINDOWS_PHONE</DefineConstants>
+    <NoStdLib>true</NoStdLib>
+    <NoConfig>true</NoConfig>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>Bin\Release\WindowsPhone\</OutputPath>
+    <DefineConstants>TRACE;SILVERLIGHT;WINDOWS_PHONE</DefineConstants>
+    <NoStdLib>true</NoStdLib>
+    <NoConfig>true</NoConfig>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="nunit.framework">
+      <HintPath>..\Lib\NUnit\Silverlight\nunit.framework.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Runtime.Serialization">
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.Windows">
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="system">
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.Core">
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.Xml">
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.Net">
+      <Private>True</Private>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Bson\BsonReaderTests.cs" />
+    <Compile Include="Bson\BsonWriterTests.cs" />
+    <Compile Include="Converters\BinaryConverterTests.cs" />
+    <Compile Include="Converters\CustomCreationConverterTests.cs" />
+    <Compile Include="Converters\DataSetConverterTests.cs" />
+    <Compile Include="Converters\DataTableConverterTests.cs" />
+    <Compile Include="Converters\ExpandoObjectConverterTests.cs" />
+    <Compile Include="Converters\ObjectIdConverterTests.cs" />
+    <Compile Include="Converters\RegexConverterTests.cs" />
+    <Compile Include="Converters\StringEnumConverterTests.cs" />
+    <Compile Include="ExceptionTests.cs" />
+    <Compile Include="JsonArrayAttributeTests.cs" />
+    <Compile Include="Linq\ComponentModel\BindingTests.cs" />
+    <Compile Include="Linq\ComponentModel\JPropertyDescriptorTests.cs" />
+    <Compile Include="Linq\JPathTests.cs" />
+    <Compile Include="Linq\JRawTests.cs" />
+    <Compile Include="Linq\JTokenReaderTest.cs" />
+    <Compile Include="Linq\JTokenWriterTest.cs" />
+    <Compile Include="JsonValidatingReaderTests.cs" />
+    <Compile Include="Schema\ExtensionsTests.cs" />
+    <Compile Include="Schema\JsonSchemaModelBuilderTests.cs" />
+    <Compile Include="Schema\JsonSchemaNodeTests.cs" />
+    <Compile Include="Serialization\CamelCasePropertyNamesContractResolverTests.cs" />
+    <Compile Include="Serialization\ConstructorHandlingTests.cs" />
+    <Compile Include="Serialization\EntitiesSerializationTests.cs" />
+    <Compile Include="Serialization\JsonSerializerTest.cs" />
+    <Compile Include="Serialization\MissingMemberHandlingTests.cs" />
+    <Compile Include="Serialization\PopulateTests.cs" />
+    <Compile Include="Serialization\PreserveReferencesHandlingTests.cs" />
+    <Compile Include="Serialization\SerializationErrorHandlingTests.cs" />
+    <Compile Include="Serialization\SerializationEventAttributeTests.cs" />
+    <Compile Include="Serialization\TypeNameHandlingTests.cs" />
+    <Compile Include="TestObjects\AbstractGenericBase.cs" />
+    <Compile Include="TestObjects\ArgumentConverterPrecedenceClassConverter.cs" />
+    <Compile Include="TestObjects\BadJsonPropertyClass.cs" />
+    <Compile Include="TestObjects\Bar.cs" />
+    <Compile Include="TestObjects\Car.cs" />
+    <Compile Include="TestObjects\CircularReferenceClass.cs" />
+    <Compile Include="TestObjects\ClassAndMemberConverterClass.cs" />
+    <Compile Include="TestObjects\ClassConverterPrecedenceClassConverter.cs" />
+    <Compile Include="TestObjects\Computer.cs" />
+    <Compile Include="TestObjects\ConstructorCaseSensitivityClass.cs" />
+    <Compile Include="TestObjects\ConstructorReadonlyFields.cs" />
+    <Compile Include="TestObjects\Container.cs" />
+    <Compile Include="TestObjects\Content.cs" />
+    <Compile Include="TestObjects\ContentBaseClass.cs" />
+    <Compile Include="TestObjects\ContentSubClass.cs" />
+    <Compile Include="TestObjects\ConverterPrecedenceClass.cs" />
+    <Compile Include="TestObjects\ConverterPrecedenceClassConverter.cs" />
+    <Compile Include="TestObjects\CircularReferenceWithIdClass.cs" />
+    <Compile Include="TestObjects\DateTimeErrorObjectCollection.cs" />
+    <Compile Include="TestObjects\DefaultValueAttributeTestClass.cs" />
+    <Compile Include="TestObjects\DictionaryInterfaceClass.cs" />
+    <Compile Include="TestObjects\DoubleClass.cs" />
+    <Compile Include="TestObjects\EmployeeReference.cs" />
+    <Compile Include="TestObjects\Event.cs" />
+    <Compile Include="TestObjects\Foo.cs" />
+    <Compile Include="TestObjects\GenericImpl.cs" />
+    <Compile Include="TestObjects\GenericListAndDictionaryInterfaceProperties.cs" />
+    <Compile Include="TestObjects\GetOnlyPropertyClass.cs" />
+    <Compile Include="TestObjects\GoogleMapGeocoderStructure.cs" />
+    <Compile Include="TestObjects\HolderClass.cs" />
+    <Compile Include="TestObjects\IncompatibleJsonAttributeClass.cs" />
+    <Compile Include="TestObjects\InterfacePropertyTestClass.cs" />
+    <Compile Include="TestObjects\Invoice.cs" />
+    <Compile Include="TestObjects\JaggedArray.cs" />
+    <Compile Include="TestObjects\JsonIgnoreAttributeTestClass.cs" />
+    <Compile Include="TestObjects\JsonPropertyClass.cs" />
+    <Compile Include="TestObjects\JsonPropertyWithHandlingValues.cs" />
+    <Compile Include="TestObjects\ListErrorObject.cs" />
+    <Compile Include="TestObjects\ListErrorObjectCollection.cs" />
+    <Compile Include="TestObjects\ListOfIds.cs" />
+    <Compile Include="TestObjects\ListTestClass.cs" />
+    <Compile Include="TestObjects\LogEntry.cs" />
+    <Compile Include="TestObjects\MemberConverterPrecedenceClassConverter.cs" />
+    <Compile Include="TestObjects\MethodExecutorObject.cs" />
+    <Compile Include="TestObjects\Movie.cs" />
+    <Compile Include="TestObjects\MyClass.cs" />
+    <Compile Include="TestObjects\Name.cs" />
+    <Compile Include="TestObjects\NonRequest.cs" />
+    <Compile Include="TestObjects\NullableDateTimeTestClass.cs" />
+    <Compile Include="TestObjects\ObjectArrayPropertyTest.cs" />
+    <Compile Include="TestObjects\PersonError.cs" />
+    <Compile Include="TestObjects\PersonPropertyClass.cs" />
+    <Compile Include="TestObjects\PersonRaw.cs" />
+    <Compile Include="TestObjects\PhoneNumber.cs" />
+    <Compile Include="TestObjects\PrivateConstructorTestClass.cs" />
+    <Compile Include="TestObjects\PrivateConstructorWithPublicParametizedConstructorTestClass.cs" />
+    <Compile Include="TestObjects\PrivateMembersClass.cs" />
+    <Compile Include="TestObjects\PropertyCase.cs" />
+    <Compile Include="TestObjects\RequestOnly.cs" />
+    <Compile Include="TestObjects\RequiredMembersClass.cs" />
+    <Compile Include="TestObjects\RoleTransfer.cs" />
+    <Compile Include="TestObjects\SearchResult.cs" />
+    <Compile Include="TestObjects\SerializationEventTestDictionary.cs" />
+    <Compile Include="TestObjects\SerializationEventTestList.cs" />
+    <Compile Include="TestObjects\SerializationEventTestObject.cs" />
+    <Compile Include="TestObjects\SerializationEventTestObjectWithConstructor.cs" />
+    <Compile Include="TestObjects\SetOnlyPropertyClass.cs" />
+    <Compile Include="TestObjects\Article.cs" />
+    <Compile Include="TestObjects\ArticleCollection.cs" />
+    <Compile Include="TestObjects\ClassWithArray.cs" />
+    <Compile Include="TestObjects\ClassWithGuid.cs" />
+    <Compile Include="TestObjects\ConverableMembers.cs" />
+    <Compile Include="TestObjects\JsonIgnoreAttributeOnClassTestClass.cs" />
+    <Compile Include="Linq\JConstructorTests.cs" />
+    <Compile Include="Linq\JPropertyTests.cs" />
+    <Compile Include="TestObjects\MemberConverterClass.cs" />
+    <Compile Include="TestObjects\Product.cs" />
+    <Compile Include="TestObjects\ProductCollection.cs" />
+    <Compile Include="TestObjects\ProductShort.cs" />
+    <Compile Include="TestObjects\SetOnlyPropertyClass2.cs" />
+    <Compile Include="TestObjects\Shortie.cs" />
+    <Compile Include="TestObjects\Store.cs" />
+    <Compile Include="TestObjects\StoreColor.cs" />
+    <Compile Include="TestObjects\Person.cs" />
+    <Compile Include="Schema\JsonSchemaBuilderTests.cs" />
+    <Compile Include="Schema\JsonSchemaGeneratorTests.cs" />
+    <Compile Include="Schema\JsonSchemaTests.cs" />
+    <Compile Include="TestObjects\DateTimeTestClass.cs" />
+    <Compile Include="Converters\IsoDateTimeConverterTests.cs" />
+    <Compile Include="JsonConvertTest.cs" />
+    <Compile Include="Converters\JavaScriptDateTimeConverterTests.cs" />
+    <Compile Include="JsonTextReaderTest.cs" />
+    <Compile Include="JsonTextWriterTest.cs" />
+    <Compile Include="Linq\JArrayTests.cs" />
+    <Compile Include="Linq\JObjectTests.cs" />
+    <Compile Include="Linq\JTokenEqualityComparerTests.cs" />
+    <Compile Include="Linq\JTokenTests.cs" />
+    <Compile Include="Linq\JValueTests.cs" />
+    <Compile Include="Linq\LinqToJsonTest.cs" />
+    <Compile Include="PerformanceTests.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="SilverlightTests.cs" />
+    <Compile Include="TestFixtureBase.cs" />
+    <Compile Include="Converters\XmlNodeConverterTest.cs" />
+    <Compile Include="TestObjects\StructTest.cs" />
+    <Compile Include="TestObjects\SubKlass.cs" />
+    <Compile Include="TestObjects\SuperKlass.cs" />
+    <Compile Include="TestObjects\TypeClass.cs" />
+    <Compile Include="TestObjects\TypedSubHashtable.cs" />
+    <Compile Include="TestObjects\UserNullable.cs" />
+    <Compile Include="TestObjects\VersionKeyedCollection.cs" />
+    <Compile Include="TestObjects\WagePerson.cs" />
+    <Compile Include="Utilities\DynamicReflectionDelegateFactoryTests.cs" />
+    <Compile Include="Utilities\ReflectionUtilsTests.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\Newtonsoft.Json\Newtonsoft.Json.WindowsPhone.csproj">
+      <Project>{7A7F70AB-5C07-47ED-BDD2-ECC14DBACA5E}</Project>
+      <Name>Newtonsoft.Json.WindowsPhone</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.$(TargetFrameworkProfile).Overrides.targets" />
+  <Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.CSharp.targets" />
+  <ProjectExtensions />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj
new file mode 100644 (file)
index 0000000..0f19d56
--- /dev/null
@@ -0,0 +1,331 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{3E6E2335-B079-4B5B-A65A-9D586914BCBB}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Newtonsoft.Json.Tests</RootNamespace>
+    <AssemblyName>Newtonsoft.Json.Tests</AssemblyName>
+    <SccProjectName>
+    </SccProjectName>
+    <SccLocalPath>
+    </SccLocalPath>
+    <SccAuxPath>
+    </SccAuxPath>
+    <SccProvider>
+    </SccProvider>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <SignAssembly>false</SignAssembly>
+    <AssemblyOriginatorKeyFile>
+    </AssemblyOriginatorKeyFile>
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\Net\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\Net\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="nunit.framework, Version=2.4.3.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\Lib\NUnit\DotNet\nunit.framework.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.ComponentModel.DataAnnotations">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Data.Entity">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data.Linq">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Runtime.Serialization">
+      <RequiredTargetFramework>3.0</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Security" />
+    <Reference Include="System.ServiceModel">
+      <RequiredTargetFramework>3.0</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.ServiceModel.Web">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Web" />
+    <Reference Include="System.Web.Extensions">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Xml" />
+    <Reference Include="System.Xml.Linq">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Bson\BsonWriterTests.cs" />
+    <Compile Include="Bson\BsonReaderTests.cs" />
+    <Compile Include="Converters\BinaryConverterTests.cs" />
+    <Compile Include="Converters\ExpandoObjectConverterTests.cs" />
+    <Compile Include="Converters\RegexConverterTests.cs" />
+    <Compile Include="Converters\DataTableConverterTests.cs" />
+    <Compile Include="Converters\DataSetConverterTests.cs" />
+    <Compile Include="Converters\CustomCreationConverterTests.cs" />
+    <Compile Include="Converters\ObjectIdConverterTests.cs" />
+    <Compile Include="Converters\StringEnumConverterTests.cs" />
+    <Compile Include="FileSystemEntityModel.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>FileSystemEntityModel.edmx</DependentUpon>
+    </Compile>
+    <Compile Include="JsonArrayAttributeTests.cs" />
+    <Compile Include="ExceptionTests.cs" />
+    <Compile Include="JsonValidatingReaderTests.cs" />
+    <Compile Include="LinqToSql\Department.cs" />
+    <Compile Include="LinqToSql\DepartmentConverter.cs" />
+    <Compile Include="LinqToSql\GuidByteArrayConverter.cs" />
+    <Compile Include="LinqToSql\Role.cs" />
+    <Compile Include="LinqToSql\LinqToSqlClasses.designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>LinqToSqlClasses.dbml</DependentUpon>
+    </Compile>
+    <Compile Include="LinqToSql\LinqToSqlClassesSerializationTests.cs" />
+    <Compile Include="LinqToSql\Person.cs" />
+    <Compile Include="Linq\ComponentModel\BindingTests.cs" />
+    <Compile Include="Linq\ComponentModel\JPropertyDescriptorTests.cs" />
+    <Compile Include="Linq\DynamicTests.cs" />
+    <Compile Include="Linq\JPathTests.cs" />
+    <Compile Include="Linq\JRawTests.cs" />
+    <Compile Include="Serialization\ConstructorHandlingTests.cs" />
+    <Compile Include="Serialization\ContractResolverTests.cs" />
+    <Compile Include="Serialization\DefaultValueHandlingTests.cs" />
+    <Compile Include="Serialization\DynamicTests.cs" />
+    <Compile Include="Serialization\NullValueHandlingTests.cs" />
+    <Compile Include="TestObjects\Bar.cs" />
+    <Compile Include="TestObjects\Car.cs" />
+    <Compile Include="TestObjects\Computer.cs" />
+    <Compile Include="TestObjects\ConstructorReadonlyFields.cs" />
+    <Compile Include="TestObjects\Container.cs" />
+    <Compile Include="TestObjects\ContentBaseClass.cs" />
+    <Compile Include="TestObjects\ContentSubClass.cs" />
+    <Compile Include="TestObjects\Foo.cs" />
+    <Compile Include="TestObjects\HolderClass.cs" />
+    <Compile Include="TestObjects\ListOfIds.cs" />
+    <Compile Include="TestObjects\Movie.cs" />
+    <Compile Include="TestObjects\PersonError.cs" />
+    <Compile Include="TestObjects\PersonPropertyClass.cs" />
+    <Compile Include="TestObjects\PrivateConstructorTestClass.cs" />
+    <Compile Include="TestObjects\PrivateConstructorWithPublicParametizedConstructorTestClass.cs" />
+    <Compile Include="TestObjects\Content.cs" />
+    <Compile Include="TestObjects\DateTimeErrorObjectCollection.cs" />
+    <Compile Include="Serialization\EntitiesSerializationTests.cs" />
+    <Compile Include="TestObjects\DictionaryInterfaceClass.cs" />
+    <Compile Include="TestObjects\Event.cs" />
+    <Compile Include="TestObjects\GoogleMapGeocoderStructure.cs" />
+    <Compile Include="TestObjects\InterfacePropertyTestClass.cs" />
+    <Compile Include="TestObjects\JsonPropertyClass.cs" />
+    <Compile Include="TestObjects\ListErrorObject.cs" />
+    <Compile Include="TestObjects\ListErrorObjectCollection.cs" />
+    <Compile Include="Serialization\MissingMemberHandlingTests.cs" />
+    <Compile Include="Serialization\PopulateTests.cs" />
+    <Compile Include="Serialization\SerializationErrorHandlingTests.cs" />
+    <Compile Include="Serialization\SerializationEventAttributeTests.cs" />
+    <Compile Include="Schema\ExtensionsTests.cs" />
+    <Compile Include="Schema\JsonSchemaModelBuilderTests.cs" />
+    <Compile Include="Schema\JsonSchemaNodeTests.cs" />
+    <Compile Include="Serialization\CamelCasePropertyNamesContractResolverTests.cs" />
+    <Compile Include="Serialization\PreserveReferencesHandlingTests.cs" />
+    <Compile Include="Serialization\TypeNameHandlingTests.cs" />
+    <Compile Include="TestObjects\ListTestClass.cs" />
+    <Compile Include="TestObjects\LogEntry.cs" />
+    <Compile Include="TestObjects\NonRequest.cs" />
+    <Compile Include="TestObjects\ObjectArrayPropertyTest.cs" />
+    <Compile Include="TestObjects\SearchResult.cs" />
+    <Compile Include="TestObjects\StructTest.cs" />
+    <Compile Include="TestObjects\WagePerson.cs" />
+    <Compile Include="TestObjects\PropertyCase.cs" />
+    <Compile Include="TestObjects\RequestOnly.cs" />
+    <Compile Include="TestObjects\RoleTransfer.cs" />
+    <Compile Include="TestObjects\SetOnlyPropertyClass2.cs" />
+    <Compile Include="TestObjects\SubKlass.cs" />
+    <Compile Include="TestObjects\SuperKlass.cs" />
+    <Compile Include="TestObjects\VersionKeyedCollection.cs" />
+    <Compile Include="TestObjects\AbstractGenericBase.cs" />
+    <Compile Include="TestObjects\ArgumentConverterPrecedenceClassConverter.cs" />
+    <Compile Include="TestObjects\BadJsonPropertyClass.cs" />
+    <Compile Include="TestObjects\CircularReferenceClass.cs" />
+    <Compile Include="TestObjects\ClassAndMemberConverterClass.cs" />
+    <Compile Include="TestObjects\ClassConverterPrecedenceClassConverter.cs" />
+    <Compile Include="TestObjects\ConstructorCaseSensitivityClass.cs" />
+    <Compile Include="TestObjects\ConverterPrecedenceClass.cs" />
+    <Compile Include="TestObjects\ConverterPrecedenceClassConverter.cs" />
+    <Compile Include="TestObjects\CircularReferenceWithIdClass.cs" />
+    <Compile Include="TestObjects\EmployeeReference.cs" />
+    <Compile Include="TestObjects\JsonPropertyWithHandlingValues.cs" />
+    <Compile Include="TestObjects\DefaultValueAttributeTestClass.cs" />
+    <Compile Include="TestObjects\DoubleClass.cs" />
+    <Compile Include="TestObjects\GenericImpl.cs" />
+    <Compile Include="TestObjects\GenericListAndDictionaryInterfaceProperties.cs" />
+    <Compile Include="TestObjects\GetOnlyPropertyClass.cs" />
+    <Compile Include="TestObjects\IncompatibleJsonAttributeClass.cs" />
+    <Compile Include="TestObjects\Invoice.cs" />
+    <Compile Include="TestObjects\JsonIgnoreAttributeTestClass.cs" />
+    <Compile Include="TestObjects\MemberConverterPrecedenceClassConverter.cs" />
+    <Compile Include="TestObjects\MethodExecutorObject.cs" />
+    <Compile Include="TestObjects\JaggedArray.cs" />
+    <Compile Include="TestObjects\MyClass.cs" />
+    <Compile Include="TestObjects\Name.cs" />
+    <Compile Include="TestObjects\PersonRaw.cs" />
+    <Compile Include="TestObjects\PhoneNumber.cs" />
+    <Compile Include="TestObjects\PrivateMembersClass.cs" />
+    <Compile Include="TestObjects\RequiredMembersClass.cs" />
+    <Compile Include="TestObjects\SerializationEventTestDictionary.cs" />
+    <Compile Include="TestObjects\SerializationEventTestList.cs" />
+    <Compile Include="TestObjects\SerializationEventTestObject.cs" />
+    <Compile Include="TestObjects\SerializationEventTestObjectWithConstructor.cs" />
+    <Compile Include="TestObjects\SetOnlyPropertyClass.cs" />
+    <Compile Include="TestObjects\Article.cs" />
+    <Compile Include="TestObjects\ArticleCollection.cs" />
+    <Compile Include="TestObjects\ClassWithArray.cs" />
+    <Compile Include="TestObjects\ClassWithGuid.cs" />
+    <Compile Include="TestObjects\ConverableMembers.cs" />
+    <Compile Include="TestObjects\JsonIgnoreAttributeOnClassTestClass.cs" />
+    <Compile Include="Linq\JConstructorTests.cs" />
+    <Compile Include="Linq\JPropertyTests.cs" />
+    <Compile Include="TestObjects\MemberConverterClass.cs" />
+    <Compile Include="TestObjects\Product.cs" />
+    <Compile Include="TestObjects\ProductCollection.cs" />
+    <Compile Include="TestObjects\ProductShort.cs" />
+    <Compile Include="TestObjects\Shortie.cs" />
+    <Compile Include="TestObjects\Store.cs" />
+    <Compile Include="TestObjects\StoreColor.cs" />
+    <Compile Include="TestObjects\Person.cs" />
+    <Compile Include="Schema\JsonSchemaBuilderTests.cs" />
+    <Compile Include="Schema\JsonSchemaGeneratorTests.cs" />
+    <Compile Include="Schema\JsonSchemaTests.cs" />
+    <Compile Include="TestObjects\NullableDateTimeTestClass.cs" />
+    <Compile Include="TestObjects\DateTimeTestClass.cs" />
+    <Compile Include="Converters\IsoDateTimeConverterTests.cs" />
+    <Compile Include="JsonConvertTest.cs" />
+    <Compile Include="Converters\JavaScriptDateTimeConverterTests.cs" />
+    <Compile Include="Serialization\JsonSerializerTest.cs" />
+    <Compile Include="JsonTextReaderTest.cs" />
+    <Compile Include="JsonTextWriterTest.cs" />
+    <Compile Include="Linq\JTokenReaderTest.cs" />
+    <Compile Include="Linq\JTokenWriterTest.cs" />
+    <Compile Include="Linq\JArrayTests.cs" />
+    <Compile Include="Linq\JObjectTests.cs" />
+    <Compile Include="Linq\JTokenEqualityComparerTests.cs" />
+    <Compile Include="Linq\JTokenTests.cs" />
+    <Compile Include="Linq\JValueTests.cs" />
+    <Compile Include="Linq\LinqToJsonTest.cs" />
+    <Compile Include="PerformanceTests.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="SilverlightTests.cs" />
+    <Compile Include="TestFixtureBase.cs" />
+    <Compile Include="Converters\XmlNodeConverterTest.cs" />
+    <Compile Include="TestObjects\TypeClass.cs" />
+    <Compile Include="TestObjects\TypedSubHashtable.cs" />
+    <Compile Include="TestObjects\UserNullable.cs" />
+    <Compile Include="Utilities\DynamicReflectionDelegateFactoryTests.cs" />
+    <Compile Include="Utilities\ReflectionUtilsTests.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\Newtonsoft.Json\Newtonsoft.Json.csproj">
+      <Project>{A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}</Project>
+      <Name>Newtonsoft.Json</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="LinqToSql\LinqToSqlClasses.dbml">
+      <Generator>MSLinqToSQLGenerator</Generator>
+      <LastGenOutput>LinqToSqlClasses.designer.cs</LastGenOutput>
+      <SubType>Designer</SubType>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <Service Include="{3259AA49-8AA1-44D3-9025-A0B520596A8C}" />
+  </ItemGroup>
+  <ItemGroup>
+    <EntityDeploy Include="FileSystemEntityModel.edmx">
+      <Generator>EntityModelCodeGenerator</Generator>
+      <LastGenOutput>FileSystemEntityModel.Designer.cs</LastGenOutput>
+    </EntityDeploy>
+    <None Include="LinqToSql\LinqToSqlClasses.dbml.layout">
+      <DependentUpon>LinqToSqlClasses.dbml</DependentUpon>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="bunny_pancake.jpg">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 3.1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/PerformanceTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/PerformanceTests.cs
new file mode 100644 (file)
index 0000000..06e85ce
--- /dev/null
@@ -0,0 +1,636 @@
+#if !SILVERLIGHT && !PocketPC && !NET20 && !NET35
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Diagnostics;
+using System.IO;
+using System.Runtime.Serialization;
+using System.Web.Script.Serialization;
+using System.Xml.Serialization;
+using Newtonsoft.Json.Utilities;
+using NUnit.Framework;
+using System.Runtime.Serialization.Json;
+using System.Text;
+using Newtonsoft.Json.Bson;
+using System.Runtime.Serialization.Formatters.Binary;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Converters;
+
+namespace Newtonsoft.Json.Tests
+{
+  [Serializable]
+  [DataContract]
+  public class Image
+  {
+    [DataMember]
+    public string FileName { get; set; }
+    [DataMember]
+    public string Author { get; set; }
+    [DataMember]
+    public string Caption { get; set; }
+    [DataMember]
+    public byte[] Data { get; set; }
+  }
+
+  public class PerformanceTests : TestFixtureBase
+  {
+    private const int Iterations = 100;
+    //private const int Iterations = 5000;
+
+    #region Data
+    private const string BsonHex =
+      @"A9-01-00-00-04-73-74-72-69-6E-67-73-00-2B-00-00-00-0A-30-00-02-31-00-19-00-00-00-4D-61-72-6B-75-73-20-65-67-67-65-72-20-5D-3E-3C-5B-2C-20-28-32-6E-64-29-00-0A-32-00-00-03-64-69-63-74-69-6F-6E-61-72-79-00-37-00-00-00-10-56-61-6C-20-26-20-61-73-64-31-00-01-00-00-00-10-56-61-6C-32-20-26-20-61-73-64-31-00-03-00-00-00-10-56-61-6C-33-20-26-20-61-73-64-31-00-04-00-00-00-00-02-4E-61-6D-65-00-05-00-00-00-52-69-63-6B-00-09-4E-6F-77-00-EF-BD-69-EC-25-01-00-00-01-42-69-67-4E-75-6D-62-65-72-00-E7-7B-CC-26-96-C7-1F-42-03-41-64-64-72-65-73-73-31-00-47-00-00-00-02-53-74-72-65-65-74-00-0B-00-00-00-66-66-66-20-53-74-72-65-65-74-00-02-50-68-6F-6E-65-00-0F-00-00-00-28-35-30-33-29-20-38-31-34-2D-36-33-33-35-00-09-45-6E-74-65-72-65-64-00-6F-FF-31-53-26-01-00-00-00-04-41-64-64-72-65-73-73-65-73-00-A2-00-00-00-03-30-00-4B-00-00-00-02-53-74-72-65-65-74-00-0F-00-00-00-1F-61-72-72-61-79-3C-61-64-64-72-65-73-73-00-02-50-68-6F-6E-65-00-0F-00-00-00-28-35-30-33-29-20-38-31-34-2D-36-33-33-35-00-09-45-6E-74-65-72-65-64-00-6F-73-0C-E7-25-01-00-00-00-03-31-00-4C-00-00-00-02-53-74-72-65-65-74-00-10-00-00-00-61-72-72-61-79-20-32-20-61-64-64-72-65-73-73-00-02-50-68-6F-6E-65-00-0F-00-00-00-28-35-30-33-29-20-38-31-34-2D-36-33-33-35-00-09-45-6E-74-65-72-65-64-00-6F-17-E6-E1-25-01-00-00-00-00-00";
+
+    private const string BinaryFormatterHex =
+      @"00-01-00-00-00-FF-FF-FF-FF-01-00-00-00-00-00-00-00-0C-02-00-00-00-4C-4E-65-77-74-6F-6E-73-6F-66-74-2E-4A-73-6F-6E-2E-54-65-73-74-73-2C-20-56-65-72-73-69-6F-6E-3D-33-2E-35-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-6E-75-6C-6C-05-01-00-00-00-1F-4E-65-77-74-6F-6E-73-6F-66-74-2E-4A-73-6F-6E-2E-54-65-73-74-73-2E-54-65-73-74-43-6C-61-73-73-07-00-00-00-05-5F-4E-61-6D-65-04-5F-4E-6F-77-0A-5F-42-69-67-4E-75-6D-62-65-72-09-5F-41-64-64-72-65-73-73-31-0A-5F-41-64-64-72-65-73-73-65-73-07-73-74-72-69-6E-67-73-0A-64-69-63-74-69-6F-6E-61-72-79-01-00-00-04-03-03-03-0D-05-1D-4E-65-77-74-6F-6E-73-6F-66-74-2E-4A-73-6F-6E-2E-54-65-73-74-73-2E-41-64-64-72-65-73-73-02-00-00-00-90-01-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-4C-69-73-74-60-31-5B-5B-4E-65-77-74-6F-6E-73-6F-66-74-2E-4A-73-6F-6E-2E-54-65-73-74-73-2E-41-64-64-72-65-73-73-2C-20-4E-65-77-74-6F-6E-73-6F-66-74-2E-4A-73-6F-6E-2E-54-65-73-74-73-2C-20-56-65-72-73-69-6F-6E-3D-33-2E-35-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-6E-75-6C-6C-5D-5D-7F-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-4C-69-73-74-60-31-5B-5B-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-5D-E1-01-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-44-69-63-74-69-6F-6E-61-72-79-60-32-5B-5B-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-2C-5B-53-79-73-74-65-6D-2E-49-6E-74-33-32-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-5D-02-00-00-00-06-03-00-00-00-04-52-69-63-6B-B6-25-3A-D1-C5-59-CC-88-0F-33-34-31-32-33-31-32-33-31-32-33-2E-31-32-31-09-04-00-00-00-09-05-00-00-00-09-06-00-00-00-09-07-00-00-00-05-04-00-00-00-1D-4E-65-77-74-6F-6E-73-6F-66-74-2E-4A-73-6F-6E-2E-54-65-73-74-73-2E-41-64-64-72-65-73-73-03-00-00-00-07-5F-73-74-72-65-65-74-06-5F-50-68-6F-6E-65-08-5F-45-6E-74-65-72-65-64-01-01-00-0D-02-00-00-00-06-08-00-00-00-0A-66-66-66-20-53-74-72-65-65-74-06-09-00-00-00-0E-28-35-30-33-29-20-38-31-34-2D-36-33-33-35-B6-BD-B8-BF-74-69-CC-88-04-05-00-00-00-90-01-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-4C-69-73-74-60-31-5B-5B-4E-65-77-74-6F-6E-73-6F-66-74-2E-4A-73-6F-6E-2E-54-65-73-74-73-2E-41-64-64-72-65-73-73-2C-20-4E-65-77-74-6F-6E-73-6F-66-74-2E-4A-73-6F-6E-2E-54-65-73-74-73-2C-20-56-65-72-73-69-6F-6E-3D-33-2E-35-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-6E-75-6C-6C-5D-5D-03-00-00-00-06-5F-69-74-65-6D-73-05-5F-73-69-7A-65-08-5F-76-65-72-73-69-6F-6E-04-00-00-1F-4E-65-77-74-6F-6E-73-6F-66-74-2E-4A-73-6F-6E-2E-54-65-73-74-73-2E-41-64-64-72-65-73-73-5B-5D-02-00-00-00-08-08-09-0A-00-00-00-02-00-00-00-02-00-00-00-04-06-00-00-00-7F-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-4C-69-73-74-60-31-5B-5B-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-5D-03-00-00-00-06-5F-69-74-65-6D-73-05-5F-73-69-7A-65-08-5F-76-65-72-73-69-6F-6E-06-00-00-08-08-09-0B-00-00-00-03-00-00-00-03-00-00-00-04-07-00-00-00-E1-01-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-44-69-63-74-69-6F-6E-61-72-79-60-32-5B-5B-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-2C-5B-53-79-73-74-65-6D-2E-49-6E-74-33-32-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-5D-04-00-00-00-07-56-65-72-73-69-6F-6E-08-43-6F-6D-70-61-72-65-72-08-48-61-73-68-53-69-7A-65-0D-4B-65-79-56-61-6C-75-65-50-61-69-72-73-00-03-00-03-08-92-01-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-47-65-6E-65-72-69-63-45-71-75-61-6C-69-74-79-43-6F-6D-70-61-72-65-72-60-31-5B-5B-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-5D-08-E5-01-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-4B-65-79-56-61-6C-75-65-50-61-69-72-60-32-5B-5B-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-2C-5B-53-79-73-74-65-6D-2E-49-6E-74-33-32-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-5D-5B-5D-03-00-00-00-09-0C-00-00-00-03-00-00-00-09-0D-00-00-00-07-0A-00-00-00-00-01-00-00-00-04-00-00-00-04-1D-4E-65-77-74-6F-6E-73-6F-66-74-2E-4A-73-6F-6E-2E-54-65-73-74-73-2E-41-64-64-72-65-73-73-02-00-00-00-09-0E-00-00-00-09-0F-00-00-00-0D-02-11-0B-00-00-00-04-00-00-00-0A-06-10-00-00-00-18-4D-61-72-6B-75-73-20-65-67-67-65-72-20-5D-3E-3C-5B-2C-20-28-32-6E-64-29-0D-02-04-0C-00-00-00-92-01-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-47-65-6E-65-72-69-63-45-71-75-61-6C-69-74-79-43-6F-6D-70-61-72-65-72-60-31-5B-5B-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-5D-00-00-00-00-07-0D-00-00-00-00-01-00-00-00-03-00-00-00-03-E3-01-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-4B-65-79-56-61-6C-75-65-50-61-69-72-60-32-5B-5B-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-2C-5B-53-79-73-74-65-6D-2E-49-6E-74-33-32-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-5D-04-EF-FF-FF-FF-E3-01-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-4B-65-79-56-61-6C-75-65-50-61-69-72-60-32-5B-5B-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-2C-5B-53-79-73-74-65-6D-2E-49-6E-74-33-32-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-5D-02-00-00-00-03-6B-65-79-05-76-61-6C-75-65-01-00-08-06-12-00-00-00-0A-56-61-6C-20-26-20-61-73-64-31-01-00-00-00-01-ED-FF-FF-FF-EF-FF-FF-FF-06-14-00-00-00-0B-56-61-6C-32-20-26-20-61-73-64-31-03-00-00-00-01-EB-FF-FF-FF-EF-FF-FF-FF-06-16-00-00-00-0B-56-61-6C-33-20-26-20-61-73-64-31-04-00-00-00-01-0E-00-00-00-04-00-00-00-06-17-00-00-00-0E-1F-61-72-72-61-79-3C-61-64-64-72-65-73-73-09-09-00-00-00-B6-FD-0B-45-F4-58-CC-88-01-0F-00-00-00-04-00-00-00-06-19-00-00-00-0F-61-72-72-61-79-20-32-20-61-64-64-72-65-73-73-09-09-00-00-00-B6-3D-A2-1A-2B-58-CC-88-0B";
+
+    private const string XmlText =
+      @"<TestClass xmlns=""http://schemas.datacontract.org/2004/07/Newtonsoft.Json.Tests"" xmlns:i=""http://www.w3.org/2001/XMLSchema-instance""><Address1><Entered>2010-01-21T11:12:16.0809174+13:00</Entered><Phone>(503) 814-6335</Phone><Street>fff Street</Street></Address1><Addresses><Address><Entered>2009-12-31T11:12:16.0809174+13:00</Entered><Phone>(503) 814-6335</Phone><Street>&#x1F;array&lt;address</Street></Address><Address><Entered>2009-12-30T11:12:16.0809174+13:00</Entered><Phone>(503) 814-6335</Phone><Street>array 2 address</Street></Address></Addresses><BigNumber>34123123123.121</BigNumber><Name>Rick</Name><Now>2010-01-01T12:12:16.0809174+13:00</Now><dictionary xmlns:a=""http://schemas.microsoft.com/2003/10/Serialization/Arrays""><a:KeyValueOfstringint><a:Key>Val &amp; asd1</a:Key><a:Value>1</a:Value></a:KeyValueOfstringint><a:KeyValueOfstringint><a:Key>Val2 &amp; asd1</a:Key><a:Value>3</a:Value></a:KeyValueOfstringint><a:KeyValueOfstringint><a:Key>Val3 &amp; asd1</a:Key><a:Value>4</a:Value></a:KeyValueOfstringint></dictionary><strings xmlns:a=""http://schemas.microsoft.com/2003/10/Serialization/Arrays""><a:string i:nil=""true""/><a:string>Markus egger ]&gt;&lt;[, (2nd)</a:string><a:string i:nil=""true""/></strings></TestClass>";
+
+    private const string JsonText =
+      @"{""strings"":[null,""Markus egger ]><[, (2nd)"",null],""dictionary"":{""Val & asd1"":1,""Val2 & asd1"":3,""Val3 & asd1"":4},""Name"":""Rick"",""Now"":""\/Date(1262301136080+1300)\/"",""BigNumber"":34123123123.121,""Address1"":{""Street"":""fff Street"",""Phone"":""(503) 814-6335"",""Entered"":""\/Date(1264025536080+1300)\/""},""Addresses"":[{""Street"":""\u001farray<address"",""Phone"":""(503) 814-6335"",""Entered"":""\/Date(1262211136080+1300)\/""},{""Street"":""array 2 address"",""Phone"":""(503) 814-6335"",""Entered"":""\/Date(1262124736080+1300)\/""}]}";
+
+    public enum SerializeMethod
+    {
+      JsonNet,
+      JsonNetBinary,
+      BinaryFormatter,
+      JavaScriptSerializer,
+      DataContractSerializer,
+      DataContractJsonSerializer
+    }
+    #endregion
+
+    [Test]
+    public void Serialize()
+    {
+      TestClass test = CreateSerializationObject();
+
+      BenchmarkSerializeMethod(SerializeMethod.DataContractSerializer, test);
+      BenchmarkSerializeMethod(SerializeMethod.BinaryFormatter, test);
+      BenchmarkSerializeMethod(SerializeMethod.JavaScriptSerializer, test);
+      BenchmarkSerializeMethod(SerializeMethod.DataContractJsonSerializer, test);
+      BenchmarkSerializeMethod(SerializeMethod.JsonNet, test);
+      BenchmarkSerializeMethod(SerializeMethod.JsonNetBinary, test);
+    }
+
+    [Test]
+    public void Deserialize()
+    {
+      BenchmarkDeserializeMethod<TestClass>(SerializeMethod.DataContractSerializer, XmlText);
+      BenchmarkDeserializeMethod<TestClass>(SerializeMethod.BinaryFormatter, MiscellaneousUtils.HexToBytes(BinaryFormatterHex));
+      BenchmarkDeserializeMethod<TestClass>(SerializeMethod.JavaScriptSerializer, JsonText);
+      BenchmarkDeserializeMethod<TestClass>(SerializeMethod.DataContractJsonSerializer, JsonText);
+      BenchmarkDeserializeMethod<TestClass>(SerializeMethod.JsonNet, JsonText);
+      BenchmarkDeserializeMethod<TestClass>(SerializeMethod.JsonNetBinary, MiscellaneousUtils.HexToBytes(BsonHex));
+    }
+
+    [Test]
+    public void SerializeSizeNormal()
+    {
+      SerializeSize(CreateSerializationObject());
+    }
+
+    [Test]
+    public void SerializeSizeData()
+    {
+      Image image = new Image();
+      image.Data = System.IO.File.ReadAllBytes(@"bunny_pancake.jpg");
+      image.FileName = "bunny_pancake.jpg";
+      image.Author = "Hironori Akutagawa";
+      image.Caption = "I have no idea what you are talking about so here's a bunny with a pancake on its head";
+
+      SerializeSize(image);
+    }
+
+    private T TimeOperation<T>(Func<T> operation, string name)
+    {
+      // warm up
+      operation();
+
+      Stopwatch timed = new Stopwatch();
+      timed.Start();
+
+      T result = operation();
+
+      Console.WriteLine(name);
+      Console.WriteLine("{0} ms", timed.ElapsedMilliseconds);
+
+      timed.Stop();
+
+      return result;
+    }
+
+    private void SerializeSize(object value)
+    {
+      // this is extremely slow with 5000 interations
+      int interations = 100;
+
+      byte[] jsonBytes = TimeOperation(() =>
+      {
+        string json = null;
+        for (int i = 0; i < interations; i++)
+        {
+          json = JsonConvert.SerializeObject(value, Formatting.None);
+        }
+
+        return Encoding.UTF8.GetBytes(json);
+      }, "Json.NET");
+
+      byte[] bsonBytes = TimeOperation(() =>
+      {
+        MemoryStream ms = null;
+        for (int i = 0; i < interations; i++)
+        {
+          ms = new MemoryStream();
+          JsonSerializer serializer = new JsonSerializer();
+          BsonWriter writer = new BsonWriter(ms);
+
+          serializer.Serialize(writer, value);
+          writer.Flush();
+        }
+
+        return ms.ToArray();
+      }, "Json.NET BSON");
+
+      byte[] xmlBytes = TimeOperation(() =>
+      {
+        MemoryStream ms = null;
+        for (int i = 0; i < interations; i++)
+        {
+          ms = new MemoryStream();
+          DataContractSerializer dataContractSerializer = new DataContractSerializer(value.GetType());
+          dataContractSerializer.WriteObject(ms, value);
+        }
+
+        return ms.ToArray();
+      }, "DataContractSerializer");
+
+      byte[] wcfJsonBytes = TimeOperation(() =>
+      {
+        MemoryStream ms = null;
+        for (int i = 0; i < interations; i++)
+        {
+          ms = new MemoryStream();
+          DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(value.GetType());
+          dataContractJsonSerializer.WriteObject(ms, value);
+        }
+
+        return ms.ToArray();
+      }, "DataContractJsonSerializer");
+
+      byte[] binaryFormatterBytes = TimeOperation(() =>
+      {
+        MemoryStream ms = null;
+        for (int i = 0; i < interations; i++)
+        {
+          ms = new MemoryStream();
+          BinaryFormatter formatter = new BinaryFormatter();
+          formatter.Serialize(ms, value);
+        }
+
+        return ms.ToArray();
+      }, "BinaryFormatter");
+
+      Console.WriteLine("Json.NET size: {0} bytes", jsonBytes.Length);
+      Console.WriteLine("BSON size: {0} bytes", bsonBytes.Length);
+      Console.WriteLine("WCF JSON size: {0} bytes", wcfJsonBytes.Length);
+      Console.WriteLine("WCF XML size: {0} bytes", xmlBytes.Length);
+      Console.WriteLine("BinaryFormatter size: {0} bytes", binaryFormatterBytes.Length);
+    }
+
+    #region Serialize
+    private static readonly byte[] Buffer = new byte[4096];
+
+    public void BenchmarkSerializeMethod(SerializeMethod method, object value)
+    {
+      Serialize(method, value);
+
+      Stopwatch timed = new Stopwatch();
+      timed.Start();
+
+      string json = null;
+      for (int x = 0; x < Iterations; x++)
+      {
+        json = Serialize(method, value);
+      }
+
+      timed.Stop();
+
+      Console.WriteLine("Serialize method: {0}", method);
+      Console.WriteLine("{0} ms", timed.ElapsedMilliseconds);
+      Console.WriteLine(json);
+      Console.WriteLine();
+    }
+
+    private TestClass CreateSerializationObject()
+    {
+      TestClass test = new TestClass();
+
+      test.dictionary = new Dictionary<string, int> { { "Val & asd1", 1 }, { "Val2 & asd1", 3 }, { "Val3 & asd1", 4 } };
+
+
+      test.Address1.Street = "fff Street";
+      test.Address1.Entered = DateTime.Now.AddDays(20);
+
+      test.BigNumber = 34123123123.121M;
+      test.Now = DateTime.Now.AddHours(1);
+      test.strings = new List<string>() { null, "Markus egger ]><[, (2nd)", null };
+
+      Address address = new Address();
+      address.Entered = DateTime.Now.AddDays(-1);
+      address.Street = "\u001farray\u003caddress";
+
+      test.Addresses.Add(address);
+
+      address = new Address();
+      address.Entered = DateTime.Now.AddDays(-2);
+      address.Street = "array 2 address";
+      test.Addresses.Add(address);
+      return test;
+    }
+
+    public string SerializeJsonNet(object value)
+    {
+      Type type = value.GetType();
+
+      Newtonsoft.Json.JsonSerializer json = new Newtonsoft.Json.JsonSerializer();
+
+      json.NullValueHandling = NullValueHandling.Ignore;
+
+      json.ObjectCreationHandling = Newtonsoft.Json.ObjectCreationHandling.Replace;
+      json.MissingMemberHandling = Newtonsoft.Json.MissingMemberHandling.Ignore;
+      json.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
+
+
+      StringWriter sw = new StringWriter();
+      Newtonsoft.Json.JsonTextWriter writer = new JsonTextWriter(sw);
+
+      writer.Formatting = Formatting.None;
+
+      writer.QuoteChar = '"';
+      json.Serialize(writer, value);
+
+      string output = sw.ToString();
+      writer.Close();
+
+      return output;
+    }
+
+    public string SerializeWebExtensions(object value)
+    {
+      JavaScriptSerializer ser = new JavaScriptSerializer();
+
+      return ser.Serialize(value);
+    }
+
+    public string SerializeDataContractJson(object value)
+    {
+      DataContractJsonSerializer dataContractSerializer
+        = new DataContractJsonSerializer(value.GetType());
+
+      MemoryStream ms = new MemoryStream();
+      dataContractSerializer.WriteObject(ms, value);
+
+      ms.Seek(0, SeekOrigin.Begin);
+
+      using (StreamReader sr = new StreamReader(ms))
+      {
+        return sr.ReadToEnd();
+      }
+    }
+
+    public string SerializeDataContract(object value)
+    {
+      DataContractSerializer dataContractSerializer
+        = new DataContractSerializer(value.GetType());
+
+      MemoryStream ms = new MemoryStream();
+      dataContractSerializer.WriteObject(ms, value);
+
+      ms.Seek(0, SeekOrigin.Begin);
+
+      using (StreamReader sr = new StreamReader(ms))
+      {
+        return sr.ReadToEnd();
+      }
+    }
+
+    private string Serialize(SerializeMethod method, object value)
+    {
+      string json;
+
+      switch (method)
+      {
+        case SerializeMethod.JsonNet:
+          json = JsonConvert.SerializeObject(value);
+          break;
+        case SerializeMethod.JsonNetBinary:
+          {
+            MemoryStream ms = new MemoryStream(Buffer);
+            JsonSerializer serializer = new JsonSerializer();
+            BsonWriter writer = new BsonWriter(ms);
+            serializer.Serialize(writer, value);
+
+            //json = BitConverter.ToString(ms.ToArray(), 0, (int)ms.Position);
+            json = "Bytes = " + ms.Position;
+            break;
+          }
+        case SerializeMethod.JavaScriptSerializer:
+          json = SerializeWebExtensions(value);
+          break;
+        case SerializeMethod.DataContractJsonSerializer:
+          json = SerializeDataContractJson(value);
+          break;
+        case SerializeMethod.DataContractSerializer:
+          json = SerializeDataContract(value);
+          break;
+        case SerializeMethod.BinaryFormatter:
+          json = SerializeBinaryFormatter(value);
+          break;
+        default:
+          throw new ArgumentOutOfRangeException("method");
+      }
+
+      return json;
+    }
+
+    private string SerializeBinaryFormatter(object value)
+    {
+      string json;
+      MemoryStream ms = new MemoryStream(Buffer);
+      BinaryFormatter formatter = new BinaryFormatter();
+      formatter.Serialize(ms, value);
+
+      json = "Bytes = " + ms.Position;
+      //json = BitConverter.ToString(ms.ToArray(), 0, (int)ms.Position);
+      return json;
+    }
+    #endregion
+
+    #region Deserialize
+    public void BenchmarkDeserializeMethod<T>(SerializeMethod method, object json)
+    {
+      Deserialize<T>(method, json);
+
+      Stopwatch timed = new Stopwatch();
+      timed.Start();
+
+      T value = default(T);
+      for (int x = 0; x < Iterations; x++)
+      {
+        value = Deserialize<T>(method, json);
+      }
+
+      timed.Stop();
+
+      Console.WriteLine("Deserialize method: {0}", method);
+      Console.WriteLine("{0} ms", timed.ElapsedMilliseconds);
+      Console.WriteLine(value);
+      Console.WriteLine();
+    }
+
+    public T DeserializeJsonNet<T>(string json)
+    {
+      Type type = typeof(T);
+
+      JsonSerializer serializer = new JsonSerializer();
+      serializer.ObjectCreationHandling = Newtonsoft.Json.ObjectCreationHandling.Replace;
+      serializer.MissingMemberHandling = Newtonsoft.Json.MissingMemberHandling.Ignore;
+      serializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
+
+      return (T)serializer.Deserialize(new StringReader(json), type);
+
+      //JsonTextReader reader = new JsonTextReader(new StringReader(JsonText));
+      //while (reader.Read())
+      //{
+
+      //}
+      //return default(T);
+    }
+
+    public T DeserializeJsonNetBinary<T>(byte[] bson)
+    {
+      Type type = typeof(T);
+
+      JsonSerializer serializer = new JsonSerializer();
+      serializer.ObjectCreationHandling = Newtonsoft.Json.ObjectCreationHandling.Replace;
+      serializer.MissingMemberHandling = Newtonsoft.Json.MissingMemberHandling.Ignore;
+      serializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
+
+      return (T)serializer.Deserialize(new BsonReader(new MemoryStream(bson)), type);
+    }
+
+    public T DeserializeWebExtensions<T>(string json)
+    {
+      JavaScriptSerializer ser = new JavaScriptSerializer();
+
+      return ser.Deserialize<T>(json);
+    }
+
+    public T DeserializeDataContractJson<T>(string json)
+    {
+      DataContractJsonSerializer dataContractSerializer
+        = new DataContractJsonSerializer(typeof(T));
+
+      MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json));
+
+      return (T)dataContractSerializer.ReadObject(ms);
+    }
+
+    private T Deserialize<T>(SerializeMethod method, object json)
+    {
+      switch (method)
+      {
+        case SerializeMethod.JsonNet:
+          return DeserializeJsonNet<T>((string)json);
+        case SerializeMethod.JsonNetBinary:
+          return DeserializeJsonNetBinary<T>((byte[])json);
+        case SerializeMethod.BinaryFormatter:
+          return DeserializeBinaryFormatter<T>((byte[])json);
+        case SerializeMethod.JavaScriptSerializer:
+          return DeserializeWebExtensions<T>((string)json);
+        case SerializeMethod.DataContractSerializer:
+          return DeserializeDataContract<T>((string)json);
+        case SerializeMethod.DataContractJsonSerializer:
+          return DeserializeDataContractJson<T>((string)json);
+        default:
+          throw new ArgumentOutOfRangeException("method");
+      }
+    }
+
+    private T DeserializeDataContract<T>(string xml)
+    {
+      MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(xml));
+
+      DataContractSerializer serializer = new DataContractSerializer(typeof(T));
+      return (T)serializer.ReadObject(ms);
+    }
+
+    private T DeserializeBinaryFormatter<T>(byte[] bytes)
+    {
+      BinaryFormatter formatter = new BinaryFormatter();
+      return (T)formatter.Deserialize(new MemoryStream(bytes));
+    }
+    #endregion
+
+
+
+    [Test]
+    public void SerializeLargeObject()
+    {
+      LargeRecursiveTestClass rootValue = null;
+      LargeRecursiveTestClass parentValue = null;
+      for (int i = 0; i < 20; i++)
+      {
+        LargeRecursiveTestClass currentValue = new LargeRecursiveTestClass()
+        {
+          Integer = int.MaxValue,
+          Text = "The quick red fox jumped over the lazy dog."
+        };
+
+        if (rootValue == null)
+          rootValue = currentValue;
+        if (parentValue != null)
+          parentValue.Child = currentValue;
+
+        parentValue = currentValue;
+      }
+
+      BenchmarkSerializeMethod(SerializeMethod.JsonNetBinary, rootValue);
+    }
+
+    [Test]
+    public void JObjectToString()
+    {
+      JObject test = JObject.Parse(JsonText);
+      IsoDateTimeConverter isoDateTimeConverter = null;// = new IsoDateTimeConverter();
+
+      TimeOperation<object>(() =>
+        {
+          for (int i = 0; i < Iterations; i++)
+          {
+            test["dummy"] = new JValue(i);
+            Encoding.UTF8.GetBytes(test.ToString(Formatting.None));
+          }
+          return null;
+        }, "JObject.ToString");
+    }
+
+    [Test]
+    public void JObjectToString2()
+    {
+      JObject test = JObject.Parse(JsonText);
+      IsoDateTimeConverter isoDateTimeConverter = null;// = new IsoDateTimeConverter();
+          MemoryStream ms = new MemoryStream();
+
+      TimeOperation<object>(() =>
+      {
+        for (int i = 0; i < Iterations; i++)
+        {
+          test["dummy"] = new JValue(i);
+          ms.Seek(0, SeekOrigin.Begin);
+          JsonTextWriter jsonTextWriter = new JsonTextWriter(new StreamWriter(ms));
+          test.WriteTo(jsonTextWriter);
+          jsonTextWriter.Flush();
+          ms.ToArray();
+          
+          //Encoding.UTF8.GetBytes(test.ToString(Formatting.None));
+        }
+        return null;
+      }, "JObject.ToString");
+    }
+  }
+
+  public class LargeRecursiveTestClass
+  {
+    public LargeRecursiveTestClass Child { get; set; }
+    public string Text { get; set; }
+    public int Integer { get; set; }
+  }
+
+  #region Classes
+  [Serializable]
+  [DataContract]
+  public class TestClass
+  {
+    [DataMember]
+    public string Name
+    {
+      get { return _Name; }
+      set { _Name = value; }
+    }
+    private string _Name = "Rick";
+
+    [DataMember]
+    public DateTime Now
+    {
+      get { return _Now; }
+      set { _Now = value; }
+    }
+    private DateTime _Now = DateTime.Now;
+
+    [DataMember]
+    public decimal BigNumber
+    {
+      get { return _BigNumber; }
+      set { _BigNumber = value; }
+    }
+    private decimal _BigNumber = 1212121.22M;
+
+    [DataMember]
+    public Address Address1
+    {
+      get { return _Address1; }
+      set { _Address1 = value; }
+    }
+    private Address _Address1 = new Address();
+
+
+
+    [DataMember]
+    public List<Address> Addresses
+    {
+      get { return _Addresses; }
+      set { _Addresses = value; }
+    }
+    private List<Address> _Addresses = new List<Address>();
+
+    [DataMember]
+    public List<string> strings = new List<string>();
+
+    [DataMember]
+    public Dictionary<string, int> dictionary = new Dictionary<string, int>();
+  }
+
+  [Serializable]
+  [DataContract]
+  public class Address
+  {
+    [DataMember]
+    public string Street
+    {
+      get { return _street; }
+      set { _street = value; }
+    }
+    private string _street = "32 Kaiea";
+
+    [DataMember]
+    public string Phone
+    {
+      get { return _Phone; }
+      set { _Phone = value; }
+    }
+    private string _Phone = "(503) 814-6335";
+
+    [DataMember]
+    public DateTime Entered
+    {
+      get { return _Entered; }
+      set { _Entered = value; }
+    }
+    private DateTime _Entered = DateTime.Parse("01/01/2007", CultureInfo.CurrentCulture.DateTimeFormat);
+  }
+  #endregion
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs
new file mode 100644 (file)
index 0000000..312623e
--- /dev/null
@@ -0,0 +1,45 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+#if SILVERLIGHT
+[assembly: AssemblyTitle("Newtonsoft Json.NET Tests Silverlight")]
+#elif PocketPC
+[assembly: AssemblyTitle("Newtonsoft Json.NET Tests Compact")]
+#else
+[assembly: AssemblyTitle("Newtonsoft Json.NET Tests")]
+#endif
+
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Newtonsoft")]
+[assembly: AssemblyProduct("Newtonsoft Json.NET Tests")]
+[assembly: AssemblyCopyright("Copyright © Newtonsoft 2008")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("0be3d72b-d2ef-409c-985c-d3ede89a25f1")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("4.0.2.0")]
+#if !PocketPC
+[assembly: AssemblyFileVersion("4.0.2.13623")]
+#endif
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Schema/ExtensionsTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Schema/ExtensionsTests.cs
new file mode 100644 (file)
index 0000000..3e315ea
--- /dev/null
@@ -0,0 +1,280 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using Newtonsoft.Json.Schema;
+using Newtonsoft.Json.Linq;
+using System.IO;
+using Newtonsoft.Json.Tests.TestObjects;
+#if !SILVERLIGHT
+using System.Data;
+#endif
+
+namespace Newtonsoft.Json.Tests.Schema
+{
+  public class ExtensionsTests : TestFixtureBase
+  {
+    [Test]
+    public void IsValid()
+    {
+      JsonSchema schema = JsonSchema.Parse("{'type':'integer'}");
+      JToken stringToken = JToken.FromObject("pie");
+      JToken integerToken = JToken.FromObject(1);
+
+      Assert.AreEqual(false, stringToken.IsValid(schema));
+      Assert.AreEqual(true, integerToken.IsValid(schema));
+    }
+
+    [Test]
+    public void ValidateWithEventHandler()
+    {
+      JsonSchema schema = JsonSchema.Parse("{'pattern':'lol'}");
+      JToken stringToken = JToken.FromObject("pie lol");
+
+      List<string> errors = new List<string>();
+      stringToken.Validate(schema, (sender, args) => errors.Add(args.Message));
+      Assert.AreEqual(0, errors.Count);
+
+      stringToken = JToken.FromObject("pie");
+
+      stringToken.Validate(schema, (sender, args) => errors.Add(args.Message));
+      Assert.AreEqual(1, errors.Count);
+
+      Assert.AreEqual("String 'pie' does not match regex pattern 'lol'.", errors[0]);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSchemaException), ExpectedMessage = @"String 'pie' does not match regex pattern 'lol'.")]
+    public void ValidateWithOutEventHandlerFailure()
+    {
+      JsonSchema schema = JsonSchema.Parse("{'pattern':'lol'}");
+      JToken stringToken = JToken.FromObject("pie");
+      stringToken.Validate(schema);
+    }
+
+    [Test]
+    public void ValidateWithOutEventHandlerSuccess()
+    {
+      JsonSchema schema = JsonSchema.Parse("{'pattern':'lol'}");
+      JToken stringToken = JToken.FromObject("pie lol");
+      stringToken.Validate(schema);
+    }
+
+    [Test]
+    public void ValidateFailureWithOutLineInfoBecauseOfEndToken()
+    {
+      JsonSchema schema = JsonSchema.Parse("{'properties':{'lol':{'required':true}}}");
+      JObject o = JObject.Parse("{}");
+
+      List<string> errors = new List<string>();
+      o.Validate(schema, (sender, args) => errors.Add(args.Message));
+
+      Assert.AreEqual("Required properties are missing from object: lol.", errors[0]);
+      Assert.AreEqual(1, errors.Count);
+    }
+
+    [Test]
+    public void ValidateFailureWithLineInfo()
+    {
+      JsonSchema schema = JsonSchema.Parse("{'properties':{'lol':{'type':'string'}}}");
+      JObject o = JObject.Parse("{'lol':1}");
+
+      List<string> errors = new List<string>();
+      o.Validate(schema, (sender, args) => errors.Add(args.Message));
+
+      Assert.AreEqual("Invalid type. Expected String but got Integer. Line 1, position 9.", errors[0]);
+      Assert.AreEqual(1, errors.Count);
+    }
+
+    [Test]
+    public void Blog()
+    {
+      string schemaJson = @"
+{
+  ""description"": ""A person schema"",
+  ""type"": ""object"",
+  ""properties"":
+  {
+    ""name"": {""type"":""string""},
+    ""hobbies"": {
+      ""type"": ""array"",
+      ""items"": {""type"":""string""}
+    }
+  }
+}
+";
+
+      //JsonSchema schema;
+
+      //using (JsonTextReader reader = new JsonTextReader(new StringReader(schemaJson)))
+      //{
+      //  JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver());
+      //  schema = builder.Parse(reader);
+      //}
+
+      JsonSchema schema = JsonSchema.Parse(schemaJson);
+
+      JObject person = JObject.Parse(@"{
+        ""name"": ""James"",
+        ""hobbies"": ["".NET"", ""Blogging"", ""Reading"", ""Xbox"", ""LOLCATS""]
+      }");
+
+      bool valid = person.IsValid(schema);
+      // true
+    }
+
+    private void GenerateSchemaAndSerializeFromType<T>(T value)
+    {
+      JsonSchemaGenerator generator = new JsonSchemaGenerator();
+      generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseAssemblyQualifiedName;
+      JsonSchema typeSchema = generator.Generate(typeof (T));
+      string schema = typeSchema.ToString();
+
+      string json = JsonConvert.SerializeObject(value, Formatting.Indented);
+      JToken token = JToken.ReadFrom(new JsonTextReader(new StringReader(json)));
+
+      List<string> errors = new List<string>();
+
+      token.Validate(typeSchema, (sender, args) =>
+                                   {
+                                     errors.Add(args.Message);
+                                   });
+
+      if (errors.Count > 0)
+        Assert.Fail("Schema generated for type '{0}' is not valid." + Environment.NewLine + string.Join(Environment.NewLine, errors.ToArray()), typeof(T));
+    }
+
+    [Test]
+    public void GenerateSchemaAndSerializeFromTypeTests()
+    {
+      GenerateSchemaAndSerializeFromType(new List<string> { "1", "Two", "III" });
+      GenerateSchemaAndSerializeFromType(new List<int> { 1 });
+      GenerateSchemaAndSerializeFromType(new Version("1.2.3.4"));
+      GenerateSchemaAndSerializeFromType(new Store());
+      GenerateSchemaAndSerializeFromType(new Person());
+      GenerateSchemaAndSerializeFromType(new PersonRaw());
+      GenerateSchemaAndSerializeFromType(new CircularReferenceClass() { Name = "I'm required" });
+      GenerateSchemaAndSerializeFromType(new CircularReferenceWithIdClass());
+      GenerateSchemaAndSerializeFromType(new ClassWithArray());
+      GenerateSchemaAndSerializeFromType(new ClassWithGuid());
+#if !NET20 && !PocketPC
+      GenerateSchemaAndSerializeFromType(new NullableDateTimeTestClass());
+#endif
+#if !SILVERLIGHT
+      GenerateSchemaAndSerializeFromType(new DataSet());
+#endif
+      GenerateSchemaAndSerializeFromType(new object());
+      GenerateSchemaAndSerializeFromType(1);
+      GenerateSchemaAndSerializeFromType("Hi");
+      GenerateSchemaAndSerializeFromType(new DateTime(2000, 12, 29, 23, 59, 0, DateTimeKind.Utc));
+      GenerateSchemaAndSerializeFromType(TimeSpan.FromTicks(1000000));
+      GenerateSchemaAndSerializeFromType(DBNull.Value);
+      GenerateSchemaAndSerializeFromType(new JsonPropertyWithHandlingValues());
+    }
+
+    [Test]
+    public void UndefinedPropertyOnNoPropertySchema()
+    {
+      JsonSchema schema = JsonSchema.Parse(@"{
+  ""description"": ""test"",
+  ""type"": ""object"",
+  ""additionalProperties"": false,
+  ""properties"": {
+  }
+}");
+
+      JObject o = JObject.Parse("{'g':1}");
+
+      List<string> errors = new List<string>();
+      o.Validate(schema, (sender, args) => errors.Add(args.Message));
+
+      Assert.AreEqual(1, errors.Count);
+      Assert.AreEqual("Property 'g' has not been defined and the schema does not allow additional properties. Line 1, position 5.", errors[0]);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSchemaException), ExpectedMessage = "Integer 10 equals maximum value of 10 and exclusive maximum is true.")]
+    public void ExclusiveMaximum_Int()
+    {
+      JsonSchema schema = new JsonSchema();
+      schema.Maximum = 10;
+      schema.ExclusiveMaximum = true;
+
+      JValue v = new JValue(10);
+      v.Validate(schema);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSchemaException), ExpectedMessage = "Float 10.1 equals maximum value of 10.1 and exclusive maximum is true.")]
+    public void ExclusiveMaximum_Float()
+    {
+      JsonSchema schema = new JsonSchema();
+      schema.Maximum = 10.1;
+      schema.ExclusiveMaximum = true;
+
+      JValue v = new JValue(10.1);
+      v.Validate(schema);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSchemaException), ExpectedMessage = "Integer 10 equals minimum value of 10 and exclusive minimum is true.")]
+    public void ExclusiveMinimum_Int()
+    {
+      JsonSchema schema = new JsonSchema();
+      schema.Minimum = 10;
+      schema.ExclusiveMinimum = true;
+
+      JValue v = new JValue(10);
+      v.Validate(schema);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSchemaException), ExpectedMessage = "Float 10.1 equals minimum value of 10.1 and exclusive minimum is true.")]
+    public void ExclusiveMinimum_Float()
+    {
+      JsonSchema schema = new JsonSchema();
+      schema.Minimum = 10.1;
+      schema.ExclusiveMinimum = true;
+
+      JValue v = new JValue(10.1);
+      v.Validate(schema);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSchemaException), ExpectedMessage = "Integer 10 is not evenly divisible by 3.")]
+    public void DivisibleBy_Int()
+    {
+      JsonSchema schema = new JsonSchema();
+      schema.DivisibleBy = 3;
+
+      JValue v = new JValue(10);
+      v.Validate(schema);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaBuilderTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaBuilderTests.cs
new file mode 100644 (file)
index 0000000..0c27c02
--- /dev/null
@@ -0,0 +1,469 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using Newtonsoft.Json.Schema;
+using System.IO;
+using Newtonsoft.Json.Linq;
+
+namespace Newtonsoft.Json.Tests.Schema
+{
+  public class JsonSchemaBuilderTests : TestFixtureBase
+  {
+    [Test]
+    public void Simple()
+    {
+      string json = @"
+{
+  ""description"": ""A person"",
+  ""type"": ""object"",
+  ""properties"":
+  {
+    ""name"": {""type"":""string""},
+    ""hobbies"": {
+      ""type"": ""array"",
+      ""items"": {""type"":""string""}
+    }
+  }
+}
+";
+
+      JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver());
+      JsonSchema schema = builder.Parse(new JsonTextReader(new StringReader(json)));
+
+      Assert.AreEqual("A person", schema.Description);
+      Assert.AreEqual(JsonSchemaType.Object, schema.Type);
+
+      Assert.AreEqual(2, schema.Properties.Count);
+
+      Assert.AreEqual(JsonSchemaType.String, schema.Properties["name"].Type);
+      Assert.AreEqual(JsonSchemaType.Array, schema.Properties["hobbies"].Type);
+      Assert.AreEqual(JsonSchemaType.String, schema.Properties["hobbies"].Items[0].Type);
+    }
+
+    [Test]
+    public void MultipleTypes()
+    {
+      string json = @"{
+  ""description"":""Age"",
+  ""type"":[""string"", ""integer""]
+}";
+
+      JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver());
+      JsonSchema schema = builder.Parse(new JsonTextReader(new StringReader(json)));
+
+      Assert.AreEqual("Age", schema.Description);
+      Assert.AreEqual(JsonSchemaType.String | JsonSchemaType.Integer, schema.Type);
+    }
+
+    [Test]
+    public void MultipleItems()
+    {
+      string json = @"{
+  ""description"":""MultipleItems"",
+  ""type"":""array"",
+  ""items"": [{""type"":""string""},{""type"":""array""}]
+}";
+
+      JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver());
+      JsonSchema schema = builder.Parse(new JsonTextReader(new StringReader(json)));
+
+      Assert.AreEqual("MultipleItems", schema.Description);
+      Assert.AreEqual(JsonSchemaType.String, schema.Items[0].Type);
+      Assert.AreEqual(JsonSchemaType.Array, schema.Items[1].Type);
+    }
+
+    [Test]
+    public void AdditionalProperties()
+    {
+      string json = @"{
+  ""description"":""AdditionalProperties"",
+  ""type"":[""string"", ""integer""],
+  ""additionalProperties"":{""type"":[""object"", ""boolean""]}
+}";
+
+      JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver());
+      JsonSchema schema = builder.Parse(new JsonTextReader(new StringReader(json)));
+
+      Assert.AreEqual("AdditionalProperties", schema.Description);
+      Assert.AreEqual(JsonSchemaType.Object | JsonSchemaType.Boolean, schema.AdditionalProperties.Type);
+    }
+
+    [Test]
+    public void Required()
+    {
+      string json = @"{
+  ""description"":""Required"",
+  ""required"":true
+}";
+
+      JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver());
+      JsonSchema schema = builder.Parse(new JsonTextReader(new StringReader(json)));
+
+      Assert.AreEqual("Required", schema.Description);
+      Assert.AreEqual(true, schema.Required);
+    }
+
+    [Test]
+    public void ExclusiveMinimum_ExclusiveMaximum()
+    {
+      string json = @"{
+  ""exclusiveMinimum"":true,
+  ""exclusiveMaximum"":true
+}";
+
+      JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver());
+      JsonSchema schema = builder.Parse(new JsonTextReader(new StringReader(json)));
+
+      Assert.AreEqual(true, schema.ExclusiveMinimum);
+      Assert.AreEqual(true, schema.ExclusiveMaximum);
+    }
+
+    [Test]
+    public void ReadOnly()
+    {
+      string json = @"{
+  ""description"":""ReadOnly"",
+  ""readonly"":true
+}";
+
+      JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver());
+      JsonSchema schema = builder.Parse(new JsonTextReader(new StringReader(json)));
+
+      Assert.AreEqual("ReadOnly", schema.Description);
+      Assert.AreEqual(true, schema.ReadOnly);
+    }
+
+    [Test]
+    public void Hidden()
+    {
+      string json = @"{
+  ""description"":""Hidden"",
+  ""hidden"":true
+}";
+
+      JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver());
+      JsonSchema schema = builder.Parse(new JsonTextReader(new StringReader(json)));
+
+      Assert.AreEqual("Hidden", schema.Description);
+      Assert.AreEqual(true, schema.Hidden);
+    }
+
+    [Test]
+    public void Id()
+    {
+      string json = @"{
+  ""description"":""Id"",
+  ""id"":""testid""
+}";
+
+      JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver());
+      JsonSchema schema = builder.Parse(new JsonTextReader(new StringReader(json)));
+
+      Assert.AreEqual("Id", schema.Description);
+      Assert.AreEqual("testid", schema.Id);
+    }
+
+    [Test]
+    public void Title()
+    {
+      string json = @"{
+  ""description"":""Title"",
+  ""title"":""testtitle""
+}";
+
+      JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver());
+      JsonSchema schema = builder.Parse(new JsonTextReader(new StringReader(json)));
+
+      Assert.AreEqual("Title", schema.Description);
+      Assert.AreEqual("testtitle", schema.Title);
+    }
+
+    [Test]
+    public void Pattern()
+    {
+      string json = @"{
+  ""description"":""Pattern"",
+  ""pattern"":""testpattern""
+}";
+
+      JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver());
+      JsonSchema schema = builder.Parse(new JsonTextReader(new StringReader(json)));
+
+      Assert.AreEqual("Pattern", schema.Description);
+      Assert.AreEqual("testpattern", schema.Pattern);
+    }
+
+    [Test]
+    public void Format()
+    {
+      string json = @"{
+  ""description"":""Format"",
+  ""format"":""testformat""
+}";
+
+      JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver());
+      JsonSchema schema = builder.Parse(new JsonTextReader(new StringReader(json)));
+
+      Assert.AreEqual("Format", schema.Description);
+      Assert.AreEqual("testformat", schema.Format);
+    }
+
+    [Test]
+    public void Requires()
+    {
+      string json = @"{
+  ""description"":""Requires"",
+  ""requires"":""PurpleMonkeyDishwasher""
+}";
+
+      JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver());
+      JsonSchema schema = builder.Parse(new JsonTextReader(new StringReader(json)));
+
+      Assert.AreEqual("Requires", schema.Description);
+      Assert.AreEqual("PurpleMonkeyDishwasher", schema.Requires);
+    }
+
+    [Test]
+    public void IdentitySingle()
+    {
+      string json = @"{
+  ""description"":""Identity"",
+  ""identity"":""PurpleMonkeyDishwasher""
+}";
+
+      JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver());
+      JsonSchema schema = builder.Parse(new JsonTextReader(new StringReader(json)));
+
+      Assert.AreEqual("Identity", schema.Description);
+      Assert.AreEqual(1, schema.Identity.Count);
+      Assert.AreEqual("PurpleMonkeyDishwasher", schema.Identity[0]);
+    }
+
+    [Test]
+    public void IdentityMultiple()
+    {
+      string json = @"{
+  ""description"":""Identity"",
+  ""identity"":[""PurpleMonkeyDishwasher"",""Antelope""]
+}";
+
+      JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver());
+      JsonSchema schema = builder.Parse(new JsonTextReader(new StringReader(json)));
+
+      Assert.AreEqual("Identity", schema.Description);
+      Assert.AreEqual(2, schema.Identity.Count);
+      Assert.AreEqual("PurpleMonkeyDishwasher", schema.Identity[0]);
+      Assert.AreEqual("Antelope", schema.Identity[1]);
+    }
+
+    [Test]
+    public void MinimumMaximum()
+    {
+      string json = @"{
+  ""description"":""MinimumMaximum"",
+  ""minimum"":1.1,
+  ""maximum"":1.2,
+  ""minItems"":1,
+  ""maxItems"":2,
+  ""minLength"":5,
+  ""maxLength"":50,
+  ""divisibleBy"":3,
+}";
+
+      JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver());
+      JsonSchema schema = builder.Parse(new JsonTextReader(new StringReader(json)));
+
+      Assert.AreEqual("MinimumMaximum", schema.Description);
+      Assert.AreEqual(1.1, schema.Minimum);
+      Assert.AreEqual(1.2, schema.Maximum);
+      Assert.AreEqual(1, schema.MinimumItems);
+      Assert.AreEqual(2, schema.MaximumItems);
+      Assert.AreEqual(5, schema.MinimumLength);
+      Assert.AreEqual(50, schema.MaximumLength);
+      Assert.AreEqual(3, schema.DivisibleBy);
+    }
+
+    [Test]
+    public void DisallowSingleType()
+    {
+      string json = @"{
+  ""description"":""DisallowSingleType"",
+  ""disallow"":""string""
+}";
+
+      JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver());
+      JsonSchema schema = builder.Parse(new JsonTextReader(new StringReader(json)));
+
+      Assert.AreEqual("DisallowSingleType", schema.Description);
+      Assert.AreEqual(JsonSchemaType.String, schema.Disallow);
+    }
+
+    [Test]
+    public void DisallowMultipleTypes()
+    {
+      string json = @"{
+  ""description"":""DisallowMultipleTypes"",
+  ""disallow"":[""string"",""number""]
+}";
+
+      JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver());
+      JsonSchema schema = builder.Parse(new JsonTextReader(new StringReader(json)));
+
+      Assert.AreEqual("DisallowMultipleTypes", schema.Description);
+      Assert.AreEqual(JsonSchemaType.String | JsonSchemaType.Float, schema.Disallow);
+    }
+
+    [Test]
+    public void DefaultPrimitiveType()
+    {
+      string json = @"{
+  ""description"":""DefaultPrimitiveType"",
+  ""default"":1.1
+}";
+
+      JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver());
+      JsonSchema schema = builder.Parse(new JsonTextReader(new StringReader(json)));
+
+      Assert.AreEqual("DefaultPrimitiveType", schema.Description);
+      Assert.AreEqual(1.1, (double)schema.Default);
+    }
+
+    [Test]
+    public void DefaultComplexType()
+    {
+      string json = @"{
+  ""description"":""DefaultComplexType"",
+  ""default"":{""pie"":true}
+}";
+
+      JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver());
+      JsonSchema schema = builder.Parse(new JsonTextReader(new StringReader(json)));
+
+      Assert.AreEqual("DefaultComplexType", schema.Description);
+      Assert.IsTrue(JToken.DeepEquals(JObject.Parse(@"{""pie"":true}"), schema.Default));
+    }
+
+    [Test]
+    public void Options()
+    {
+      string json = @"{
+  ""description"":""NZ Island"",
+  ""type"":""string"",
+  ""options"":
+  [
+    {""value"":""NI"",""label"":""North Island""},
+    {""value"":""SI"",""label"":""South Island""}
+  ]
+}";
+
+      JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver());
+      JsonSchema schema = builder.Parse(new JsonTextReader(new StringReader(json)));
+
+      Assert.AreEqual("NZ Island", schema.Description);
+      Assert.AreEqual(JsonSchemaType.String, schema.Type);
+
+      Assert.AreEqual(2, schema.Options.Count);
+      Assert.AreEqual("North Island", schema.Options[new JValue("NI")]);
+      Assert.AreEqual("South Island", schema.Options[new JValue("SI")]);
+    }
+
+    [Test]
+    public void Enum()
+    {
+      string json = @"{
+  ""description"":""Type"",
+  ""type"":[""string"",""array""],
+  ""enum"":[""string"",""object"",""array"",""boolean"",""number"",""integer"",""null"",""any""]
+}";
+
+      JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver());
+      JsonSchema schema = builder.Parse(new JsonTextReader(new StringReader(json)));
+
+      Assert.AreEqual("Type", schema.Description);
+      Assert.AreEqual(JsonSchemaType.String | JsonSchemaType.Array, schema.Type);
+
+      Assert.AreEqual(8, schema.Enum.Count);
+      Assert.AreEqual("string", (string)schema.Enum[0]);
+      Assert.AreEqual("any", (string)schema.Enum[schema.Enum.Count - 1]);
+    }
+
+    [Test]
+    public void CircularReference()
+    {
+      string json = @"{
+  ""id"":""CircularReferenceArray"",
+  ""description"":""CircularReference"",
+  ""type"":[""array""],
+  ""items"":{""$ref"":""CircularReferenceArray""}
+}";
+
+      JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver());
+      JsonSchema schema = builder.Parse(new JsonTextReader(new StringReader(json)));
+
+      Assert.AreEqual("CircularReference", schema.Description);
+      Assert.AreEqual("CircularReferenceArray", schema.Id);
+      Assert.AreEqual(JsonSchemaType.Array, schema.Type);
+
+      Assert.AreEqual(schema, schema.Items[0]);
+    }
+
+    [Test]
+    [ExpectedException(typeof(Exception), ExpectedMessage = @"Could not resolve schema reference for Id 'MyUnresolvedReference'.")]
+    public void UnresolvedReference()
+    {
+      string json = @"{
+  ""id"":""CircularReferenceArray"",
+  ""description"":""CircularReference"",
+  ""type"":[""array""],
+  ""items"":{""$ref"":""MyUnresolvedReference""}
+}";
+
+      JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver());
+      JsonSchema schema = builder.Parse(new JsonTextReader(new StringReader(json)));
+    }
+
+    [Test]
+    public void PatternProperties()
+    {
+      string json = @"{
+  ""patternProperties"": {
+    ""[abc]"": { ""id"":""Blah"" }
+  }
+}";
+
+      JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver());
+      JsonSchema schema = builder.Parse(new JsonTextReader(new StringReader(json)));
+
+      Assert.IsNotNull(schema.PatternProperties);
+      Assert.AreEqual(1, schema.PatternProperties.Count);
+      Assert.AreEqual("Blah", schema.PatternProperties["[abc]"].Id);
+    }
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaGeneratorTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaGeneratorTests.cs
new file mode 100644 (file)
index 0000000..7365f9d
--- /dev/null
@@ -0,0 +1,724 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Globalization;
+using Newtonsoft.Json.Converters;
+using Newtonsoft.Json.Serialization;
+using Newtonsoft.Json.Tests.TestObjects;
+using Newtonsoft.Json.Utilities;
+using NUnit.Framework;
+using Newtonsoft.Json.Schema;
+using System.IO;
+using System.Linq;
+using Newtonsoft.Json.Linq;
+using System.Text;
+using Extensions=Newtonsoft.Json.Schema.Extensions;
+
+namespace Newtonsoft.Json.Tests.Schema
+{
+  public class JsonSchemaGeneratorTests : TestFixtureBase
+  {
+    [Test]
+    public void Generate_GenericDictionary()
+    {
+      JsonSchemaGenerator generator = new JsonSchemaGenerator();
+      JsonSchema schema = generator.Generate(typeof (Dictionary<string, List<string>>));
+
+      string json = schema.ToString();
+
+      Assert.AreEqual(@"{
+  ""type"": ""object"",
+  ""additionalProperties"": {
+    ""type"": [
+      ""array"",
+      ""null""
+    ],
+    ""items"": {
+      ""type"": [
+        ""string"",
+        ""null""
+      ]
+    }
+  }
+}", json);
+
+      Dictionary<string, List<string>> value = new Dictionary<string, List<string>>
+                                                 {
+                                                   {"HasValue", new List<string>() { "first", "second", null }},
+                                                   {"NoValue", null}
+                                                 };
+
+      string valueJson = JsonConvert.SerializeObject(value, Formatting.Indented);
+      JObject o = JObject.Parse(valueJson);
+
+      Assert.IsTrue(o.IsValid(schema));
+    }
+
+#if !PocketPC
+    [Test]
+    public void Generate_DefaultValueAttributeTestClass()
+    {
+      JsonSchemaGenerator generator = new JsonSchemaGenerator();
+      JsonSchema schema = generator.Generate(typeof(DefaultValueAttributeTestClass));
+
+      string json = schema.ToString();
+
+      Assert.AreEqual(@"{
+  ""description"": ""DefaultValueAttributeTestClass description!"",
+  ""type"": ""object"",
+  ""additionalProperties"": false,
+  ""properties"": {
+    ""TestField1"": {
+      ""required"": true,
+      ""type"": ""integer"",
+      ""default"": 21
+    },
+    ""TestProperty1"": {
+      ""required"": true,
+      ""type"": [
+        ""string"",
+        ""null""
+      ],
+      ""default"": ""TestProperty1Value""
+    }
+  }
+}", json);
+    }
+#endif
+
+    [Test]
+    public void Generate_Person()
+    {
+      JsonSchemaGenerator generator = new JsonSchemaGenerator();
+      JsonSchema schema = generator.Generate(typeof(Person));
+
+      string json = schema.ToString();
+
+      Assert.AreEqual(@"{
+  ""id"": ""Person"",
+  ""title"": ""Title!"",
+  ""description"": ""JsonObjectAttribute description!"",
+  ""type"": ""object"",
+  ""properties"": {
+    ""Name"": {
+      ""required"": true,
+      ""type"": [
+        ""string"",
+        ""null""
+      ]
+    },
+    ""BirthDate"": {
+      ""required"": true,
+      ""type"": ""string""
+    },
+    ""LastModified"": {
+      ""required"": true,
+      ""type"": ""string""
+    }
+  }
+}", json);
+    }
+
+    [Test]
+    public void Generate_UserNullable()
+    {
+      JsonSchemaGenerator generator = new JsonSchemaGenerator();
+      JsonSchema schema = generator.Generate(typeof(UserNullable));
+
+      string json = schema.ToString();
+
+      Assert.AreEqual(@"{
+  ""type"": ""object"",
+  ""properties"": {
+    ""Id"": {
+      ""required"": true,
+      ""type"": ""string""
+    },
+    ""FName"": {
+      ""required"": true,
+      ""type"": [
+        ""string"",
+        ""null""
+      ]
+    },
+    ""LName"": {
+      ""required"": true,
+      ""type"": [
+        ""string"",
+        ""null""
+      ]
+    },
+    ""RoleId"": {
+      ""required"": true,
+      ""type"": ""integer""
+    },
+    ""NullableRoleId"": {
+      ""required"": true,
+      ""type"": [
+        ""integer"",
+        ""null""
+      ]
+    },
+    ""NullRoleId"": {
+      ""required"": true,
+      ""type"": [
+        ""integer"",
+        ""null""
+      ]
+    },
+    ""Active"": {
+      ""required"": true,
+      ""type"": [
+        ""boolean"",
+        ""null""
+      ]
+    }
+  }
+}", json);
+    }
+
+    [Test]
+    public void Generate_RequiredMembersClass()
+    {
+      JsonSchemaGenerator generator = new JsonSchemaGenerator();
+      JsonSchema schema = generator.Generate(typeof(RequiredMembersClass));
+
+      Assert.AreEqual(JsonSchemaType.String, schema.Properties["FirstName"].Type);
+      Assert.AreEqual(JsonSchemaType.String | JsonSchemaType.Null, schema.Properties["MiddleName"].Type);
+      Assert.AreEqual(JsonSchemaType.String | JsonSchemaType.Null, schema.Properties["LastName"].Type);
+      Assert.AreEqual(JsonSchemaType.String, schema.Properties["BirthDate"].Type);
+    }
+
+    [Test]
+    public void Generate_Store()
+    {
+      JsonSchemaGenerator generator = new JsonSchemaGenerator();
+      JsonSchema schema = generator.Generate(typeof(Store));
+
+      Assert.AreEqual(11, schema.Properties.Count);
+
+      JsonSchema productArraySchema = schema.Properties["product"];
+      JsonSchema productSchema = productArraySchema.Items[0];
+
+      Assert.AreEqual(4, productSchema.Properties.Count);
+    }
+
+    [Test]
+    public void MissingSchemaIdHandlingTest()
+    {
+      JsonSchemaGenerator generator = new JsonSchemaGenerator();
+
+      JsonSchema schema = generator.Generate(typeof(Store));
+      Assert.AreEqual(null, schema.Id);
+
+      generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName;
+      schema = generator.Generate(typeof (Store));
+      Assert.AreEqual(typeof(Store).FullName, schema.Id);
+
+      generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseAssemblyQualifiedName;
+      schema = generator.Generate(typeof(Store));
+      Assert.AreEqual(typeof(Store).AssemblyQualifiedName, schema.Id);
+    }
+
+    [Test]
+    public void Generate_NumberFormatInfo()
+    {
+      JsonSchemaGenerator generator = new JsonSchemaGenerator();
+      JsonSchema schema = generator.Generate(typeof(NumberFormatInfo));
+
+      string json = schema.ToString();
+
+      Console.WriteLine(json);
+
+      //      Assert.AreEqual(@"{
+      //  ""type"": ""object"",
+      //  ""additionalProperties"": {
+      //    ""type"": ""array"",
+      //    ""items"": {
+      //      ""type"": ""string""
+      //    }
+      //  }
+      //}", json);
+    }
+
+    [Test]
+    [ExpectedException(typeof(Exception), ExpectedMessage = @"Unresolved circular reference for type 'Newtonsoft.Json.Tests.TestObjects.CircularReferenceClass'. Explicitly define an Id for the type using a JsonObject/JsonArray attribute or automatically generate a type Id using the UndefinedSchemaIdHandling property.")]
+    public void CircularReferenceError()
+    {
+      JsonSchemaGenerator generator = new JsonSchemaGenerator();
+      generator.Generate(typeof(CircularReferenceClass));
+    }
+
+    [Test]
+    public void CircularReferenceWithTypeNameId()
+    {
+      JsonSchemaGenerator generator = new JsonSchemaGenerator();
+      generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName;
+
+      JsonSchema schema = generator.Generate(typeof(CircularReferenceClass), true);
+
+      Assert.AreEqual(JsonSchemaType.String, schema.Properties["Name"].Type);
+      Assert.AreEqual(typeof(CircularReferenceClass).FullName, schema.Id);
+      Assert.AreEqual(JsonSchemaType.Object | JsonSchemaType.Null, schema.Properties["Child"].Type);
+      Assert.AreEqual(schema, schema.Properties["Child"]);
+    }
+
+    [Test]
+    public void CircularReferenceWithExplicitId()
+    {
+      JsonSchemaGenerator generator = new JsonSchemaGenerator();
+
+      JsonSchema schema = generator.Generate(typeof(CircularReferenceWithIdClass));
+
+      Assert.AreEqual(JsonSchemaType.String | JsonSchemaType.Null, schema.Properties["Name"].Type);
+      Assert.AreEqual("MyExplicitId", schema.Id);
+      Assert.AreEqual(JsonSchemaType.Object | JsonSchemaType.Null, schema.Properties["Child"].Type);
+      Assert.AreEqual(schema, schema.Properties["Child"]);
+    }
+
+    [Test]
+    public void GenerateSchemaForType()
+    {
+      JsonSchemaGenerator generator = new JsonSchemaGenerator();
+      generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName;
+
+      JsonSchema schema = generator.Generate(typeof(Type));
+
+      Assert.AreEqual(JsonSchemaType.String, schema.Type);
+
+      string json = JsonConvert.SerializeObject(typeof(Version), Formatting.Indented);
+
+      JValue v = new JValue(json);
+      Assert.IsTrue(v.IsValid(schema));
+    }
+
+#if !SILVERLIGHT && !PocketPC
+    [Test]
+    public void GenerateSchemaForISerializable()
+    {
+      JsonSchemaGenerator generator = new JsonSchemaGenerator();
+      generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName;
+
+      JsonSchema schema = generator.Generate(typeof(Exception));
+
+      Assert.AreEqual(JsonSchemaType.Object, schema.Type);
+      Assert.AreEqual(true, schema.AllowAdditionalProperties);
+      Assert.AreEqual(null, schema.Properties);
+    }
+#endif
+
+    [Test]
+    public void GenerateSchemaForDBNull()
+    {
+      JsonSchemaGenerator generator = new JsonSchemaGenerator();
+      generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName;
+
+      JsonSchema schema = generator.Generate(typeof(DBNull));
+
+      Assert.AreEqual(JsonSchemaType.Null, schema.Type);
+    }
+
+    public class CustomDirectoryInfoMapper : DefaultContractResolver
+    {
+      public CustomDirectoryInfoMapper()
+        : base(true)
+      {
+      }
+
+      protected override JsonContract CreateContract(Type objectType)
+      {
+        if (objectType == typeof(DirectoryInfo))
+          return base.CreateObjectContract(objectType);
+
+        return base.CreateContract(objectType);
+      }
+
+      protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
+      {
+        IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization);
+
+        JsonPropertyCollection c = new JsonPropertyCollection(type);
+        CollectionUtils.AddRange(c, (IEnumerable)properties.Where(m => m.PropertyName != "Root"));
+
+        return c;
+      }
+    }
+
+    [Test]
+    public void GenerateSchemaForDirectoryInfo()
+    {
+      JsonSchemaGenerator generator = new JsonSchemaGenerator();
+      generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName;
+      generator.ContractResolver = new CustomDirectoryInfoMapper();
+
+      JsonSchema schema = generator.Generate(typeof(DirectoryInfo), true);
+
+      string json = schema.ToString();
+      
+      Assert.AreEqual(@"{
+  ""id"": ""System.IO.DirectoryInfo"",
+  ""required"": true,
+  ""type"": [
+    ""object"",
+    ""null""
+  ],
+  ""additionalProperties"": false,
+  ""properties"": {
+    ""Name"": {
+      ""required"": true,
+      ""type"": [
+        ""string"",
+        ""null""
+      ]
+    },
+    ""Parent"": {
+      ""$ref"": ""System.IO.DirectoryInfo""
+    },
+    ""Exists"": {
+      ""required"": true,
+      ""type"": ""boolean""
+    },
+    ""FullName"": {
+      ""required"": true,
+      ""type"": [
+        ""string"",
+        ""null""
+      ]
+    },
+    ""Extension"": {
+      ""required"": true,
+      ""type"": [
+        ""string"",
+        ""null""
+      ]
+    },
+    ""CreationTime"": {
+      ""required"": true,
+      ""type"": ""string""
+    },
+    ""CreationTimeUtc"": {
+      ""required"": true,
+      ""type"": ""string""
+    },
+    ""LastAccessTime"": {
+      ""required"": true,
+      ""type"": ""string""
+    },
+    ""LastAccessTimeUtc"": {
+      ""required"": true,
+      ""type"": ""string""
+    },
+    ""LastWriteTime"": {
+      ""required"": true,
+      ""type"": ""string""
+    },
+    ""LastWriteTimeUtc"": {
+      ""required"": true,
+      ""type"": ""string""
+    },
+    ""Attributes"": {
+      ""required"": true,
+      ""type"": ""integer""
+    }
+  }
+}", json);
+
+      DirectoryInfo temp = new DirectoryInfo(@"c:\temp");
+
+      JTokenWriter jsonWriter = new JTokenWriter();
+      JsonSerializer serializer = new JsonSerializer();
+      serializer.Converters.Add(new IsoDateTimeConverter());
+      serializer.ContractResolver = new CustomDirectoryInfoMapper();
+      serializer.Serialize(jsonWriter, temp);
+
+      List<string> errors = new List<string>();
+      jsonWriter.Token.Validate(schema, (sender, args) => errors.Add(args.Message));
+
+      Assert.AreEqual(0, errors.Count);
+    }
+
+    [Test]
+    public void GenerateSchemaCamelCase()
+    {
+      JsonSchemaGenerator generator = new JsonSchemaGenerator();
+      generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName;
+      generator.ContractResolver = new CamelCasePropertyNamesContractResolver();
+
+      JsonSchema schema = generator.Generate(typeof (Version), true);
+
+      string json = schema.ToString();
+
+      Assert.AreEqual(@"{
+  ""id"": ""System.Version"",
+  ""type"": [
+    ""object"",
+    ""null""
+  ],
+  ""additionalProperties"": false,
+  ""properties"": {
+    ""major"": {
+      ""required"": true,
+      ""type"": ""integer""
+    },
+    ""minor"": {
+      ""required"": true,
+      ""type"": ""integer""
+    },
+    ""build"": {
+      ""required"": true,
+      ""type"": ""integer""
+    },
+    ""revision"": {
+      ""required"": true,
+      ""type"": ""integer""
+    },
+    ""majorRevision"": {
+      ""required"": true,
+      ""type"": ""integer""
+    },
+    ""minorRevision"": {
+      ""required"": true,
+      ""type"": ""integer""
+    }
+  }
+}", json);
+    }
+
+    public enum SortTypeFlag
+    {
+      No = 0,
+      Asc = 1,
+      Desc = -1
+    }
+
+    public class X
+    {
+      public SortTypeFlag x;
+    }
+
+    [Test]
+    public void GenerateSchemaWithNegativeEnum()
+    {
+      JsonSchemaGenerator jsonSchemaGenerator = new JsonSchemaGenerator();
+      JsonSchema schema = jsonSchemaGenerator.Generate(typeof(X));
+
+      string json = schema.ToString();
+
+      Assert.AreEqual(@"{
+  ""type"": ""object"",
+  ""properties"": {
+    ""x"": {
+      ""required"": true,
+      ""type"": ""integer"",
+      ""enum"": [
+        0,
+        1,
+        -1
+      ],
+      ""options"": [
+        {
+          ""value"": 0,
+          ""label"": ""No""
+        },
+        {
+          ""value"": 1,
+          ""label"": ""Asc""
+        },
+        {
+          ""value"": -1,
+          ""label"": ""Desc""
+        }
+      ]
+    }
+  }
+}", json);
+    }
+
+    [Test]
+    public void CircularCollectionReferences()
+    {
+      Type type = typeof (Workspace);
+      JsonSchemaGenerator jsonSchemaGenerator = new JsonSchemaGenerator();
+
+      jsonSchemaGenerator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName;
+      JsonSchema jsonSchema = jsonSchemaGenerator.Generate(type);
+
+      // should succeed
+      Assert.IsNotNull(jsonSchema);
+    }
+
+    [Test]
+    public void CircularReferenceWithMixedRequires()
+    {
+      JsonSchemaGenerator jsonSchemaGenerator = new JsonSchemaGenerator();
+
+      jsonSchemaGenerator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName;
+      JsonSchema jsonSchema = jsonSchemaGenerator.Generate(typeof(CircularReferenceClass));
+      string json = jsonSchema.ToString();
+
+      Assert.AreEqual(@"{
+  ""id"": ""Newtonsoft.Json.Tests.TestObjects.CircularReferenceClass"",
+  ""type"": [
+    ""object"",
+    ""null""
+  ],
+  ""properties"": {
+    ""Name"": {
+      ""required"": true,
+      ""type"": ""string""
+    },
+    ""Child"": {
+      ""$ref"": ""Newtonsoft.Json.Tests.TestObjects.CircularReferenceClass""
+    }
+  }
+}", json);
+    }
+
+    [Test]
+    public void JsonPropertyWithHandlingValues()
+    {
+      JsonSchemaGenerator jsonSchemaGenerator = new JsonSchemaGenerator();
+
+      jsonSchemaGenerator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName;
+      JsonSchema jsonSchema = jsonSchemaGenerator.Generate(typeof(JsonPropertyWithHandlingValues));
+      string json = jsonSchema.ToString();
+
+      Assert.AreEqual(@"{
+  ""id"": ""Newtonsoft.Json.Tests.TestObjects.JsonPropertyWithHandlingValues"",
+  ""required"": true,
+  ""type"": [
+    ""object"",
+    ""null""
+  ],
+  ""properties"": {
+    ""DefaultValueHandlingIgnoreProperty"": {
+      ""type"": [
+        ""string"",
+        ""null""
+      ],
+      ""default"": ""Default!""
+    },
+    ""DefaultValueHandlingIncludeProperty"": {
+      ""required"": true,
+      ""type"": [
+        ""string"",
+        ""null""
+      ],
+      ""default"": ""Default!""
+    },
+    ""NullValueHandlingIgnoreProperty"": {
+      ""type"": [
+        ""string"",
+        ""null""
+      ]
+    },
+    ""NullValueHandlingIncludeProperty"": {
+      ""required"": true,
+      ""type"": [
+        ""string"",
+        ""null""
+      ]
+    },
+    ""ReferenceLoopHandlingErrorProperty"": {
+      ""$ref"": ""Newtonsoft.Json.Tests.TestObjects.JsonPropertyWithHandlingValues""
+    },
+    ""ReferenceLoopHandlingIgnoreProperty"": {
+      ""$ref"": ""Newtonsoft.Json.Tests.TestObjects.JsonPropertyWithHandlingValues""
+    },
+    ""ReferenceLoopHandlingSerializeProperty"": {
+      ""$ref"": ""Newtonsoft.Json.Tests.TestObjects.JsonPropertyWithHandlingValues""
+    }
+  }
+}", json);
+    }
+  }
+
+  public class DMDSLBase
+  {
+    public String Comment;
+  }
+
+  public class Workspace : DMDSLBase
+  {
+    public ControlFlowItemCollection Jobs = new ControlFlowItemCollection();
+  }
+
+  public class ControlFlowItemBase : DMDSLBase
+  {
+    public String Name;
+  }
+
+  public class ControlFlowItem : ControlFlowItemBase//A Job
+  {
+    public TaskCollection Tasks = new TaskCollection();
+    public ContainerCollection Containers = new ContainerCollection();
+  }
+
+  public class ControlFlowItemCollection : List<ControlFlowItem>
+  {
+  }
+
+  public class Task : ControlFlowItemBase
+  {
+    public DataFlowTaskCollection DataFlowTasks = new DataFlowTaskCollection();
+    public BulkInsertTaskCollection BulkInsertTask = new BulkInsertTaskCollection();
+  }
+
+  public class TaskCollection : List<Task>
+  {
+  }
+
+  public class Container : ControlFlowItemBase
+  {
+    public ControlFlowItemCollection ContainerJobs = new ControlFlowItemCollection();
+  }
+
+  public class ContainerCollection : List<Container>
+  {
+  }
+
+  public class DataFlowTask_DSL : ControlFlowItemBase
+  {
+  }
+
+  public class DataFlowTaskCollection : List<DataFlowTask_DSL>
+  {
+  }
+
+  public class SequenceContainer_DSL : Container
+  {
+  }
+
+  public class BulkInsertTaskCollection : List<BulkInsertTask_DSL>
+  {
+  }
+
+  public class BulkInsertTask_DSL
+  {
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaModelBuilderTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaModelBuilderTests.cs
new file mode 100644 (file)
index 0000000..0443dbd
--- /dev/null
@@ -0,0 +1,166 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Schema;
+using NUnit.Framework;
+
+namespace Newtonsoft.Json.Tests.Schema
+{
+  public class JsonSchemaModelBuilderTests : TestFixtureBase
+  {
+    [Test]
+    public void ExtendedComplex()
+    {
+      string first = @"{
+  ""id"":""first"",
+  ""type"":""object"",
+  ""properties"":
+  {
+    ""firstproperty"":{""type"":""string""},
+    ""secondproperty"":{""type"":""string"",""maxLength"":10},
+    ""thirdproperty"":{
+      ""type"":""object"",
+      ""properties"":
+      {
+        ""thirdproperty_firstproperty"":{""type"":""string"",""maxLength"":10,""minLength"":7}
+      }
+    }
+  },
+  ""additionalProperties"":{}
+}";
+
+      string second = @"{
+  ""id"":""second"",
+  ""type"":""object"",
+  ""extends"":{""$ref"":""first""},
+  ""properties"":
+  {
+    ""secondproperty"":{""type"":""any""},
+    ""thirdproperty"":{
+      ""extends"":{
+        ""properties"":
+        {
+          ""thirdproperty_firstproperty"":{""maxLength"":9,""minLength"":6,""pattern"":""hi2u""}
+        },
+        ""additionalProperties"":{""maxLength"":9,""minLength"":6,""enum"":[""one"",""two""]}
+      },
+      ""type"":""object"",
+      ""properties"":
+      {
+        ""thirdproperty_firstproperty"":{""pattern"":""hi""}
+      },
+      ""additionalProperties"":{""type"":""string"",""enum"":[""two"",""three""]}
+    },
+    ""fourthproperty"":{""type"":""string""}
+  },
+  ""additionalProperties"":false
+}";
+
+      JsonSchemaResolver resolver = new JsonSchemaResolver();
+      JsonSchema firstSchema = JsonSchema.Parse(first, resolver);
+      JsonSchema secondSchema = JsonSchema.Parse(second, resolver);
+
+      JsonSchemaModelBuilder modelBuilder = new JsonSchemaModelBuilder();
+
+      JsonSchemaModel model = modelBuilder.Build(secondSchema);
+
+      Assert.AreEqual(4, model.Properties.Count);
+
+      Assert.AreEqual(JsonSchemaType.String, model.Properties["firstproperty"].Type);
+
+      Assert.AreEqual(JsonSchemaType.String, model.Properties["secondproperty"].Type);
+      Assert.AreEqual(10, model.Properties["secondproperty"].MaximumLength);
+      Assert.AreEqual(null, model.Properties["secondproperty"].Enum);
+      Assert.AreEqual(null, model.Properties["secondproperty"].Patterns);
+
+      Assert.AreEqual(JsonSchemaType.Object, model.Properties["thirdproperty"].Type);
+      Assert.AreEqual(3, model.Properties["thirdproperty"].AdditionalProperties.Enum.Count);
+      Assert.AreEqual("two", (string)model.Properties["thirdproperty"].AdditionalProperties.Enum[0]);
+      Assert.AreEqual("three", (string)model.Properties["thirdproperty"].AdditionalProperties.Enum[1]);
+      Assert.AreEqual("one", (string)model.Properties["thirdproperty"].AdditionalProperties.Enum[2]);
+
+      Assert.AreEqual(JsonSchemaType.String, model.Properties["thirdproperty"].Properties["thirdproperty_firstproperty"].Type);
+      Assert.AreEqual(9, model.Properties["thirdproperty"].Properties["thirdproperty_firstproperty"].MaximumLength);
+      Assert.AreEqual(7, model.Properties["thirdproperty"].Properties["thirdproperty_firstproperty"].MinimumLength);
+      Assert.AreEqual(2, model.Properties["thirdproperty"].Properties["thirdproperty_firstproperty"].Patterns.Count);
+      Assert.AreEqual("hi", model.Properties["thirdproperty"].Properties["thirdproperty_firstproperty"].Patterns[0]);
+      Assert.AreEqual("hi2u", model.Properties["thirdproperty"].Properties["thirdproperty_firstproperty"].Patterns[1]);
+      Assert.AreEqual(null, model.Properties["thirdproperty"].Properties["thirdproperty_firstproperty"].Properties);
+      Assert.AreEqual(null, model.Properties["thirdproperty"].Properties["thirdproperty_firstproperty"].Items);
+      Assert.AreEqual(null, model.Properties["thirdproperty"].Properties["thirdproperty_firstproperty"].AdditionalProperties);
+    }
+
+    [Test]
+    public void CircularReference()
+    {
+      string json = @"{
+  ""id"":""CircularReferenceArray"",
+  ""description"":""CircularReference"",
+  ""type"":[""array""],
+  ""items"":{""$ref"":""CircularReferenceArray""}
+}";
+
+      JsonSchema schema = JsonSchema.Parse(json);
+
+      JsonSchemaModelBuilder modelBuilder = new JsonSchemaModelBuilder();
+
+      JsonSchemaModel model = modelBuilder.Build(schema);
+
+      Assert.AreEqual(JsonSchemaType.Array, model.Type);
+
+      Assert.AreEqual(model, model.Items[0]);
+    }
+
+    [Test]
+    public void Required()
+    {
+      string schemaJson = @"{
+  ""description"":""A person"",
+  ""type"":""object"",
+  ""properties"":
+  {
+    ""name"":{""type"":""string""},
+    ""hobbies"":{""type"":""string"",required:true},
+    ""age"":{""type"":""integer"",required:true}
+  }
+}";
+
+      JsonSchema schema = JsonSchema.Parse(schemaJson);
+      JsonSchemaModelBuilder modelBuilder = new JsonSchemaModelBuilder();
+      JsonSchemaModel model = modelBuilder.Build(schema);
+
+      Assert.AreEqual(JsonSchemaType.Object, model.Type);
+      Assert.AreEqual(3, model.Properties.Count);
+      Assert.AreEqual(false, model.Properties["name"].Required);
+      Assert.AreEqual(true, model.Properties["hobbies"].Required);
+      Assert.AreEqual(true, model.Properties["age"].Required);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaNodeTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaNodeTests.cs
new file mode 100644 (file)
index 0000000..fc26f09
--- /dev/null
@@ -0,0 +1,118 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Schema;
+using NUnit.Framework;
+
+namespace Newtonsoft.Json.Tests.Schema
+{
+  public class JsonSchemaNodeTests : TestFixtureBase
+  {
+    [Test]
+    public void AddSchema()
+    {
+      string first = @"{
+  ""id"":""first"",
+  ""type"":""object"",
+  ""properties"":
+  {
+    ""firstproperty"":{""type"":""string"",""maxLength"":10},
+    ""secondproperty"":{
+      ""type"":""object"",
+      ""properties"":
+      {
+        ""secondproperty_firstproperty"":{""type"":""string"",""maxLength"":10,""minLength"":7}
+      }
+    }
+  },
+  ""additionalProperties"":{}
+}";
+
+      string second = @"{
+  ""id"":""second"",
+  ""type"":""object"",
+  ""extends"":{""$ref"":""first""},
+  ""properties"":
+  {
+    ""firstproperty"":{""type"":""string""},
+    ""secondproperty"":{
+      ""extends"":{
+        ""properties"":
+        {
+          ""secondproperty_firstproperty"":{""maxLength"":9,""minLength"":6}
+        }
+      },
+      ""type"":""object"",
+      ""properties"":
+      {
+        ""secondproperty_firstproperty"":{}
+      }
+    },
+    ""thirdproperty"":{""type"":""string""}
+  },
+  ""additionalProperties"":false
+}";
+
+      JsonSchemaResolver resolver = new JsonSchemaResolver();
+      JsonSchema firstSchema = JsonSchema.Parse(first, resolver);
+      JsonSchema secondSchema = JsonSchema.Parse(second, resolver);
+
+      JsonSchemaModelBuilder modelBuilder = new JsonSchemaModelBuilder();
+
+      JsonSchemaNode node = modelBuilder.AddSchema(null, secondSchema);
+
+      Assert.AreEqual(2, node.Schemas.Count);
+      Assert.AreEqual(2, node.Properties["firstproperty"].Schemas.Count);
+      Assert.AreEqual(3, node.Properties["secondproperty"].Schemas.Count);
+      Assert.AreEqual(3, node.Properties["secondproperty"].Properties["secondproperty_firstproperty"].Schemas.Count);
+    }
+
+    [Test]
+    public void CircularReference()
+    {
+      string json = @"{
+  ""id"":""CircularReferenceArray"",
+  ""description"":""CircularReference"",
+  ""type"":[""array""],
+  ""items"":{""$ref"":""CircularReferenceArray""}
+}";
+
+      JsonSchema schema = JsonSchema.Parse(json);
+
+      JsonSchemaModelBuilder modelBuilder = new JsonSchemaModelBuilder();
+
+      JsonSchemaNode node = modelBuilder.AddSchema(null, schema);
+
+      Assert.AreEqual(1, node.Schemas.Count);
+
+      Assert.AreEqual(node, node.Items[0]);
+    }
+
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaTests.cs
new file mode 100644 (file)
index 0000000..ac242a2
--- /dev/null
@@ -0,0 +1,426 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Schema;
+using NUnit.Framework;
+
+namespace Newtonsoft.Json.Tests.Schema
+{
+  public class JsonSchemaTests : TestFixtureBase
+  {
+    [Test]
+    public void Extends()
+    {
+      string json;
+      JsonSchemaResolver resolver = new JsonSchemaResolver();
+
+      json = @"{
+  ""id"":""first"",
+  ""type"":""object"",
+  ""additionalProperties"":{}
+}";
+
+      JsonSchema first = JsonSchema.Parse(json, resolver);
+
+      json =
+        @"{
+  ""id"":""second"",
+  ""type"":""object"",
+  ""extends"":{""$ref"":""first""},
+  ""additionalProperties"":{""type"":""string""}
+}";
+
+      JsonSchema second = JsonSchema.Parse(json, resolver);
+      Assert.AreEqual(first, second.Extends);
+
+      json =
+        @"{
+  ""id"":""third"",
+  ""type"":""object"",
+  ""extends"":{""$ref"":""second""},
+  ""additionalProperties"":false
+}";
+
+      JsonSchema third = JsonSchema.Parse(json, resolver);
+      Assert.AreEqual(second, third.Extends);
+      Assert.AreEqual(first, third.Extends.Extends);
+
+      StringWriter writer = new StringWriter();
+      JsonTextWriter jsonWriter = new JsonTextWriter(writer);
+      jsonWriter.Formatting = Formatting.Indented;
+
+      third.WriteTo(jsonWriter, resolver);
+
+      string writtenJson = writer.ToString();
+      Assert.AreEqual(@"{
+  ""id"": ""third"",
+  ""type"": ""object"",
+  ""additionalProperties"": false,
+  ""extends"": {
+    ""$ref"": ""second""
+  }
+}", writtenJson);
+
+      StringWriter writer1 = new StringWriter();
+      JsonTextWriter jsonWriter1 = new JsonTextWriter(writer1);
+      jsonWriter1.Formatting = Formatting.Indented;
+
+      third.WriteTo(jsonWriter1);
+
+      writtenJson = writer1.ToString();
+      Assert.AreEqual(@"{
+  ""id"": ""third"",
+  ""type"": ""object"",
+  ""additionalProperties"": false,
+  ""extends"": {
+    ""id"": ""second"",
+    ""type"": ""object"",
+    ""additionalProperties"": {
+      ""type"": ""string""
+    },
+    ""extends"": {
+      ""id"": ""first"",
+      ""type"": ""object"",
+      ""additionalProperties"": {}
+    }
+  }
+}", writtenJson);
+    }
+    [Test]
+    public void WriteTo_AdditionalProperties()
+    {
+      StringWriter writer = new StringWriter();
+      JsonTextWriter jsonWriter = new JsonTextWriter(writer);
+      jsonWriter.Formatting = Formatting.Indented;
+
+      JsonSchema schema = JsonSchema.Parse(@"{
+  ""description"":""AdditionalProperties"",
+  ""type"":[""string"", ""integer""],
+  ""additionalProperties"":{""type"":[""object"", ""boolean""]}
+}");
+
+      schema.WriteTo(jsonWriter);
+
+      string json = writer.ToString();
+
+      Assert.AreEqual(@"{
+  ""description"": ""AdditionalProperties"",
+  ""type"": [
+    ""string"",
+    ""integer""
+  ],
+  ""additionalProperties"": {
+    ""type"": [
+      ""boolean"",
+      ""object""
+    ]
+  }
+}", json);
+    }
+
+    [Test]
+    public void WriteTo_Properties()
+    {
+      JsonSchema schema = JsonSchema.Parse(@"{
+  ""description"":""A person"",
+  ""type"":""object"",
+  ""properties"":
+  {
+    ""name"":{""type"":""string""},
+    ""hobbies"":
+    {
+      ""type"":""array"",
+      ""items"": {""type"":""string""}
+    }
+  }
+}");
+
+      StringWriter writer = new StringWriter();
+      JsonTextWriter jsonWriter = new JsonTextWriter(writer);
+      jsonWriter.Formatting = Formatting.Indented;
+
+      schema.WriteTo(jsonWriter);
+
+      string json = writer.ToString();
+
+      Assert.AreEqual(@"{
+  ""description"": ""A person"",
+  ""type"": ""object"",
+  ""properties"": {
+    ""name"": {
+      ""type"": ""string""
+    },
+    ""hobbies"": {
+      ""type"": ""array"",
+      ""items"": {
+        ""type"": ""string""
+      }
+    }
+  }
+}", json);
+
+    }
+
+    [Test]
+    public void WriteTo_Enum()
+    {
+      JsonSchema schema = JsonSchema.Parse(@"{
+  ""description"":""Type"",
+  ""type"":[""string"",""array""],
+  ""items"":{},
+  ""enum"":[""string"",""object"",""array"",""boolean"",""number"",""integer"",""null"",""any""]
+}");
+
+      StringWriter writer = new StringWriter();
+      JsonTextWriter jsonWriter = new JsonTextWriter(writer);
+      jsonWriter.Formatting = Formatting.Indented;
+
+      schema.WriteTo(jsonWriter);
+
+      string json = writer.ToString();
+
+      Assert.AreEqual(@"{
+  ""description"": ""Type"",
+  ""type"": [
+    ""string"",
+    ""array""
+  ],
+  ""items"": {},
+  ""enum"": [
+    ""string"",
+    ""object"",
+    ""array"",
+    ""boolean"",
+    ""number"",
+    ""integer"",
+    ""null"",
+    ""any""
+  ]
+}", json);
+    }
+
+    [Test]
+    public void WriteTo_CircularReference()
+    {
+      string json = @"{
+  ""id"":""CircularReferenceArray"",
+  ""description"":""CircularReference"",
+  ""type"":[""array""],
+  ""items"":{""$ref"":""CircularReferenceArray""}
+}";
+
+      JsonSchema schema = JsonSchema.Parse(json);
+
+      StringWriter writer = new StringWriter();
+      JsonTextWriter jsonWriter = new JsonTextWriter(writer);
+      jsonWriter.Formatting = Formatting.Indented;
+
+      schema.WriteTo(jsonWriter);
+
+      string writtenJson = writer.ToString();
+
+      Assert.AreEqual(@"{
+  ""id"": ""CircularReferenceArray"",
+  ""description"": ""CircularReference"",
+  ""type"": ""array"",
+  ""items"": {
+    ""$ref"": ""CircularReferenceArray""
+  }
+}", writtenJson);
+    }
+
+    [Test]
+    public void WriteTo_DisallowMultiple()
+    {
+      JsonSchema schema = JsonSchema.Parse(@"{
+  ""description"":""Type"",
+  ""type"":[""string"",""array""],
+  ""items"":{},
+  ""disallow"":[""string"",""object"",""array""]
+}");
+
+      StringWriter writer = new StringWriter();
+      JsonTextWriter jsonWriter = new JsonTextWriter(writer);
+      jsonWriter.Formatting = Formatting.Indented;
+
+      schema.WriteTo(jsonWriter);
+
+      string json = writer.ToString();
+
+      Assert.AreEqual(@"{
+  ""description"": ""Type"",
+  ""type"": [
+    ""string"",
+    ""array""
+  ],
+  ""items"": {},
+  ""disallow"": [
+    ""string"",
+    ""object"",
+    ""array""
+  ]
+}", json);
+    }
+
+    [Test]
+    public void WriteTo_DisallowSingle()
+    {
+      JsonSchema schema = JsonSchema.Parse(@"{
+  ""description"":""Type"",
+  ""type"":[""string"",""array""],
+  ""items"":{},
+  ""disallow"":""any""
+}");
+
+      StringWriter writer = new StringWriter();
+      JsonTextWriter jsonWriter = new JsonTextWriter(writer);
+      jsonWriter.Formatting = Formatting.Indented;
+
+      schema.WriteTo(jsonWriter);
+
+      string json = writer.ToString();
+
+      Assert.AreEqual(@"{
+  ""description"": ""Type"",
+  ""type"": [
+    ""string"",
+    ""array""
+  ],
+  ""items"": {},
+  ""disallow"": ""any""
+}", json);
+    }
+
+    [Test]
+    public void WriteTo_MultipleItems()
+    {
+      JsonSchema schema = JsonSchema.Parse(@"{
+  ""items"":[{},{}]
+}");
+
+      StringWriter writer = new StringWriter();
+      JsonTextWriter jsonWriter = new JsonTextWriter(writer);
+      jsonWriter.Formatting = Formatting.Indented;
+
+      schema.WriteTo(jsonWriter);
+
+      string json = writer.ToString();
+
+      Assert.AreEqual(@"{
+  ""items"": [
+    {},
+    {}
+  ]
+}", json);
+    }
+
+    [Test]
+    public void ReadOptions()
+    {
+      JsonSchema schema = JsonSchema.Parse(@"{
+  ""type"": ""object"",
+  ""properties"": {
+    ""x"": {
+      ""type"": ""integer"",
+      ""enum"": [
+        0,
+        1,
+        -1
+      ],
+      ""options"": [
+        {
+          ""value"": 0,
+          ""label"": ""No""
+        },
+        {
+          ""value"": 1,
+          ""label"": ""Asc""
+        },
+        {
+          ""value"": -1,
+          ""label"": ""Desc""
+        }
+      ]
+    }
+  }
+}");
+
+      Assert.AreEqual(schema.Properties["x"].Options.Count, 3);
+      Assert.AreEqual(schema.Properties["x"].Options[0], "No");
+      Assert.AreEqual(schema.Properties["x"].Options[1], "Asc");
+      Assert.AreEqual(schema.Properties["x"].Options[-1], "Desc");
+    }
+
+    [Test]
+    public void WriteTo_ExclusiveMinimum_ExclusiveMaximum()
+    {
+      JsonSchema schema = new JsonSchema();
+      schema.ExclusiveMinimum = true;
+      schema.ExclusiveMaximum = true;
+
+      StringWriter writer = new StringWriter();
+      JsonTextWriter jsonWriter = new JsonTextWriter(writer);
+      jsonWriter.Formatting = Formatting.Indented;
+
+      schema.WriteTo(jsonWriter);
+
+      string json = writer.ToString();
+
+      Assert.AreEqual(@"{
+  ""exclusiveMinimum"": true,
+  ""exclusiveMaximum"": true
+}", json);
+    }
+
+    [Test]
+    public void WriteTo_PatternProperties()
+    {
+      JsonSchema schema = new JsonSchema();
+      schema.PatternProperties = new Dictionary<string, JsonSchema>
+        {
+          { "[abc]", new JsonSchema() }
+        };
+
+      StringWriter writer = new StringWriter();
+      JsonTextWriter jsonWriter = new JsonTextWriter(writer);
+      jsonWriter.Formatting = Formatting.Indented;
+
+      schema.WriteTo(jsonWriter);
+
+      string json = writer.ToString();
+
+      Assert.AreEqual(@"{
+  ""patternProperties"": {
+    ""[abc]"": {}
+  }
+}", json);
+    }
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/CamelCasePropertyNamesContractResolverTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/CamelCasePropertyNamesContractResolverTests.cs
new file mode 100644 (file)
index 0000000..b849def
--- /dev/null
@@ -0,0 +1,217 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Serialization;
+using NUnit.Framework;
+using Newtonsoft.Json.Tests.TestObjects;
+using Newtonsoft.Json.Linq;
+using System.Reflection;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Tests.Serialization
+{
+  public class CamelCasePropertyNamesContractResolverTests : TestFixtureBase
+  {
+    [Test]
+    public void JsonConvertSerializerSettings()
+    {
+      Person person = new Person();
+      person.BirthDate = new DateTime(2000, 11, 20, 23, 55, 44, DateTimeKind.Utc);
+      person.LastModified = new DateTime(2000, 11, 20, 23, 55, 44, DateTimeKind.Utc);
+      person.Name = "Name!";
+
+      string json = JsonConvert.SerializeObject(person, Formatting.Indented, new JsonSerializerSettings
+                                                               {
+                                                                 ContractResolver = new CamelCasePropertyNamesContractResolver()
+                                                               });
+
+      Assert.AreEqual(@"{
+  ""name"": ""Name!"",
+  ""birthDate"": ""\/Date(974764544000)\/"",
+  ""lastModified"": ""\/Date(974764544000)\/""
+}", json);
+
+      Person deserializedPerson = JsonConvert.DeserializeObject<Person>(json, new JsonSerializerSettings
+                                                                        {
+                                                                          ContractResolver = new CamelCasePropertyNamesContractResolver()
+                                                                        });
+
+      Assert.AreEqual(person.BirthDate, deserializedPerson.BirthDate);
+      Assert.AreEqual(person.LastModified, deserializedPerson.LastModified);
+      Assert.AreEqual(person.Name, deserializedPerson.Name);
+
+      json = JsonConvert.SerializeObject(person, Formatting.Indented);
+      Assert.AreEqual(@"{
+  ""Name"": ""Name!"",
+  ""BirthDate"": ""\/Date(974764544000)\/"",
+  ""LastModified"": ""\/Date(974764544000)\/""
+}", json);
+
+    }
+
+    [Test]
+    public void JTokenWriter()
+    {
+      JsonIgnoreAttributeOnClassTestClass ignoreAttributeOnClassTestClass = new JsonIgnoreAttributeOnClassTestClass();
+      ignoreAttributeOnClassTestClass.Field = int.MinValue;
+
+      JsonSerializer serializer = new JsonSerializer();
+      serializer.ContractResolver = new CamelCasePropertyNamesContractResolver();
+
+      JTokenWriter writer = new JTokenWriter();
+
+      serializer.Serialize(writer, ignoreAttributeOnClassTestClass);
+
+      JObject o = (JObject) writer.Token;
+      JProperty p = o.Property("theField");
+
+      Assert.IsNotNull(p);
+      Assert.AreEqual(int.MinValue, (int)p.Value);
+
+      string json = o.ToString();
+    }
+
+    [Test]
+    public void MemberSearchFlags()
+    {
+      PrivateMembersClass privateMembersClass = new PrivateMembersClass("PrivateString!", "InternalString!");
+
+      string json = JsonConvert.SerializeObject(privateMembersClass, Formatting.Indented, new JsonSerializerSettings
+      {
+        ContractResolver = new CamelCasePropertyNamesContractResolver { DefaultMembersSearchFlags = BindingFlags.NonPublic | BindingFlags.Instance }
+      });
+
+      Assert.AreEqual(@"{
+  ""_privateString"": ""PrivateString!"",
+  ""i"": 0,
+  ""_internalString"": ""InternalString!""
+}", json);
+
+      PrivateMembersClass deserializedPrivateMembersClass = JsonConvert.DeserializeObject<PrivateMembersClass>(@"{
+  ""_privateString"": ""Private!"",
+  ""i"": -2,
+  ""_internalString"": ""Internal!""
+}", new JsonSerializerSettings
+      {
+        ContractResolver = new CamelCasePropertyNamesContractResolver { DefaultMembersSearchFlags = BindingFlags.NonPublic | BindingFlags.Instance }
+      });
+
+      Assert.AreEqual("Private!", ReflectionUtils.GetMemberValue(typeof(PrivateMembersClass).GetField("_privateString", BindingFlags.Instance | BindingFlags.NonPublic), deserializedPrivateMembersClass));
+      Assert.AreEqual("Internal!", ReflectionUtils.GetMemberValue(typeof(PrivateMembersClass).GetField("_internalString", BindingFlags.Instance | BindingFlags.NonPublic), deserializedPrivateMembersClass));
+
+      // readonly
+      Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(PrivateMembersClass).GetField("i", BindingFlags.Instance | BindingFlags.NonPublic), deserializedPrivateMembersClass));
+    }
+
+    [Test]
+    public void BlogPostExample()
+    {
+      Product product = new Product
+                          {
+                            ExpiryDate = new DateTime(2010, 12, 20, 18, 1, 0, DateTimeKind.Utc),
+                            Name = "Widget",
+                            Price = 9.99m,
+                            Sizes = new[] {"Small", "Medium", "Large"}
+                          };
+
+      string json = 
+        JsonConvert.SerializeObject(
+          product,
+          Formatting.Indented,
+          new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }
+        );
+
+      //{
+      //  "name": "Widget",
+      //  "expiryDate": "\/Date(1292868060000)\/",
+      //  "price": 9.99,
+      //  "sizes": [
+      //    "Small",
+      //    "Medium",
+      //    "Large"
+      //  ]
+      //}
+
+      Assert.AreEqual(@"{
+  ""name"": ""Widget"",
+  ""expiryDate"": ""\/Date(1292868060000)\/"",
+  ""price"": 9.99,
+  ""sizes"": [
+    ""Small"",
+    ""Medium"",
+    ""Large""
+  ]
+}", json);
+    }
+
+#if !(NET35 || NET20 || WINDOWS_PHONE)
+    [Test]
+    public void DynamicCamelCasePropertyNames()
+    {
+      dynamic o = new DynamicTests.TestDynamicObject();
+      o.Text = "Text!";
+      o.Integer = int.MaxValue;
+
+      string json = JsonConvert.SerializeObject(o, Formatting.Indented,
+        new JsonSerializerSettings
+        {
+          ContractResolver = new CamelCasePropertyNamesContractResolver()
+        });
+
+      Assert.AreEqual(@"{
+  ""text"": ""Text!"",
+  ""integer"": 2147483647,
+  ""int"": 0,
+  ""childObject"": null
+}", json);
+    }
+#endif
+
+    [Test]
+    public void DictionaryCamelCasePropertyNames()
+    {
+      Dictionary<string, string> values = new Dictionary<string, string>
+        {
+          {"First", "Value1!"},
+          {"Second", "Value2!"}
+        };
+
+      string json = JsonConvert.SerializeObject(values, Formatting.Indented,
+        new JsonSerializerSettings
+        {
+          ContractResolver = new CamelCasePropertyNamesContractResolver()
+        });
+
+      Assert.AreEqual(@"{
+  ""first"": ""Value1!"",
+  ""second"": ""Value2!""
+}", json);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/ConstructorHandlingTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/ConstructorHandlingTests.cs
new file mode 100644 (file)
index 0000000..463d475
--- /dev/null
@@ -0,0 +1,59 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using Newtonsoft.Json.Tests.TestObjects;
+using NUnit.Framework;
+
+namespace Newtonsoft.Json.Tests.Serialization
+{
+  public class ConstructorHandlingTests : TestFixtureBase
+  {
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "Unable to find a constructor to use for type Newtonsoft.Json.Tests.TestObjects.PrivateConstructorTestClass. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute.")]
+    public void FailWithPrivateConstructorAndDefault()
+    {
+      string json = @"{Name:""Name!""}";
+
+      JsonConvert.DeserializeObject<PrivateConstructorTestClass>(json);
+    }
+
+    [Test]
+    public void SuccessWithPrivateConstructorAndAllowNonPublic()
+    {
+      string json = @"{Name:""Name!""}";
+
+      PrivateConstructorTestClass c = JsonConvert.DeserializeObject<PrivateConstructorTestClass>(json,
+        new JsonSerializerSettings
+          {
+            ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
+          });
+      Assert.IsNotNull(c);
+      Assert.AreEqual("Name!", c.Name);
+    }
+
+    [Test]
+    [ExpectedException(typeof(TargetInvocationException))]
+    public void FailWithPrivateConstructorPlusParametizedAndDefault()
+    {
+      string json = @"{Name:""Name!""}";
+
+      PrivateConstructorWithPublicParametizedConstructorTestClass c = JsonConvert.DeserializeObject<PrivateConstructorWithPublicParametizedConstructorTestClass>(json);
+    }
+
+    [Test]
+    public void SuccessWithPrivateConstructorPlusParametizedAndAllowNonPublic()
+    {
+      string json = @"{Name:""Name!""}";
+
+      PrivateConstructorWithPublicParametizedConstructorTestClass c = JsonConvert.DeserializeObject<PrivateConstructorWithPublicParametizedConstructorTestClass>(json,
+        new JsonSerializerSettings
+        {
+          ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
+        });
+      Assert.IsNotNull(c);
+      Assert.AreEqual("Name!", c.Name);
+      Assert.AreEqual(1, c.Age);
+    }
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/ContractResolverTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/ContractResolverTests.cs
new file mode 100644 (file)
index 0000000..50897dc
--- /dev/null
@@ -0,0 +1,180 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using Newtonsoft.Json.Serialization;
+using Newtonsoft.Json.Tests.TestObjects;
+using System.Reflection;
+
+namespace Newtonsoft.Json.Tests.Serialization
+{
+  public class DynamicContractResolver : DefaultContractResolver
+  {
+    private readonly char _startingWithChar;
+    public DynamicContractResolver(char startingWithChar)
+      : base(false)
+    {
+      _startingWithChar = startingWithChar;
+    }
+
+    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
+    {
+      IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization);
+
+      // only serializer properties that start with the specified character
+      properties =
+        properties.Where(p => p.PropertyName.StartsWith(_startingWithChar.ToString())).ToList();
+
+      return properties;
+    }
+  }
+
+  public class Book
+  {
+    public string BookName { get; set; }
+    public decimal BookPrice { get; set; }
+    public string AuthorName { get; set; }
+    public int AuthorAge { get; set; }
+    public string AuthorCountry { get; set; }
+  }
+
+  public interface IPerson
+  {
+    string FirstName { get; set; }
+    string LastName { get; set; }
+    DateTime BirthDate { get; set; }
+  }
+
+  public class Employee : IPerson
+  {
+    public string FirstName { get; set; }
+    public string LastName { get; set; }
+    public DateTime BirthDate { get; set; }
+
+    public string Department { get; set; }
+    public string JobTitle { get; set; }
+  }
+
+  public class IPersonContractResolver : DefaultContractResolver
+  {
+    protected override JsonContract CreateContract(Type objectType)
+    {
+      if (objectType == typeof(Employee))
+        objectType = typeof(IPerson);
+
+      return base.CreateContract(objectType);
+    }
+  }
+
+  public class ContractResolverTests : TestFixtureBase
+  {
+    [Test]
+    public void SerializeInterface()
+    {
+      Employee employee = new Employee
+         {
+           BirthDate = new DateTime(1977, 12, 30, 1, 1, 1, DateTimeKind.Utc),
+           FirstName = "Maurice",
+           LastName = "Moss",
+           Department = "IT",
+           JobTitle = "Support"
+         };
+
+      string iPersonJson = JsonConvert.SerializeObject(employee, Formatting.Indented,
+        new JsonSerializerSettings { ContractResolver = new IPersonContractResolver() });
+
+      Assert.AreEqual(@"{
+  ""FirstName"": ""Maurice"",
+  ""LastName"": ""Moss"",
+  ""BirthDate"": ""\/Date(252291661000)\/""
+}", iPersonJson);
+    }
+
+    [Test]
+    public void SingleTypeWithMultipleContractResolvers()
+    {
+      Book book = new Book
+                    {
+                      BookName = "The Gathering Storm",
+                      BookPrice = 16.19m,
+                      AuthorName = "Brandon Sanderson",
+                      AuthorAge = 34,
+                      AuthorCountry = "United States of America"
+                    };
+
+      string startingWithA = JsonConvert.SerializeObject(book, Formatting.Indented,
+        new JsonSerializerSettings { ContractResolver = new DynamicContractResolver('A') });
+
+      // {
+      //   "AuthorName": "Brandon Sanderson",
+      //   "AuthorAge": 34,
+      //   "AuthorCountry": "United States of America"
+      // }
+
+      string startingWithB = JsonConvert.SerializeObject(book, Formatting.Indented,
+        new JsonSerializerSettings { ContractResolver = new DynamicContractResolver('B') });
+
+      // {
+      //   "BookName": "The Gathering Storm",
+      //   "BookPrice": 16.19
+      // }
+
+      Assert.AreEqual(@"{
+  ""AuthorName"": ""Brandon Sanderson"",
+  ""AuthorAge"": 34,
+  ""AuthorCountry"": ""United States of America""
+}", startingWithA);
+
+      Assert.AreEqual(@"{
+  ""BookName"": ""The Gathering Storm"",
+  ""BookPrice"": 16.19
+}", startingWithB);
+    }
+
+    [Test]
+    public void SerializeCompilerGeneratedMembers()
+    {
+      StructTest structTest = new StructTest
+        {
+          IntField = 1,
+          IntProperty = 2,
+          StringField = "Field",
+          StringProperty = "Property"
+        };
+
+      DefaultContractResolver skipCompilerGeneratedResolver = new DefaultContractResolver
+      {
+        DefaultMembersSearchFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public
+      };
+
+      string skipCompilerGeneratedJson = JsonConvert.SerializeObject(structTest, Formatting.Indented,
+        new JsonSerializerSettings { ContractResolver = skipCompilerGeneratedResolver });
+
+      Assert.AreEqual(@"{
+  ""StringField"": ""Field"",
+  ""IntField"": 1,
+  ""StringProperty"": ""Property"",
+  ""IntProperty"": 2
+}", skipCompilerGeneratedJson);
+
+      DefaultContractResolver includeCompilerGeneratedResolver = new DefaultContractResolver
+      {
+        DefaultMembersSearchFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public,
+        SerializeCompilerGeneratedMembers = true
+      };
+
+      string includeCompilerGeneratedJson = JsonConvert.SerializeObject(structTest, Formatting.Indented,
+        new JsonSerializerSettings { ContractResolver = includeCompilerGeneratedResolver });
+
+      Assert.AreEqual(@"{
+  ""StringField"": ""Field"",
+  ""IntField"": 1,
+  ""<StringProperty>k__BackingField"": ""Property"",
+  ""<IntProperty>k__BackingField"": 2,
+  ""StringProperty"": ""Property"",
+  ""IntProperty"": 2
+}", includeCompilerGeneratedJson);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/DefaultValueHandlingTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/DefaultValueHandlingTests.cs
new file mode 100644 (file)
index 0000000..24aee8e
--- /dev/null
@@ -0,0 +1,108 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Tests.TestObjects;
+using NUnit.Framework;
+
+namespace Newtonsoft.Json.Tests.Serialization
+{
+  public class DefaultValueHandlingTests : TestFixtureBase
+  {
+    [Test]
+    public void SerializeInvoice()
+    {
+      Invoice invoice = new Invoice
+      {
+        Company = "Acme Ltd.",
+        Amount = 50.0m,
+        Paid = false,
+        FollowUpDays = 30,
+        FollowUpEmailAddress = string.Empty,
+        PaidDate = null
+      };
+
+      string included = JsonConvert.SerializeObject(invoice,
+        Formatting.Indented,
+        new JsonSerializerSettings { });
+
+      // {
+      //   "Company": "Acme Ltd.",
+      //   "Amount": 50.0,
+      //   "Paid": false,
+      //   "PaidDate": null,
+      //   "FollowUpDays": 30,
+      //   "FollowUpEmailAddress": ""
+      // }
+
+      string ignored = JsonConvert.SerializeObject(invoice,
+        Formatting.Indented,
+        new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore });
+
+      // {
+      //   "Company": "Acme Ltd.",
+      //   "Amount": 50.0
+      // }
+
+      Console.WriteLine(included);
+      Console.WriteLine(ignored);
+    }
+
+    [Test]
+    public void DefaultValueAttributeTest()
+    {
+      string json = JsonConvert.SerializeObject(new DefaultValueAttributeTestClass(),
+        Formatting.None, new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore });
+      Assert.AreEqual(@"{""TestField1"":0,""TestProperty1"":null}", json);
+
+      json = JsonConvert.SerializeObject(new DefaultValueAttributeTestClass { TestField1 = int.MinValue, TestProperty1 = "NotDefault" },
+        Formatting.None, new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore });
+      Assert.AreEqual(@"{""TestField1"":-2147483648,""TestProperty1"":""NotDefault""}", json);
+
+      json = JsonConvert.SerializeObject(new DefaultValueAttributeTestClass { TestField1 = 21, TestProperty1 = "NotDefault" },
+        Formatting.None, new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore });
+      Assert.AreEqual(@"{""TestProperty1"":""NotDefault""}", json);
+
+      json = JsonConvert.SerializeObject(new DefaultValueAttributeTestClass { TestField1 = 21, TestProperty1 = "TestProperty1Value" },
+        Formatting.None, new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore });
+      Assert.AreEqual(@"{}", json);
+    }
+
+    [JsonObject]
+    public class NetworkUser
+    {
+      [JsonProperty(PropertyName = "userId")]
+      [DefaultValue(-1)]
+      public long GlobalId { get; set; }
+
+      [JsonProperty(PropertyName = "floatUserId")]
+      [DefaultValue(-1.0d)]
+      public float FloatGlobalId { get; set; }
+
+      [JsonProperty(PropertyName = "firstName")]
+      public string Firstname { get; set; }
+      [JsonProperty(PropertyName = "lastName")]
+      public string Lastname { get; set; }
+
+      public NetworkUser()
+      {
+        GlobalId = -1;
+        FloatGlobalId = -1.0f;
+      }
+    }
+
+    [Test]
+    public void IgnoreNumberTypeDifferencesWithDefaultValue()
+    {
+      NetworkUser user = new NetworkUser
+      {
+        Firstname = "blub"
+      };
+
+      string json = JsonConvert.SerializeObject(user, Formatting.None, new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore, NullValueHandling = NullValueHandling.Ignore });
+
+      Assert.AreEqual(@"{""firstName"":""blub""}", json);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/DynamicTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/DynamicTests.cs
new file mode 100644 (file)
index 0000000..3d93a23
--- /dev/null
@@ -0,0 +1,285 @@
+#if !(NET35 || NET20)
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Dynamic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Runtime.CompilerServices;
+using System.Runtime.Serialization.Formatters;
+using System.Text;
+using Newtonsoft.Json.Serialization;
+using Newtonsoft.Json.Tests.TestObjects;
+using Newtonsoft.Json.Utilities;
+using NUnit.Framework;
+
+namespace Newtonsoft.Json.Tests.Serialization
+{
+  public class DynamicTests : TestFixtureBase
+  {
+    public class DynamicChildObject
+    {
+      public string Text { get; set; }
+      public int Integer { get; set; }
+    }
+
+    public class TestDynamicObject : DynamicObject
+    {
+      private readonly Dictionary<string, object> _members;
+
+      public int Int;
+      public DynamicChildObject ChildObject { get; set; }
+
+      internal Dictionary<string, object> Members
+      {
+        get { return _members; }
+      }
+
+      public TestDynamicObject()
+      {
+        _members = new Dictionary<string, object>();
+      }
+
+      public override IEnumerable<string> GetDynamicMemberNames()
+      {
+        return _members.Keys.Union(new[] { "Int", "ChildObject" });
+      }
+
+      public override bool TryConvert(ConvertBinder binder, out object result)
+      {
+        Type targetType = binder.Type;
+
+        if (targetType == typeof(IDictionary<string, object>) ||
+            targetType == typeof(IDictionary))
+        {
+          result = new Dictionary<string, object>(_members);
+          return true;
+        }
+        else
+        {
+          return base.TryConvert(binder, out result);
+        }
+      }
+
+      public override bool TryDeleteMember(DeleteMemberBinder binder)
+      {
+        return _members.Remove(binder.Name);
+      }
+
+      public override bool TryGetMember(GetMemberBinder binder, out object result)
+      {
+        return _members.TryGetValue(binder.Name, out result);
+      }
+
+      public override bool TrySetMember(SetMemberBinder binder, object value)
+      {
+        _members[binder.Name] = value;
+        return true;
+      }
+    }
+
+    public class ErrorSettingDynamicObject : DynamicObject
+    {
+      public override bool TrySetMember(SetMemberBinder binder, object value)
+      {
+        return false;
+      }
+    }
+
+    [Test]
+    public void SerializeDynamicObject()
+    {
+      TestDynamicObject dynamicObject = new TestDynamicObject();
+
+      dynamic d = dynamicObject;
+      d.Int = 1;
+      d.Decimal = 99.9d;
+      d.ChildObject = new DynamicChildObject();
+
+      Dictionary<string, object> values = new Dictionary<string, object>();
+
+      foreach (string memberName in dynamicObject.GetDynamicMemberNames())
+      {
+        object value;
+        dynamicObject.TryGetMember(memberName, out value);
+
+        values.Add(memberName, value);
+      }
+
+      Assert.AreEqual(d.Int, values["Int"]);
+      Assert.AreEqual(d.Decimal, values["Decimal"]);
+      Assert.AreEqual(d.ChildObject, values["ChildObject"]);
+
+      string json = JsonConvert.SerializeObject(dynamicObject, Formatting.Indented);
+      Assert.AreEqual(@"{
+  ""Decimal"": 99.9,
+  ""Int"": 1,
+  ""ChildObject"": {
+    ""Text"": null,
+    ""Integer"": 0
+  }
+}", json);
+
+      TestDynamicObject newDynamicObject = JsonConvert.DeserializeObject<TestDynamicObject>(json);
+      d = newDynamicObject;
+
+      Assert.AreEqual(99.9, d.Decimal);
+      Assert.AreEqual(1, d.Int);
+      Assert.AreEqual(dynamicObject.ChildObject.Integer, d.ChildObject.Integer);
+      Assert.AreEqual(dynamicObject.ChildObject.Text, d.ChildObject.Text);
+    }
+
+    [Test]
+    public void sdfsdf()
+    {
+      ErrorSettingDynamicObject d = JsonConvert.DeserializeObject<ErrorSettingDynamicObject>("{'hi':5}");
+    }
+
+    [Test]
+    public void SerializeDynamicObjectWithObjectTracking()
+    {
+      dynamic o = new ExpandoObject();
+      o.Text = "Text!";
+      o.Integer = int.MaxValue;
+      o.DynamicChildObject = new DynamicChildObject
+        {
+          Integer = int.MinValue,
+          Text = "Child text!"
+        };
+
+      string json = JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings
+        {
+          TypeNameHandling = TypeNameHandling.All,
+          TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
+        });
+
+      Console.WriteLine(json);
+
+      string dynamicChildObjectTypeName = ReflectionUtils.GetTypeName(typeof(DynamicChildObject), FormatterAssemblyStyle.Full);
+      string expandoObjectTypeName = ReflectionUtils.GetTypeName(typeof(ExpandoObject), FormatterAssemblyStyle.Full);
+
+      Assert.AreEqual(@"{
+  ""$type"": """ + expandoObjectTypeName + @""",
+  ""Text"": ""Text!"",
+  ""Integer"": 2147483647,
+  ""DynamicChildObject"": {
+    ""$type"": """ + dynamicChildObjectTypeName + @""",
+    ""Text"": ""Child text!"",
+    ""Integer"": -2147483648
+  }
+}", json);
+
+      dynamic n = JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings
+        {
+          TypeNameHandling = TypeNameHandling.All,
+          TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
+        });
+
+      Assert.IsInstanceOfType(typeof(ExpandoObject), n);
+      Assert.AreEqual("Text!", n.Text);
+      Assert.AreEqual(int.MaxValue, n.Integer);
+
+      Assert.IsInstanceOfType(typeof(DynamicChildObject), n.DynamicChildObject);
+      Assert.AreEqual("Child text!", n.DynamicChildObject.Text);
+      Assert.AreEqual(int.MinValue, n.DynamicChildObject.Integer);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "Unable to find a default constructor to use for type System.Dynamic.DynamicObject.")]
+    public void NoPublicDefaultConstructor()
+    {
+      var settings = new JsonSerializerSettings();
+      settings.NullValueHandling = NullValueHandling.Ignore;
+      var json = @"{
+  ""contributors"": null
+}";
+      
+      JsonConvert.DeserializeObject<DynamicObject>(json, settings);
+    }
+
+    public class DictionaryDynamicObject : DynamicObject
+    {
+      public IDictionary<string, object> Values { get; private set; }
+
+      protected DictionaryDynamicObject()
+      {
+        Values = new Dictionary<string, object>();
+      }
+
+      public override bool TrySetMember(SetMemberBinder binder, object value)
+      {
+        Values[binder.Name] = value;
+        return true;
+      }
+    }
+
+    [Test]
+    public void AllowNonPublicDefaultConstructor()
+    {
+      var settings = new JsonSerializerSettings();
+      settings.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor;
+
+      var json = @"{
+  ""contributors"": null,
+  ""retweeted"": false,
+  ""text"": ""Guys SX4 diesel is launched.what are your plans?catch us at #facebook http://bit.ly/dV3H1a #auto #car #maruti #india #delhi"",
+  ""in_reply_to_user_id_str"": null,
+  ""retweet_count"": 0,
+  ""geo"": null,
+  ""id_str"": ""40678260320768000"",
+  ""in_reply_to_status_id"": null,
+  ""source"": ""<a href=\""http://www.tweetdeck.com\"" rel=\""nofollow\"">TweetDeck</a>"",
+  ""created_at"": ""Thu Feb 24 07:43:47 +0000 2011"",
+  ""place"": null,
+  ""coordinates"": null,
+  ""truncated"": false,
+  ""favorited"": false,
+  ""user"": {
+    ""profile_background_image_url"": ""http://a1.twimg.com/profile_background_images/206944715/twitter_bg.jpg"",
+    ""url"": ""http://bit.ly/dcFwWC"",
+    ""screen_name"": ""marutisuzukisx4"",
+    ""verified"": false,
+    ""friends_count"": 45,
+    ""description"": ""This is the Official Maruti Suzuki SX4 Twitter ID! Men are Back - mail us on social (at) sx4bymaruti (dot) com"",
+    ""follow_request_sent"": null,
+    ""time_zone"": ""Chennai"",
+    ""profile_text_color"": ""333333"",
+    ""location"": ""India"",
+    ""notifications"": null,
+    ""profile_sidebar_fill_color"": ""efefef"",
+    ""id_str"": ""196143889"",
+    ""contributors_enabled"": false,
+    ""lang"": ""en"",
+    ""profile_background_tile"": false,
+    ""created_at"": ""Tue Sep 28 12:55:15 +0000 2010"",
+    ""followers_count"": 117,
+    ""show_all_inline_media"": true,
+    ""listed_count"": 1,
+    ""geo_enabled"": true,
+    ""profile_link_color"": ""009999"",
+    ""profile_sidebar_border_color"": ""eeeeee"",
+    ""protected"": false,
+    ""name"": ""Maruti Suzuki SX4"",
+    ""statuses_count"": 637,
+    ""following"": null,
+    ""profile_use_background_image"": true,
+    ""profile_image_url"": ""http://a3.twimg.com/profile_images/1170694644/Slide1_normal.JPG"",
+    ""id"": 196143889,
+    ""is_translator"": false,
+    ""utc_offset"": 19800,
+    ""favourites_count"": 0,
+    ""profile_background_color"": ""131516""
+  },
+  ""in_reply_to_screen_name"": null,
+  ""id"": 40678260320768000,
+  ""in_reply_to_status_id_str"": null,
+  ""in_reply_to_user_id"": null
+}";
+
+      DictionaryDynamicObject foo = JsonConvert.DeserializeObject<DictionaryDynamicObject>(json, settings);
+
+      Assert.AreEqual(false, foo.Values["retweeted"]);
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/EntitiesSerializationTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/EntitiesSerializationTests.cs
new file mode 100644 (file)
index 0000000..7731482
--- /dev/null
@@ -0,0 +1,314 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+#if !(NET35 || NET20 || SILVERLIGHT)
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Converters;
+using NUnit.Framework;
+
+namespace Newtonsoft.Json.Tests.Serialization
+{
+  public class EntitiesSerializationTests : TestFixtureBase
+  {
+    [Test]
+    public void SerializeEntity()
+    {
+      Folder rootFolder = CreateEntitiesTestData();
+
+      string json = JsonConvert.SerializeObject(rootFolder, Formatting.Indented, new IsoDateTimeConverter());
+
+      string expected = @"{
+  ""$id"": ""1"",
+  ""FolderId"": ""a4e8ba80-eb24-4591-bb1c-62d3ad83701e"",
+  ""Name"": ""Root folder"",
+  ""Description"": ""Description!"",
+  ""CreatedDate"": ""2000-12-10T10:50:00Z"",
+  ""Files"": [],
+  ""ChildFolders"": [
+    {
+      ""$id"": ""2"",
+      ""FolderId"": ""484936e2-7cbb-4592-93ff-b2103e5705e4"",
+      ""Name"": ""Child folder"",
+      ""Description"": ""Description!"",
+      ""CreatedDate"": ""2001-11-20T10:50:00Z"",
+      ""Files"": [
+        {
+          ""$id"": ""3"",
+          ""FileId"": ""cc76d734-49f1-4616-bb38-41514228ac6c"",
+          ""Name"": ""File 1"",
+          ""Description"": ""Description!"",
+          ""CreatedDate"": ""2002-10-30T10:50:00Z"",
+          ""Folder"": {
+            ""$ref"": ""2""
+          },
+          ""EntityKey"": {
+            ""$id"": ""4"",
+            ""EntitySetName"": ""File"",
+            ""EntityContainerName"": ""DataServicesTestDatabaseEntities"",
+            ""EntityKeyValues"": [
+              {
+                ""Key"": ""FileId"",
+                ""Type"": ""System.Guid"",
+                ""Value"": ""cc76d734-49f1-4616-bb38-41514228ac6c""
+              }
+            ]
+          }
+        }
+      ],
+      ""ChildFolders"": [],
+      ""ParentFolder"": {
+        ""$ref"": ""1""
+      },
+      ""EntityKey"": {
+        ""$id"": ""5"",
+        ""EntitySetName"": ""Folder"",
+        ""EntityContainerName"": ""DataServicesTestDatabaseEntities"",
+        ""EntityKeyValues"": [
+          {
+            ""Key"": ""FolderId"",
+            ""Type"": ""System.Guid"",
+            ""Value"": ""484936e2-7cbb-4592-93ff-b2103e5705e4""
+          }
+        ]
+      }
+    }
+  ],
+  ""ParentFolder"": null,
+  ""EntityKey"": {
+    ""$id"": ""6"",
+    ""EntitySetName"": ""Folder"",
+    ""EntityContainerName"": ""DataServicesTestDatabaseEntities"",
+    ""EntityKeyValues"": [
+      {
+        ""Key"": ""FolderId"",
+        ""Type"": ""System.Guid"",
+        ""Value"": ""a4e8ba80-eb24-4591-bb1c-62d3ad83701e""
+      }
+    ]
+  }
+}";
+
+      Assert.AreEqual(expected, json);
+    }
+
+    [Test]
+    public void DeserializeEntity()
+    {
+      string json = @"{
+  ""$id"": ""1"",
+  ""FolderId"": ""a4e8ba80-eb24-4591-bb1c-62d3ad83701e"",
+  ""Name"": ""Root folder"",
+  ""Description"": ""Description!"",
+  ""CreatedDate"": ""2000-12-10T10:50:00Z"",
+  ""Files"": [],
+  ""ChildFolders"": [
+    {
+      ""$id"": ""2"",
+      ""FolderId"": ""484936e2-7cbb-4592-93ff-b2103e5705e4"",
+      ""Name"": ""Child folder"",
+      ""Description"": ""Description!"",
+      ""CreatedDate"": ""2001-11-20T10:50:00Z"",
+      ""Files"": [
+        {
+          ""$id"": ""3"",
+          ""FileId"": ""cc76d734-49f1-4616-bb38-41514228ac6c"",
+          ""Name"": ""File 1"",
+          ""Description"": ""Description!"",
+          ""CreatedDate"": ""2002-10-30T10:50:00Z"",
+          ""Folder"": {
+            ""$ref"": ""2""
+          },
+          ""EntityKey"": {
+            ""$id"": ""4"",
+            ""EntitySetName"": ""File"",
+            ""EntityContainerName"": ""DataServicesTestDatabaseEntities"",
+            ""EntityKeyValues"": [
+              {
+                ""Key"": ""FileId"",
+                ""Type"": ""System.Guid"",
+                ""Value"": ""cc76d734-49f1-4616-bb38-41514228ac6c""
+              }
+            ]
+          }
+        }
+      ],
+      ""ChildFolders"": [],
+      ""ParentFolder"": {
+        ""$ref"": ""1""
+      },
+      ""EntityKey"": {
+        ""$id"": ""5"",
+        ""EntitySetName"": ""Folder"",
+        ""EntityContainerName"": ""DataServicesTestDatabaseEntities"",
+        ""EntityKeyValues"": [
+          {
+            ""Key"": ""FolderId"",
+            ""Type"": ""System.Guid"",
+            ""Value"": ""484936e2-7cbb-4592-93ff-b2103e5705e4""
+          }
+        ]
+      }
+    }
+  ],
+  ""ParentFolder"": null,
+  ""EntityKey"": {
+    ""$id"": ""6"",
+    ""EntitySetName"": ""Folder"",
+    ""EntityContainerName"": ""DataServicesTestDatabaseEntities"",
+    ""EntityKeyValues"": [
+      {
+        ""Key"": ""FolderId"",
+        ""Type"": ""System.Guid"",
+        ""Value"": ""a4e8ba80-eb24-4591-bb1c-62d3ad83701e""
+      }
+    ]
+  }
+}";
+
+      Folder f = JsonConvert.DeserializeObject<Folder>(json, new IsoDateTimeConverter());
+
+      Assert.IsNotNull(f);
+      Assert.AreEqual(new Guid("A4E8BA80-EB24-4591-BB1C-62D3AD83701E"), f.FolderId);
+      Assert.AreEqual("Folder", f.EntityKey.EntitySetName);
+      Assert.AreEqual("DataServicesTestDatabaseEntities", f.EntityKey.EntityContainerName);
+      Assert.AreEqual("Folder", f.EntityKey.EntitySetName);
+      Assert.AreEqual(false, f.EntityKey.IsTemporary);
+      Assert.AreEqual(1, f.EntityKey.EntityKeyValues.Length);
+      Assert.AreEqual("FolderId", f.EntityKey.EntityKeyValues[0].Key);
+      Assert.AreEqual(new Guid("A4E8BA80-EB24-4591-BB1C-62D3AD83701E"), f.EntityKey.EntityKeyValues[0].Value);
+      Assert.AreEqual("Root folder", f.Name);
+      Assert.AreEqual(new DateTime(2000, 12, 10, 10, 50, 0, DateTimeKind.Utc), f.CreatedDate);
+      Assert.AreEqual(null, f.ParentFolder);
+      Assert.AreEqual(1, f.ChildFolders.Count);
+
+      Folder childFolder = f.ChildFolders.ElementAt(0);
+
+      Assert.AreEqual("Child folder", childFolder.Name);
+      Assert.AreEqual("Description!", childFolder.Description);
+      Assert.AreEqual(f, childFolder.ParentFolder);
+      Assert.AreEqual(f, childFolder.ParentFolderReference.Value);
+      // is this a problem?
+      Assert.AreEqual(null, childFolder.ParentFolderReference.EntityKey);
+    }
+
+    [Test]
+    public void SerializeMultiValueEntityKey()
+    {
+      EntityKey e = new EntityKey("DataServicesTestDatabaseEntities.Folder",
+                                  new List<EntityKeyMember>
+                                    {
+                                      new EntityKeyMember("GuidId", new Guid("A4E8BA80-EB24-4591-BB1C-62D3AD83701E")),
+                                      new EntityKeyMember("IntId", int.MaxValue),
+                                      new EntityKeyMember("LongId", long.MaxValue),
+                                      new EntityKeyMember("StringId", "String!"),
+                                      new EntityKeyMember("DateTimeId", new DateTime(2000, 12, 10, 10, 50, 0, DateTimeKind.Utc))
+                                    });
+
+      string json = JsonConvert.SerializeObject(e, Formatting.Indented);
+
+      Assert.AreEqual(@"{
+  ""$id"": ""1"",
+  ""EntitySetName"": ""Folder"",
+  ""EntityContainerName"": ""DataServicesTestDatabaseEntities"",
+  ""EntityKeyValues"": [
+    {
+      ""Key"": ""GuidId"",
+      ""Type"": ""System.Guid"",
+      ""Value"": ""a4e8ba80-eb24-4591-bb1c-62d3ad83701e""
+    },
+    {
+      ""Key"": ""IntId"",
+      ""Type"": ""System.Int32"",
+      ""Value"": ""2147483647""
+    },
+    {
+      ""Key"": ""LongId"",
+      ""Type"": ""System.Int64"",
+      ""Value"": ""9223372036854775807""
+    },
+    {
+      ""Key"": ""StringId"",
+      ""Type"": ""System.String"",
+      ""Value"": ""String!""
+    },
+    {
+      ""Key"": ""DateTimeId"",
+      ""Type"": ""System.DateTime"",
+      ""Value"": ""12/10/2000 10:50:00""
+    }
+  ]
+}", json);
+
+      EntityKey newKey = JsonConvert.DeserializeObject<EntityKey>(json);
+      Assert.IsFalse(ReferenceEquals(e, newKey));
+
+      Assert.AreEqual(5, newKey.EntityKeyValues.Length);
+      Assert.AreEqual("GuidId", newKey.EntityKeyValues[0].Key);
+      Assert.AreEqual(new Guid("A4E8BA80-EB24-4591-BB1C-62D3AD83701E"), newKey.EntityKeyValues[0].Value);
+      Assert.AreEqual("IntId", newKey.EntityKeyValues[1].Key);
+      Assert.AreEqual(int.MaxValue, newKey.EntityKeyValues[1].Value);
+      Assert.AreEqual("LongId", newKey.EntityKeyValues[2].Key);
+      Assert.AreEqual(long.MaxValue, newKey.EntityKeyValues[2].Value);
+      Assert.AreEqual("StringId", newKey.EntityKeyValues[3].Key);
+      Assert.AreEqual("String!", newKey.EntityKeyValues[3].Value);
+      Assert.AreEqual("DateTimeId", newKey.EntityKeyValues[4].Key);
+      Assert.AreEqual(new DateTime(2000, 12, 10, 10, 50, 0, DateTimeKind.Utc), newKey.EntityKeyValues[4].Value);
+    }
+
+    private Folder CreateEntitiesTestData()
+    {
+      Folder folder = new Folder();
+      folder.FolderId = new Guid("A4E8BA80-EB24-4591-BB1C-62D3AD83701E");
+      folder.EntityKey = new EntityKey("DataServicesTestDatabaseEntities.Folder", "FolderId", folder.FolderId);
+      folder.Name = "Root folder";
+      folder.Description = "Description!";
+      folder.CreatedDate = new DateTime(2000, 12, 10, 10, 50, 0, DateTimeKind.Utc);
+      
+      Folder childFolder = new Folder();
+      childFolder.FolderId = new Guid("484936E2-7CBB-4592-93FF-B2103E5705E4");
+      childFolder.EntityKey = new EntityKey("DataServicesTestDatabaseEntities.Folder", "FolderId", childFolder.FolderId);
+      childFolder.Name = "Child folder";
+      childFolder.Description = "Description!";
+      childFolder.CreatedDate = new DateTime(2001, 11, 20, 10, 50, 0, DateTimeKind.Utc);
+
+      folder.ChildFolders.Add(childFolder);
+
+      File file1 = new File();
+      file1.FileId = new Guid("CC76D734-49F1-4616-BB38-41514228AC6C");
+      file1.EntityKey = new EntityKey("DataServicesTestDatabaseEntities.File", "FileId", file1.FileId);
+      file1.Name = "File 1";
+      file1.Description = "Description!";
+      file1.CreatedDate = new DateTime(2002, 10, 30, 10, 50, 0, DateTimeKind.Utc);
+
+      childFolder.Files.Add(file1);
+      return folder;
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs
new file mode 100644 (file)
index 0000000..25d05eb
--- /dev/null
@@ -0,0 +1,4314 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+#if !SILVERLIGHT && !PocketPC && !NET20
+using System.ComponentModel.DataAnnotations;
+using System.Configuration;
+using System.Runtime.CompilerServices;
+using System.Threading;
+using System.Web.Script.Serialization;
+#endif
+using System.Text;
+using NUnit.Framework;
+using Newtonsoft.Json;
+using System.IO;
+using System.Collections;
+using System.Xml;
+using System.Xml.Serialization;
+using System.Collections.ObjectModel;
+using Newtonsoft.Json.Linq;
+using System.Linq;
+using Newtonsoft.Json.Converters;
+#if !PocketPC && !NET20 && !WINDOWS_PHONE
+using System.Runtime.Serialization.Json;
+#endif
+using Newtonsoft.Json.Tests.TestObjects;
+using System.Runtime.Serialization;
+using System.Globalization;
+using Newtonsoft.Json.Utilities;
+using System.Reflection;
+#if !NET20 && !SILVERLIGHT
+using System.Xml.Linq;
+using System.Text.RegularExpressions;
+using System.Collections.Specialized;
+using System.Linq.Expressions;
+#endif
+#if !(NET35 || NET20 || WINDOWS_PHONE)
+using System.Dynamic;
+using System.ComponentModel;
+#endif
+
+namespace Newtonsoft.Json.Tests.Serialization
+{
+  public class JsonSerializerTest : TestFixtureBase
+  {
+    [Test]
+    public void PersonTypedObjectDeserialization()
+    {
+      Store store = new Store();
+
+      string jsonText = JsonConvert.SerializeObject(store);
+
+      Store deserializedStore = (Store)JsonConvert.DeserializeObject(jsonText, typeof(Store));
+
+      Assert.AreEqual(store.Establised, deserializedStore.Establised);
+      Assert.AreEqual(store.product.Count, deserializedStore.product.Count);
+
+      Console.WriteLine(jsonText);
+    }
+
+    [Test]
+    public void TypedObjectDeserialization()
+    {
+      Product product = new Product();
+
+      product.Name = "Apple";
+      product.ExpiryDate = new DateTime(2008, 12, 28);
+      product.Price = 3.99M;
+      product.Sizes = new string[] { "Small", "Medium", "Large" };
+
+      string output = JsonConvert.SerializeObject(product);
+      //{
+      //  "Name": "Apple",
+      //  "ExpiryDate": "\/Date(1230375600000+1300)\/",
+      //  "Price": 3.99,
+      //  "Sizes": [
+      //    "Small",
+      //    "Medium",
+      //    "Large"
+      //  ]
+      //}
+
+      Product deserializedProduct = (Product)JsonConvert.DeserializeObject(output, typeof(Product));
+
+      Assert.AreEqual("Apple", deserializedProduct.Name);
+      Assert.AreEqual(new DateTime(2008, 12, 28), deserializedProduct.ExpiryDate);
+      Assert.AreEqual(3.99, deserializedProduct.Price);
+      Assert.AreEqual("Small", deserializedProduct.Sizes[0]);
+      Assert.AreEqual("Medium", deserializedProduct.Sizes[1]);
+      Assert.AreEqual("Large", deserializedProduct.Sizes[2]);
+    }
+
+    //[Test]
+    //public void Advanced()
+    //{
+    //  Product product = new Product();
+    //  product.ExpiryDate = new DateTime(2008, 12, 28);
+
+    //  JsonSerializer serializer = new JsonSerializer();
+    //  serializer.Converters.Add(new JavaScriptDateTimeConverter());
+    //  serializer.NullValueHandling = NullValueHandling.Ignore;
+
+    //  using (StreamWriter sw = new StreamWriter(@"c:\json.txt"))
+    //  using (JsonWriter writer = new JsonTextWriter(sw))
+    //  {
+    //    serializer.Serialize(writer, product);
+    //    // {"ExpiryDate":new Date(1230375600000),"Price":0}
+    //  }
+    //}
+
+    [Test]
+    public void JsonConvertSerializer()
+    {
+      string value = @"{""Name"":""Orange"", ""Price"":3.99, ""ExpiryDate"":""01/24/2010 12:00:00""}";
+
+      Product p = JsonConvert.DeserializeObject(value, typeof(Product)) as Product;
+
+      Assert.AreEqual("Orange", p.Name);
+      Assert.AreEqual(new DateTime(2010, 1, 24, 12, 0, 0), p.ExpiryDate);
+      Assert.AreEqual(3.99, p.Price);
+    }
+
+    [Test]
+    public void DeserializeJavaScriptDate()
+    {
+      DateTime dateValue = new DateTime(2010, 3, 30);
+      Dictionary<string, object> testDictionary = new Dictionary<string, object>();
+      testDictionary["date"] = dateValue;
+
+      string jsonText = JsonConvert.SerializeObject(testDictionary);
+
+#if !PocketPC && !NET20 && !WINDOWS_PHONE
+      MemoryStream ms = new MemoryStream();
+      DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Dictionary<string, object>));
+      serializer.WriteObject(ms, testDictionary);
+
+      byte[] data = ms.ToArray();
+      string output = Encoding.UTF8.GetString(data, 0, data.Length);
+#endif
+
+      Dictionary<string, object> deserializedDictionary = (Dictionary<string, object>)JsonConvert.DeserializeObject(jsonText, typeof(Dictionary<string, object>));
+      DateTime deserializedDate = (DateTime)deserializedDictionary["date"];
+
+      Assert.AreEqual(dateValue, deserializedDate);
+
+      Console.WriteLine("DeserializeJavaScriptDate");
+      Console.WriteLine(jsonText);
+      Console.WriteLine();
+      Console.WriteLine(jsonText);
+    }
+
+    [Test]
+    public void TestMethodExecutorObject()
+    {
+      MethodExecutorObject executorObject = new MethodExecutorObject();
+      executorObject.serverClassName = "BanSubs";
+      executorObject.serverMethodParams = new object[] { "21321546", "101", "1236", "D:\\1.txt" };
+      executorObject.clientGetResultFunction = "ClientBanSubsCB";
+
+      string output = JsonConvert.SerializeObject(executorObject);
+
+      MethodExecutorObject executorObject2 = JsonConvert.DeserializeObject(output, typeof(MethodExecutorObject)) as MethodExecutorObject;
+
+      Assert.AreNotSame(executorObject, executorObject2);
+      Assert.AreEqual(executorObject2.serverClassName, "BanSubs");
+      Assert.AreEqual(executorObject2.serverMethodParams.Length, 4);
+      Assert.Contains("101", executorObject2.serverMethodParams);
+      Assert.AreEqual(executorObject2.clientGetResultFunction, "ClientBanSubsCB");
+    }
+
+#if !SILVERLIGHT
+    [Test]
+    public void HashtableDeserialization()
+    {
+      string value = @"{""Name"":""Orange"", ""Price"":3.99, ""ExpiryDate"":""01/24/2010 12:00:00""}";
+
+      Hashtable p = JsonConvert.DeserializeObject(value, typeof(Hashtable)) as Hashtable;
+
+      Assert.AreEqual("Orange", p["Name"].ToString());
+    }
+
+    [Test]
+    public void TypedHashtableDeserialization()
+    {
+      string value = @"{""Name"":""Orange"", ""Hash"":{""ExpiryDate"":""01/24/2010 12:00:00"",""UntypedArray"":[""01/24/2010 12:00:00""]}}";
+
+      TypedSubHashtable p = JsonConvert.DeserializeObject(value, typeof(TypedSubHashtable)) as TypedSubHashtable;
+
+      Assert.AreEqual("01/24/2010 12:00:00", p.Hash["ExpiryDate"].ToString());
+      Assert.AreEqual(@"[
+  ""01/24/2010 12:00:00""
+]", p.Hash["UntypedArray"].ToString());
+    }
+#endif
+
+    [Test]
+    public void SerializeDeserializeGetOnlyProperty()
+    {
+      string value = JsonConvert.SerializeObject(new GetOnlyPropertyClass());
+
+      GetOnlyPropertyClass c = JsonConvert.DeserializeObject<GetOnlyPropertyClass>(value);
+
+      Assert.AreEqual(c.Field, "Field");
+      Assert.AreEqual(c.GetOnlyProperty, "GetOnlyProperty");
+    }
+
+    [Test]
+    public void SerializeDeserializeSetOnlyProperty()
+    {
+      string value = JsonConvert.SerializeObject(new SetOnlyPropertyClass());
+
+      SetOnlyPropertyClass c = JsonConvert.DeserializeObject<SetOnlyPropertyClass>(value);
+
+      Assert.AreEqual(c.Field, "Field");
+    }
+
+    [Test]
+    public void JsonIgnoreAttributeTest()
+    {
+      string json = JsonConvert.SerializeObject(new JsonIgnoreAttributeTestClass());
+
+      Assert.AreEqual(@"{""Field"":0,""Property"":21}", json);
+
+      JsonIgnoreAttributeTestClass c = JsonConvert.DeserializeObject<JsonIgnoreAttributeTestClass>(@"{""Field"":99,""Property"":-1,""IgnoredField"":-1,""IgnoredObject"":[1,2,3,4,5]}");
+
+      Assert.AreEqual(0, c.IgnoredField);
+      Assert.AreEqual(99, c.Field);
+    }
+
+    [Test]
+    public void GoogleSearchAPI()
+    {
+      string json = @"{
+    results:
+        [
+            {
+                GsearchResultClass:""GwebSearch"",
+                unescapedUrl : ""http://www.google.com/"",
+                url : ""http://www.google.com/"",
+                visibleUrl : ""www.google.com"",
+                cacheUrl : 
+""http://www.google.com/search?q=cache:zhool8dxBV4J:www.google.com"",
+                title : ""Google"",
+                titleNoFormatting : ""Google"",
+                content : ""Enables users to search the Web, Usenet, and 
+images. Features include PageRank,   caching and translation of 
+results, and an option to find similar pages.""
+            },
+            {
+                GsearchResultClass:""GwebSearch"",
+                unescapedUrl : ""http://news.google.com/"",
+                url : ""http://news.google.com/"",
+                visibleUrl : ""news.google.com"",
+                cacheUrl : 
+""http://www.google.com/search?q=cache:Va_XShOz_twJ:news.google.com"",
+                title : ""Google News"",
+                titleNoFormatting : ""Google News"",
+                content : ""Aggregated headlines and a search engine of many of the world's news sources.""
+            },
+            
+            {
+                GsearchResultClass:""GwebSearch"",
+                unescapedUrl : ""http://groups.google.com/"",
+                url : ""http://groups.google.com/"",
+                visibleUrl : ""groups.google.com"",
+                cacheUrl : 
+""http://www.google.com/search?q=cache:x2uPD3hfkn0J:groups.google.com"",
+                title : ""Google Groups"",
+                titleNoFormatting : ""Google Groups"",
+                content : ""Enables users to search and browse the Usenet 
+archives which consist of over 700   million messages, and post new 
+comments.""
+            },
+            
+            {
+                GsearchResultClass:""GwebSearch"",
+                unescapedUrl : ""http://maps.google.com/"",
+                url : ""http://maps.google.com/"",
+                visibleUrl : ""maps.google.com"",
+                cacheUrl : 
+""http://www.google.com/search?q=cache:dkf5u2twBXIJ:maps.google.com"",
+                title : ""Google Maps"",
+                titleNoFormatting : ""Google Maps"",
+                content : ""Provides directions, interactive maps, and 
+satellite/aerial imagery of the United   States. Can also search by 
+keyword such as type of business.""
+            }
+        ],
+        
+    adResults:
+        [
+            {
+                GsearchResultClass:""GwebSearch.ad"",
+                title : ""Gartner Symposium/ITxpo"",
+                content1 : ""Meet brilliant Gartner IT analysts"",
+                content2 : ""20-23 May 2007- Barcelona, Spain"",
+                url : 
+""http://www.google.com/url?sa=L&ai=BVualExYGRo3hD5ianAPJvejjD8-s6ye7kdTwArbI4gTAlrECEAEYASDXtMMFOAFQubWAjvr_____AWDXw_4EiAEBmAEAyAEBgAIB&num=1&q=http://www.gartner.com/it/sym/2007/spr8/spr8.jsp%3Fsrc%3D_spain_07_%26WT.srch%3D1&usg=__CxRH06E4Xvm9Muq13S4MgMtnziY="", 
+
+                impressionUrl : 
+""http://www.google.com/uds/css/ad-indicator-on.gif?ai=BVualExYGRo3hD5ianAPJvejjD8-s6ye7kdTwArbI4gTAlrECEAEYASDXtMMFOAFQubWAjvr_____AWDXw_4EiAEBmAEAyAEBgAIB"", 
+
+                unescapedUrl : 
+""http://www.google.com/url?sa=L&ai=BVualExYGRo3hD5ianAPJvejjD8-s6ye7kdTwArbI4gTAlrECEAEYASDXtMMFOAFQubWAjvr_____AWDXw_4EiAEBmAEAyAEBgAIB&num=1&q=http://www.gartner.com/it/sym/2007/spr8/spr8.jsp%3Fsrc%3D_spain_07_%26WT.srch%3D1&usg=__CxRH06E4Xvm9Muq13S4MgMtnziY="", 
+
+                visibleUrl : ""www.gartner.com""
+            }
+        ]
+}
+";
+      object o = JsonConvert.DeserializeObject(json);
+      string s = string.Empty;
+      s += s;
+    }
+
+    [Test]
+    public void TorrentDeserializeTest()
+    {
+      string jsonText = @"{
+"""":"""",
+""label"": [
+       [""SomeName"",6]
+],
+""torrents"": [
+       [""192D99A5C943555CB7F00A852821CF6D6DB3008A"",201,""filename.avi"",178311826,1000,178311826,72815250,408,1603,7,121430,""NameOfLabelPrevioslyDefined"",3,6,0,8,128954,-1,0],
+],
+""torrentc"": ""1816000723""
+}";
+
+      JObject o = (JObject)JsonConvert.DeserializeObject(jsonText);
+      Assert.AreEqual(4, o.Children().Count());
+
+      JToken torrentsArray = (JToken)o["torrents"];
+      JToken nestedTorrentsArray = (JToken)torrentsArray[0];
+      Assert.AreEqual(nestedTorrentsArray.Children().Count(), 19);
+    }
+
+    [Test]
+    public void JsonPropertyClassSerialize()
+    {
+      JsonPropertyClass test = new JsonPropertyClass();
+      test.Pie = "Delicious";
+      test.SweetCakesCount = int.MaxValue;
+
+      string jsonText = JsonConvert.SerializeObject(test);
+
+      Assert.AreEqual(@"{""pie"":""Delicious"",""pie1"":""PieChart!"",""sweet_cakes_count"":2147483647}", jsonText);
+
+      JsonPropertyClass test2 = JsonConvert.DeserializeObject<JsonPropertyClass>(jsonText);
+
+      Assert.AreEqual(test.Pie, test2.Pie);
+      Assert.AreEqual(test.SweetCakesCount, test2.SweetCakesCount);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"A member with the name 'pie' already exists on 'Newtonsoft.Json.Tests.TestObjects.BadJsonPropertyClass'. Use the JsonPropertyAttribute to specify another name.")]
+    public void BadJsonPropertyClassSerialize()
+    {
+      JsonConvert.SerializeObject(new BadJsonPropertyClass());
+    }
+
+    [Test]
+    public void InheritedListSerialize()
+    {
+      Article a1 = new Article("a1");
+      Article a2 = new Article("a2");
+
+      ArticleCollection articles1 = new ArticleCollection();
+      articles1.Add(a1);
+      articles1.Add(a2);
+
+      string jsonText = JsonConvert.SerializeObject(articles1);
+
+      ArticleCollection articles2 = JsonConvert.DeserializeObject<ArticleCollection>(jsonText);
+
+      Assert.AreEqual(articles1.Count, articles2.Count);
+      Assert.AreEqual(articles1[0].Name, articles2[0].Name);
+    }
+
+    [Test]
+    public void ReadOnlyCollectionSerialize()
+    {
+      ReadOnlyCollection<int> r1 = new ReadOnlyCollection<int>(new int[] { 0, 1, 2, 3, 4 });
+
+      string jsonText = JsonConvert.SerializeObject(r1);
+
+      ReadOnlyCollection<int> r2 = JsonConvert.DeserializeObject<ReadOnlyCollection<int>>(jsonText);
+
+      CollectionAssert.AreEqual(r1, r2);
+    }
+
+#if !PocketPC && !NET20 && !WINDOWS_PHONE
+    [Test]
+    public void Unicode()
+    {
+      string json = @"[""PRE\u003cPOST""]";
+
+      DataContractJsonSerializer s = new DataContractJsonSerializer(typeof(List<string>));
+      List<string> dataContractResult = (List<string>)s.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(json)));
+
+      List<string> jsonNetResult = JsonConvert.DeserializeObject<List<string>>(json);
+
+      Assert.AreEqual(1, jsonNetResult.Count);
+      Assert.AreEqual(dataContractResult[0], jsonNetResult[0]);
+    }
+
+    [Test]
+    public void BackslashEqivilence()
+    {
+      string json = @"[""vvv\/vvv\tvvv\""vvv\bvvv\nvvv\rvvv\\vvv\fvvv""]";
+
+#if !SILVERLIGHT
+      JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
+      List<string> javaScriptSerializerResult = javaScriptSerializer.Deserialize<List<string>>(json);
+#endif
+
+      DataContractJsonSerializer s = new DataContractJsonSerializer(typeof(List<string>));
+      List<string> dataContractResult = (List<string>)s.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(json)));
+
+      List<string> jsonNetResult = JsonConvert.DeserializeObject<List<string>>(json);
+
+      Assert.AreEqual(1, jsonNetResult.Count);
+      Assert.AreEqual(dataContractResult[0], jsonNetResult[0]);
+#if !SILVERLIGHT
+      Assert.AreEqual(javaScriptSerializerResult[0], jsonNetResult[0]);
+#endif
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonReaderException), ExpectedMessage = @"Bad JSON escape sequence: \j. Line 1, position 7.")]
+    public void InvalidBackslash()
+    {
+      string json = @"[""vvv\jvvv""]";
+
+      JsonConvert.DeserializeObject<List<string>>(json);
+    }
+
+    [Test]
+    public void DateTimeTest()
+    {
+      List<DateTime> testDates = new List<DateTime> {
+        new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Local),
+        new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Unspecified),
+        new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Utc),
+        new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Local),
+        new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Unspecified),
+        new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc),
+      };
+      string result;
+
+
+      MemoryStream ms = new MemoryStream();
+      DataContractJsonSerializer s = new DataContractJsonSerializer(typeof(List<DateTime>));
+      s.WriteObject(ms, testDates);
+      ms.Seek(0, SeekOrigin.Begin);
+      StreamReader sr = new StreamReader(ms);
+
+      string expected = sr.ReadToEnd();
+
+      result = JsonConvert.SerializeObject(testDates);
+      Assert.AreEqual(expected, result);
+    }
+
+    [Test]
+    public void DateTimeOffset()
+    {
+      List<DateTimeOffset> testDates = new List<DateTimeOffset> {
+        new DateTimeOffset(new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Utc)),
+        new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero),
+        new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(13)),
+        new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(-3.5)),
+      };
+
+      string result = JsonConvert.SerializeObject(testDates);
+      Assert.AreEqual(@"[""\/Date(-59011455539000+0000)\/"",""\/Date(946688461000+0000)\/"",""\/Date(946641661000+1300)\/"",""\/Date(946701061000-0330)\/""]", result);
+    }
+#endif
+
+    [Test]
+    public void NonStringKeyDictionary()
+    {
+      Dictionary<int, int> values = new Dictionary<int, int>();
+      values.Add(-5, 6);
+      values.Add(int.MinValue, int.MaxValue);
+
+      string json = JsonConvert.SerializeObject(values);
+
+      Assert.AreEqual(@"{""-5"":6,""-2147483648"":2147483647}", json);
+
+      Dictionary<int, int> newValues = JsonConvert.DeserializeObject<Dictionary<int, int>>(json);
+
+      CollectionAssert.AreEqual(values, newValues);
+    }
+
+    [Test]
+    public void AnonymousObjectSerialization()
+    {
+      var anonymous =
+        new
+        {
+          StringValue = "I am a string",
+          IntValue = int.MaxValue,
+          NestedAnonymous = new { NestedValue = byte.MaxValue },
+          NestedArray = new[] { 1, 2 },
+          Product = new Product() { Name = "TestProduct" }
+        };
+
+      string json = JsonConvert.SerializeObject(anonymous);
+      Assert.AreEqual(@"{""StringValue"":""I am a string"",""IntValue"":2147483647,""NestedAnonymous"":{""NestedValue"":255},""NestedArray"":[1,2],""Product"":{""Name"":""TestProduct"",""ExpiryDate"":""\/Date(946684800000)\/"",""Price"":0.0,""Sizes"":null}}", json);
+
+      anonymous = JsonConvert.DeserializeAnonymousType(json, anonymous);
+      Assert.AreEqual("I am a string", anonymous.StringValue);
+      Assert.AreEqual(int.MaxValue, anonymous.IntValue);
+      Assert.AreEqual(255, anonymous.NestedAnonymous.NestedValue);
+      Assert.AreEqual(2, anonymous.NestedArray.Length);
+      Assert.AreEqual(1, anonymous.NestedArray[0]);
+      Assert.AreEqual(2, anonymous.NestedArray[1]);
+      Assert.AreEqual("TestProduct", anonymous.Product.Name);
+    }
+
+    [Test]
+    public void CustomCollectionSerialization()
+    {
+      ProductCollection collection = new ProductCollection()
+      {
+        new Product() { Name = "Test1" },
+        new Product() { Name = "Test2" },
+        new Product() { Name = "Test3" }
+      };
+
+      JsonSerializer jsonSerializer = new JsonSerializer();
+      jsonSerializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
+
+      StringWriter sw = new StringWriter();
+
+      jsonSerializer.Serialize(sw, collection);
+
+      Assert.AreEqual(@"[{""Name"":""Test1"",""ExpiryDate"":""\/Date(946684800000)\/"",""Price"":0.0,""Sizes"":null},{""Name"":""Test2"",""ExpiryDate"":""\/Date(946684800000)\/"",""Price"":0.0,""Sizes"":null},{""Name"":""Test3"",""ExpiryDate"":""\/Date(946684800000)\/"",""Price"":0.0,""Sizes"":null}]",
+        sw.GetStringBuilder().ToString());
+
+      ProductCollection collectionNew = (ProductCollection)jsonSerializer.Deserialize(new JsonTextReader(new StringReader(sw.GetStringBuilder().ToString())), typeof(ProductCollection));
+
+      CollectionAssert.AreEqual(collection, collectionNew);
+    }
+
+    [Test]
+    public void SerializeObject()
+    {
+      string json = JsonConvert.SerializeObject(new object());
+      Assert.AreEqual("{}", json);
+    }
+
+    [Test]
+    public void SerializeNull()
+    {
+      string json = JsonConvert.SerializeObject(null);
+      Assert.AreEqual("null", json);
+    }
+
+    [Test]
+    public void CanDeserializeIntArrayWhenNotFirstPropertyInJson()
+    {
+      string json = "{foo:'hello',bar:[1,2,3]}";
+      ClassWithArray wibble = JsonConvert.DeserializeObject<ClassWithArray>(json);
+      Assert.AreEqual("hello", wibble.Foo);
+
+      Assert.AreEqual(4, wibble.Bar.Count);
+      Assert.AreEqual(int.MaxValue, wibble.Bar[0]);
+      Assert.AreEqual(1, wibble.Bar[1]);
+      Assert.AreEqual(2, wibble.Bar[2]);
+      Assert.AreEqual(3, wibble.Bar[3]);
+    }
+
+    [Test]
+    public void CanDeserializeIntArray_WhenArrayIsFirstPropertyInJson()
+    {
+      string json = "{bar:[1,2,3], foo:'hello'}";
+      ClassWithArray wibble = JsonConvert.DeserializeObject<ClassWithArray>(json);
+      Assert.AreEqual("hello", wibble.Foo);
+
+      Assert.AreEqual(4, wibble.Bar.Count);
+      Assert.AreEqual(int.MaxValue, wibble.Bar[0]);
+      Assert.AreEqual(1, wibble.Bar[1]);
+      Assert.AreEqual(2, wibble.Bar[2]);
+      Assert.AreEqual(3, wibble.Bar[3]);
+    }
+
+    [Test]
+    public void ObjectCreationHandlingReplace()
+    {
+      string json = "{bar:[1,2,3], foo:'hello'}";
+
+      JsonSerializer s = new JsonSerializer();
+      s.ObjectCreationHandling = ObjectCreationHandling.Replace;
+
+      ClassWithArray wibble = (ClassWithArray)s.Deserialize(new StringReader(json), typeof(ClassWithArray));
+
+      Assert.AreEqual("hello", wibble.Foo);
+
+      Assert.AreEqual(1, wibble.Bar.Count);
+    }
+
+    [Test]
+    public void CanDeserializeSerializedJson()
+    {
+      ClassWithArray wibble = new ClassWithArray();
+      wibble.Foo = "hello";
+      wibble.Bar.Add(1);
+      wibble.Bar.Add(2);
+      wibble.Bar.Add(3);
+      string json = JsonConvert.SerializeObject(wibble);
+
+      ClassWithArray wibbleOut = JsonConvert.DeserializeObject<ClassWithArray>(json);
+      Assert.AreEqual("hello", wibbleOut.Foo);
+
+      Assert.AreEqual(5, wibbleOut.Bar.Count);
+      Assert.AreEqual(int.MaxValue, wibbleOut.Bar[0]);
+      Assert.AreEqual(int.MaxValue, wibbleOut.Bar[1]);
+      Assert.AreEqual(1, wibbleOut.Bar[2]);
+      Assert.AreEqual(2, wibbleOut.Bar[3]);
+      Assert.AreEqual(3, wibbleOut.Bar[4]);
+    }
+
+    [Test]
+    public void SerializeConverableObjects()
+    {
+      string json = JsonConvert.SerializeObject(new ConverableMembers());
+
+      Assert.AreEqual(@"{""String"":""string"",""Int32"":2147483647,""UInt32"":4294967295,""Byte"":255,""SByte"":127,""Short"":32767,""UShort"":65535,""Long"":9223372036854775807,""ULong"":9223372036854775807,""Double"":1.7976931348623157E+308,""Float"":3.40282347E+38,""DBNull"":null,""Bool"":true,""Char"":""\u0000""}", json);
+
+      ConverableMembers c = JsonConvert.DeserializeObject<ConverableMembers>(json);
+      Assert.AreEqual("string", c.String);
+      Assert.AreEqual(double.MaxValue, c.Double);
+      Assert.AreEqual(DBNull.Value, c.DBNull);
+    }
+
+    [Test]
+    public void SerializeStack()
+    {
+      Stack<object> s = new Stack<object>();
+      s.Push(1);
+      s.Push(2);
+      s.Push(3);
+
+      string json = JsonConvert.SerializeObject(s);
+      Assert.AreEqual("[3,2,1]", json);
+    }
+
+    [Test]
+    public void GuidTest()
+    {
+      Guid guid = new Guid("BED7F4EA-1A96-11d2-8F08-00A0C9A6186D");
+
+      string json = JsonConvert.SerializeObject(new ClassWithGuid { GuidField = guid });
+      Assert.AreEqual(@"{""GuidField"":""bed7f4ea-1a96-11d2-8f08-00a0c9a6186d""}", json);
+
+      ClassWithGuid c = JsonConvert.DeserializeObject<ClassWithGuid>(json);
+      Assert.AreEqual(guid, c.GuidField);
+    }
+
+    [Test]
+    public void EnumTest()
+    {
+      string json = JsonConvert.SerializeObject(StringComparison.CurrentCultureIgnoreCase);
+      Assert.AreEqual(@"1", json);
+
+      StringComparison s = JsonConvert.DeserializeObject<StringComparison>(json);
+      Assert.AreEqual(StringComparison.CurrentCultureIgnoreCase, s);
+    }
+
+    public class ClassWithTimeSpan
+    {
+      public TimeSpan TimeSpanField;
+    }
+
+    [Test]
+    public void TimeSpanTest()
+    {
+      TimeSpan ts = new TimeSpan(00, 23, 59, 1);
+
+      string json = JsonConvert.SerializeObject(new ClassWithTimeSpan { TimeSpanField = ts }, Formatting.Indented);
+      Assert.AreEqual(@"{
+  ""TimeSpanField"": ""23:59:01""
+}", json);
+
+      ClassWithTimeSpan c = JsonConvert.DeserializeObject<ClassWithTimeSpan>(json);
+      Assert.AreEqual(ts, c.TimeSpanField);
+    }
+
+    [Test]
+    public void JsonIgnoreAttributeOnClassTest()
+    {
+      string json = JsonConvert.SerializeObject(new JsonIgnoreAttributeOnClassTestClass());
+
+      Assert.AreEqual(@"{""TheField"":0,""Property"":21}", json);
+
+      JsonIgnoreAttributeOnClassTestClass c = JsonConvert.DeserializeObject<JsonIgnoreAttributeOnClassTestClass>(@"{""TheField"":99,""Property"":-1,""IgnoredField"":-1}");
+
+      Assert.AreEqual(0, c.IgnoredField);
+      Assert.AreEqual(99, c.Field);
+    }
+
+#if !SILVERLIGHT
+    [Test]
+    public void SerializeArrayAsArrayList()
+    {
+      string jsonText = @"[3, ""somestring"",[1,2,3],{}]";
+      ArrayList o = JsonConvert.DeserializeObject<ArrayList>(jsonText);
+
+      Assert.AreEqual(4, o.Count);
+      Assert.AreEqual(3, ((JArray)o[2]).Count);
+      Assert.AreEqual(0, ((JObject)o[3]).Count);
+    }
+#endif
+
+    [Test]
+    public void SerializeMemberGenericList()
+    {
+      Name name = new Name("The Idiot in Next To Me");
+
+      PhoneNumber p1 = new PhoneNumber("555-1212");
+      PhoneNumber p2 = new PhoneNumber("444-1212");
+
+      name.pNumbers.Add(p1);
+      name.pNumbers.Add(p2);
+
+      string json = JsonConvert.SerializeObject(name, Formatting.Indented);
+
+      Assert.AreEqual(@"{
+  ""personsName"": ""The Idiot in Next To Me"",
+  ""pNumbers"": [
+    {
+      ""phoneNumber"": ""555-1212""
+    },
+    {
+      ""phoneNumber"": ""444-1212""
+    }
+  ]
+}", json);
+
+      Name newName = JsonConvert.DeserializeObject<Name>(json);
+
+      Assert.AreEqual("The Idiot in Next To Me", newName.personsName);
+
+      // not passed in as part of the constructor but assigned to pNumbers property
+      Assert.AreEqual(2, newName.pNumbers.Count);
+      Assert.AreEqual("555-1212", newName.pNumbers[0].phoneNumber);
+      Assert.AreEqual("444-1212", newName.pNumbers[1].phoneNumber);
+    }
+
+    [Test]
+    public void ConstructorCaseSensitivity()
+    {
+      ConstructorCaseSensitivityClass c = new ConstructorCaseSensitivityClass("param1", "Param1", "Param2");
+
+      string json = JsonConvert.SerializeObject(c);
+
+      ConstructorCaseSensitivityClass deserialized = JsonConvert.DeserializeObject<ConstructorCaseSensitivityClass>(json);
+
+      Assert.AreEqual("param1", deserialized.param1);
+      Assert.AreEqual("Param1", deserialized.Param1);
+      Assert.AreEqual("Param2", deserialized.Param2);
+    }
+
+    [Test]
+    public void SerializerShouldUseClassConverter()
+    {
+      ConverterPrecedenceClass c1 = new ConverterPrecedenceClass("!Test!");
+
+      string json = JsonConvert.SerializeObject(c1);
+      Assert.AreEqual(@"[""Class"",""!Test!""]", json);
+
+      ConverterPrecedenceClass c2 = JsonConvert.DeserializeObject<ConverterPrecedenceClass>(json);
+
+      Assert.AreEqual("!Test!", c2.TestValue);
+    }
+
+    [Test]
+    public void SerializerShouldUseClassConverterOverArgumentConverter()
+    {
+      ConverterPrecedenceClass c1 = new ConverterPrecedenceClass("!Test!");
+
+      string json = JsonConvert.SerializeObject(c1, new ArgumentConverterPrecedenceClassConverter());
+      Assert.AreEqual(@"[""Class"",""!Test!""]", json);
+
+      ConverterPrecedenceClass c2 = JsonConvert.DeserializeObject<ConverterPrecedenceClass>(json, new ArgumentConverterPrecedenceClassConverter());
+
+      Assert.AreEqual("!Test!", c2.TestValue);
+    }
+
+    [Test]
+    public void SerializerShouldUseMemberConverter()
+    {
+      DateTime testDate = new DateTime(JsonConvert.InitialJavaScriptDateTicks, DateTimeKind.Utc);
+      MemberConverterClass m1 = new MemberConverterClass { DefaultConverter = testDate, MemberConverter = testDate };
+
+      string json = JsonConvert.SerializeObject(m1);
+      Assert.AreEqual(@"{""DefaultConverter"":""\/Date(0)\/"",""MemberConverter"":""1970-01-01T00:00:00Z""}", json);
+
+      MemberConverterClass m2 = JsonConvert.DeserializeObject<MemberConverterClass>(json);
+
+      Assert.AreEqual(testDate, m2.DefaultConverter);
+      Assert.AreEqual(testDate, m2.MemberConverter);
+    }
+
+    [Test]
+    public void SerializerShouldUseMemberConverterOverArgumentConverter()
+    {
+      DateTime testDate = new DateTime(JsonConvert.InitialJavaScriptDateTicks, DateTimeKind.Utc);
+      MemberConverterClass m1 = new MemberConverterClass { DefaultConverter = testDate, MemberConverter = testDate };
+
+      string json = JsonConvert.SerializeObject(m1, new JavaScriptDateTimeConverter());
+      Assert.AreEqual(@"{""DefaultConverter"":new Date(0),""MemberConverter"":""1970-01-01T00:00:00Z""}", json);
+
+      MemberConverterClass m2 = JsonConvert.DeserializeObject<MemberConverterClass>(json, new JavaScriptDateTimeConverter());
+
+      Assert.AreEqual(testDate, m2.DefaultConverter);
+      Assert.AreEqual(testDate, m2.MemberConverter);
+    }
+
+    [Test]
+    public void ConverterAttributeExample()
+    {
+      DateTime date = Convert.ToDateTime("1970-01-01T00:00:00Z").ToUniversalTime();
+
+      MemberConverterClass c = new MemberConverterClass
+        {
+          DefaultConverter = date,
+          MemberConverter = date
+        };
+
+      string json = JsonConvert.SerializeObject(c, Formatting.Indented);
+
+      Console.WriteLine(json);
+      //{
+      //  "DefaultConverter": "\/Date(0)\/",
+      //  "MemberConverter": "1970-01-01T00:00:00Z"
+      //}
+    }
+
+    [Test]
+    public void SerializerShouldUseMemberConverterOverClassAndArgumentConverter()
+    {
+      ClassAndMemberConverterClass c1 = new ClassAndMemberConverterClass();
+      c1.DefaultConverter = new ConverterPrecedenceClass("DefaultConverterValue");
+      c1.MemberConverter = new ConverterPrecedenceClass("MemberConverterValue");
+
+      string json = JsonConvert.SerializeObject(c1, new ArgumentConverterPrecedenceClassConverter());
+      Assert.AreEqual(@"{""DefaultConverter"":[""Class"",""DefaultConverterValue""],""MemberConverter"":[""Member"",""MemberConverterValue""]}", json);
+
+      ClassAndMemberConverterClass c2 = JsonConvert.DeserializeObject<ClassAndMemberConverterClass>(json, new ArgumentConverterPrecedenceClassConverter());
+
+      Assert.AreEqual("DefaultConverterValue", c2.DefaultConverter.TestValue);
+      Assert.AreEqual("MemberConverterValue", c2.MemberConverter.TestValue);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "JsonConverter IsoDateTimeConverter on Newtonsoft.Json.Tests.TestObjects.IncompatibleJsonAttributeClass is not compatible with member type IncompatibleJsonAttributeClass.")]
+    public void IncompatibleJsonAttributeShouldThrow()
+    {
+      IncompatibleJsonAttributeClass c = new IncompatibleJsonAttributeClass();
+      JsonConvert.SerializeObject(c);
+    }
+
+    [Test]
+    public void GenericAbstractProperty()
+    {
+      string json = JsonConvert.SerializeObject(new GenericImpl());
+      Assert.AreEqual(@"{""Id"":0}", json);
+    }
+
+    [Test]
+    public void DeserializeNullable()
+    {
+      string json;
+
+      json = JsonConvert.SerializeObject((int?)null);
+      Assert.AreEqual("null", json);
+
+      json = JsonConvert.SerializeObject((int?)1);
+      Assert.AreEqual("1", json);
+    }
+
+    [Test]
+    public void SerializeJsonRaw()
+    {
+      PersonRaw personRaw = new PersonRaw
+      {
+        FirstName = "FirstNameValue",
+        RawContent = new JRaw("[1,2,3,4,5]"),
+        LastName = "LastNameValue"
+      };
+
+      string json;
+
+      json = JsonConvert.SerializeObject(personRaw);
+      Assert.AreEqual(@"{""first_name"":""FirstNameValue"",""RawContent"":[1,2,3,4,5],""last_name"":""LastNameValue""}", json);
+    }
+
+    [Test]
+    public void DeserializeJsonRaw()
+    {
+      string json = @"{""first_name"":""FirstNameValue"",""RawContent"":[1,2,3,4,5],""last_name"":""LastNameValue""}";
+
+      PersonRaw personRaw = JsonConvert.DeserializeObject<PersonRaw>(json);
+
+      Assert.AreEqual("FirstNameValue", personRaw.FirstName);
+      Assert.AreEqual("[1,2,3,4,5]", personRaw.RawContent.ToString());
+      Assert.AreEqual("LastNameValue", personRaw.LastName);
+    }
+
+
+    [Test]
+    public void DeserializeNullableMember()
+    {
+      UserNullable userNullablle = new UserNullable
+                                    {
+                                      Id = new Guid("AD6205E8-0DF4-465d-AEA6-8BA18E93A7E7"),
+                                      FName = "FirstValue",
+                                      LName = "LastValue",
+                                      RoleId = 5,
+                                      NullableRoleId = 6,
+                                      NullRoleId = null,
+                                      Active = true
+                                    };
+
+      string json = JsonConvert.SerializeObject(userNullablle);
+
+      Assert.AreEqual(@"{""Id"":""ad6205e8-0df4-465d-aea6-8ba18e93a7e7"",""FName"":""FirstValue"",""LName"":""LastValue"",""RoleId"":5,""NullableRoleId"":6,""NullRoleId"":null,""Active"":true}", json);
+
+      UserNullable userNullablleDeserialized = JsonConvert.DeserializeObject<UserNullable>(json);
+
+      Assert.AreEqual(new Guid("AD6205E8-0DF4-465d-AEA6-8BA18E93A7E7"), userNullablleDeserialized.Id);
+      Assert.AreEqual("FirstValue", userNullablleDeserialized.FName);
+      Assert.AreEqual("LastValue", userNullablleDeserialized.LName);
+      Assert.AreEqual(5, userNullablleDeserialized.RoleId);
+      Assert.AreEqual(6, userNullablleDeserialized.NullableRoleId);
+      Assert.AreEqual(null, userNullablleDeserialized.NullRoleId);
+      Assert.AreEqual(true, userNullablleDeserialized.Active);
+    }
+
+    [Test]
+    public void DeserializeInt64ToNullableDouble()
+    {
+      string json = @"{""Height"":1}";
+
+      DoubleClass c = JsonConvert.DeserializeObject<DoubleClass>(json);
+      Assert.AreEqual(1, c.Height);
+    }
+
+    [Test]
+    public void SerializeTypeProperty()
+    {
+      string boolRef = typeof(bool).AssemblyQualifiedName;
+      TypeClass typeClass = new TypeClass { TypeProperty = typeof(bool) };
+
+      string json = JsonConvert.SerializeObject(typeClass);
+      Assert.AreEqual(@"{""TypeProperty"":""" + boolRef + @"""}", json);
+
+      TypeClass typeClass2 = JsonConvert.DeserializeObject<TypeClass>(json);
+      Assert.AreEqual(typeof(bool), typeClass2.TypeProperty);
+
+      string jsonSerializerTestRef = typeof(JsonSerializerTest).AssemblyQualifiedName;
+      typeClass = new TypeClass { TypeProperty = typeof(JsonSerializerTest) };
+
+      json = JsonConvert.SerializeObject(typeClass);
+      Assert.AreEqual(@"{""TypeProperty"":""" + jsonSerializerTestRef + @"""}", json);
+
+      typeClass2 = JsonConvert.DeserializeObject<TypeClass>(json);
+      Assert.AreEqual(typeof(JsonSerializerTest), typeClass2.TypeProperty);
+    }
+
+    [Test]
+    public void RequiredMembersClass()
+    {
+      RequiredMembersClass c = new RequiredMembersClass()
+      {
+        BirthDate = new DateTime(2000, 12, 20, 10, 55, 55, DateTimeKind.Utc),
+        FirstName = "Bob",
+        LastName = "Smith",
+        MiddleName = "Cosmo"
+      };
+
+      string json = JsonConvert.SerializeObject(c, Formatting.Indented);
+
+      Assert.AreEqual(@"{
+  ""FirstName"": ""Bob"",
+  ""MiddleName"": ""Cosmo"",
+  ""LastName"": ""Smith"",
+  ""BirthDate"": ""\/Date(977309755000)\/""
+}", json);
+
+      RequiredMembersClass c2 = JsonConvert.DeserializeObject<RequiredMembersClass>(json);
+
+      Assert.AreEqual("Bob", c2.FirstName);
+      Assert.AreEqual(new DateTime(2000, 12, 20, 10, 55, 55, DateTimeKind.Utc), c2.BirthDate);
+    }
+
+    [Test]
+    public void DeserializeRequiredMembersClassWithNullValues()
+    {
+      string json = @"{
+  ""FirstName"": ""I can't be null bro!"",
+  ""MiddleName"": null,
+  ""LastName"": null,
+  ""BirthDate"": ""\/Date(977309755000)\/""
+}";
+
+      RequiredMembersClass c = JsonConvert.DeserializeObject<RequiredMembersClass>(json);
+
+      Assert.AreEqual("I can't be null bro!", c.FirstName);
+      Assert.AreEqual(null, c.MiddleName);
+      Assert.AreEqual(null, c.LastName);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "Required property 'FirstName' expects a value but got null.")]
+    public void DeserializeRequiredMembersClassNullRequiredValueProperty()
+    {
+      string json = @"{
+  ""FirstName"": null,
+  ""MiddleName"": null,
+  ""LastName"": null,
+  ""BirthDate"": ""\/Date(977309755000)\/""
+}";
+
+      JsonConvert.DeserializeObject<RequiredMembersClass>(json);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "Cannot write a null value for property 'FirstName'. Property requires a value.")]
+    public void SerializeRequiredMembersClassNullRequiredValueProperty()
+    {
+      RequiredMembersClass requiredMembersClass = new RequiredMembersClass
+        {
+          FirstName = null,
+          BirthDate = new DateTime(2000, 10, 10, 10, 10, 10, DateTimeKind.Utc),
+          LastName = null,
+          MiddleName = null
+        };
+
+      string json = JsonConvert.SerializeObject(requiredMembersClass);
+      Console.WriteLine(json);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "Required property 'LastName' not found in JSON.")]
+    public void RequiredMembersClassMissingRequiredProperty()
+    {
+      string json = @"{
+  ""FirstName"": ""Bob""
+}";
+
+      JsonConvert.DeserializeObject<RequiredMembersClass>(json);
+    }
+
+    [Test]
+    public void SerializeJaggedArray()
+    {
+      JaggedArray aa = new JaggedArray();
+      aa.Before = "Before!";
+      aa.After = "After!";
+      aa.Coordinates = new[] { new[] { 1, 1 }, new[] { 1, 2 }, new[] { 2, 1 }, new[] { 2, 2 } };
+
+      string json = JsonConvert.SerializeObject(aa);
+
+      Assert.AreEqual(@"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2],[2,1],[2,2]],""After"":""After!""}", json);
+    }
+
+    [Test]
+    public void DeserializeJaggedArray()
+    {
+      string json = @"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2],[2,1],[2,2]],""After"":""After!""}";
+
+      JaggedArray aa = JsonConvert.DeserializeObject<JaggedArray>(json);
+
+      Assert.AreEqual("Before!", aa.Before);
+      Assert.AreEqual("After!", aa.After);
+      Assert.AreEqual(4, aa.Coordinates.Length);
+      Assert.AreEqual(2, aa.Coordinates[0].Length);
+      Assert.AreEqual(1, aa.Coordinates[0][0]);
+      Assert.AreEqual(2, aa.Coordinates[1][1]);
+
+      string after = JsonConvert.SerializeObject(aa);
+
+      Assert.AreEqual(json, after);
+    }
+
+    [Test]
+    public void DeserializeGoogleGeoCode()
+    {
+      string json = @"{
+  ""name"": ""1600 Amphitheatre Parkway, Mountain View, CA, USA"",
+  ""Status"": {
+    ""code"": 200,
+    ""request"": ""geocode""
+  },
+  ""Placemark"": [
+    {
+      ""address"": ""1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA"",
+      ""AddressDetails"": {
+        ""Country"": {
+          ""CountryNameCode"": ""US"",
+          ""AdministrativeArea"": {
+            ""AdministrativeAreaName"": ""CA"",
+            ""SubAdministrativeArea"": {
+              ""SubAdministrativeAreaName"": ""Santa Clara"",
+              ""Locality"": {
+                ""LocalityName"": ""Mountain View"",
+                ""Thoroughfare"": {
+                  ""ThoroughfareName"": ""1600 Amphitheatre Pkwy""
+                },
+                ""PostalCode"": {
+                  ""PostalCodeNumber"": ""94043""
+                }
+              }
+            }
+          }
+        },
+        ""Accuracy"": 8
+      },
+      ""Point"": {
+        ""coordinates"": [-122.083739, 37.423021, 0]
+      }
+    }
+  ]
+}";
+
+      GoogleMapGeocoderStructure jsonGoogleMapGeocoder = JsonConvert.DeserializeObject<GoogleMapGeocoderStructure>(json);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"Could not create an instance of type Newtonsoft.Json.Tests.TestObjects.ICo. Type is an interface or abstract class and cannot be instantated.")]
+    public void DeserializeInterfaceProperty()
+    {
+      InterfacePropertyTestClass testClass = new InterfacePropertyTestClass();
+      testClass.co = new Co();
+      String strFromTest = JsonConvert.SerializeObject(testClass);
+      InterfacePropertyTestClass testFromDe = (InterfacePropertyTestClass)JsonConvert.DeserializeObject(strFromTest, typeof(InterfacePropertyTestClass));
+    }
+
+    private Person GetPerson()
+    {
+      Person person = new Person
+                        {
+                          Name = "Mike Manager",
+                          BirthDate = new DateTime(1983, 8, 3, 0, 0, 0, DateTimeKind.Utc),
+                          Department = "IT",
+                          LastModified = new DateTime(2009, 2, 15, 0, 0, 0, DateTimeKind.Utc)
+                        };
+      return person;
+    }
+
+    //[Test]
+    public void WriteJsonToFile()
+    {
+      //Person person = GetPerson();
+
+      //string json = JsonConvert.SerializeObject(person, Formatting.Indented);
+
+      //File.WriteAllText(@"c:\person.json", json);
+
+      Person person = GetPerson();
+
+      using (FileStream fs = System.IO.File.Open(@"c:\person.json", FileMode.CreateNew))
+      using (StreamWriter sw = new StreamWriter(fs))
+      using (JsonWriter jw = new JsonTextWriter(sw))
+      {
+        jw.Formatting = Formatting.Indented;
+
+        JsonSerializer serializer = new JsonSerializer();
+        serializer.Serialize(jw, person);
+      }
+    }
+
+    [Test]
+    public void WriteJsonDates()
+    {
+      LogEntry entry = new LogEntry
+                         {
+                           LogDate = new DateTime(2009, 2, 15, 0, 0, 0, DateTimeKind.Utc),
+                           Details = "Application started."
+                         };
+
+      string defaultJson = JsonConvert.SerializeObject(entry);
+      // {"Details":"Application started.","LogDate":"\/Date(1234656000000)\/"}
+
+      string isoJson = JsonConvert.SerializeObject(entry, new IsoDateTimeConverter());
+      // {"Details":"Application started.","LogDate":"2009-02-15T00:00:00.0000000Z"}
+
+      string javascriptJson = JsonConvert.SerializeObject(entry, new JavaScriptDateTimeConverter());
+      // {"Details":"Application started.","LogDate":new Date(1234656000000)}
+
+      Console.WriteLine(defaultJson);
+      Console.WriteLine(isoJson);
+      Console.WriteLine(javascriptJson);
+    }
+
+    public void GenericListAndDictionaryInterfaceProperties()
+    {
+      GenericListAndDictionaryInterfaceProperties o = new GenericListAndDictionaryInterfaceProperties();
+      o.IDictionaryProperty = new Dictionary<string, int>
+                                {
+                                  {"one", 1},
+                                  {"two", 2},
+                                  {"three", 3}
+                                };
+      o.IListProperty = new List<int>
+                          {
+                            1, 2, 3
+                          };
+      o.IEnumerableProperty = new List<int>
+                                {
+                                  4, 5, 6
+                                };
+
+      string json = JsonConvert.SerializeObject(o, Formatting.Indented);
+
+      Assert.AreEqual(@"{
+  ""IEnumerableProperty"": [
+    4,
+    5,
+    6
+  ],
+  ""IListProperty"": [
+    1,
+    2,
+    3
+  ],
+  ""IDictionaryProperty"": {
+    ""one"": 1,
+    ""two"": 2,
+    ""three"": 3
+  }
+}", json);
+
+      GenericListAndDictionaryInterfaceProperties deserializedObject = JsonConvert.DeserializeObject<GenericListAndDictionaryInterfaceProperties>(json);
+      Assert.IsNotNull(deserializedObject);
+
+      CollectionAssert.AreEqual(o.IListProperty.ToArray(), deserializedObject.IListProperty.ToArray());
+      CollectionAssert.AreEqual(o.IEnumerableProperty.ToArray(), deserializedObject.IEnumerableProperty.ToArray());
+      CollectionAssert.AreEqual(o.IDictionaryProperty.ToArray(), deserializedObject.IDictionaryProperty.ToArray());
+    }
+
+    [Test]
+    public void DeserializeBestMatchPropertyCase()
+    {
+      string json = @"{
+  ""firstName"": ""firstName"",
+  ""FirstName"": ""FirstName"",
+  ""LastName"": ""LastName"",
+  ""lastName"": ""lastName"",
+}";
+
+      PropertyCase o = JsonConvert.DeserializeObject<PropertyCase>(json);
+      Assert.IsNotNull(o);
+
+      Assert.AreEqual("firstName", o.firstName);
+      Assert.AreEqual("FirstName", o.FirstName);
+      Assert.AreEqual("LastName", o.LastName);
+      Assert.AreEqual("lastName", o.lastName);
+    }
+
+    [Test]
+    public void DeserializePropertiesOnToNonDefaultConstructor()
+    {
+      SubKlass i = new SubKlass("my subprop");
+      i.SuperProp = "overrided superprop";
+
+      string json = JsonConvert.SerializeObject(i);
+      Assert.AreEqual(@"{""SubProp"":""my subprop"",""SuperProp"":""overrided superprop""}", json);
+
+      SubKlass ii = JsonConvert.DeserializeObject<SubKlass>(json);
+
+      string newJson = JsonConvert.SerializeObject(ii);
+      Assert.AreEqual(@"{""SubProp"":""my subprop"",""SuperProp"":""overrided superprop""}", newJson);
+    }
+
+    [Test]
+    public void JsonPropertyWithHandlingValues()
+    {
+      JsonPropertyWithHandlingValues o = new JsonPropertyWithHandlingValues();
+      o.DefaultValueHandlingIgnoreProperty = "Default!";
+      o.DefaultValueHandlingIncludeProperty = "Default!";
+
+      string json = JsonConvert.SerializeObject(o, Formatting.Indented);
+
+      Assert.AreEqual(@"{
+  ""DefaultValueHandlingIncludeProperty"": ""Default!"",
+  ""NullValueHandlingIncludeProperty"": null,
+  ""ReferenceLoopHandlingErrorProperty"": null,
+  ""ReferenceLoopHandlingIgnoreProperty"": null,
+  ""ReferenceLoopHandlingSerializeProperty"": null
+}", json);
+
+      json = JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
+
+      Assert.AreEqual(@"{
+  ""DefaultValueHandlingIncludeProperty"": ""Default!"",
+  ""NullValueHandlingIncludeProperty"": null
+}", json);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException))]
+    public void JsonPropertyWithHandlingValues_ReferenceLoopError()
+    {
+      JsonPropertyWithHandlingValues o = new JsonPropertyWithHandlingValues();
+      o.ReferenceLoopHandlingErrorProperty = o;
+
+      JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
+    }
+
+    [Test]
+    public void PartialClassDeserialize()
+    {
+      string json = @"{
+    ""request"": ""ux.settings.update"",
+    ""sid"": ""14c561bd-32a8-457e-b4e5-4bba0832897f"",
+    ""uid"": ""30c39065-0f31-de11-9442-001e3786a8ec"",
+    ""fidOrder"": [
+        ""id"",
+        ""andytest_name"",
+        ""andytest_age"",
+        ""andytest_address"",
+        ""andytest_phone"",
+        ""date"",
+        ""title"",
+        ""titleId""
+    ],
+    ""entityName"": ""Andy Test"",
+    ""setting"": ""entity.field.order""
+}";
+
+      RequestOnly r = JsonConvert.DeserializeObject<RequestOnly>(json);
+      Assert.AreEqual("ux.settings.update", r.Request);
+
+      NonRequest n = JsonConvert.DeserializeObject<NonRequest>(json);
+      Assert.AreEqual(new Guid("14c561bd-32a8-457e-b4e5-4bba0832897f"), n.Sid);
+      Assert.AreEqual(new Guid("30c39065-0f31-de11-9442-001e3786a8ec"), n.Uid);
+      Assert.AreEqual(8, n.FidOrder.Count);
+      Assert.AreEqual("id", n.FidOrder[0]);
+      Assert.AreEqual("titleId", n.FidOrder[n.FidOrder.Count - 1]);
+    }
+
+#if !SILVERLIGHT && !PocketPC && !NET20
+    [MetadataType(typeof(OptInClassMetadata))]
+    public class OptInClass
+    {
+      [DataContract]
+      public class OptInClassMetadata
+      {
+        [DataMember]
+        public string Name { get; set; }
+        [DataMember]
+        public int Age { get; set; }
+        public string NotIncluded { get; set; }
+      }
+
+      public string Name { get; set; }
+      public int Age { get; set; }
+      public string NotIncluded { get; set; }
+    }
+
+    [Test]
+    public void OptInClassMetadataSerialization()
+    {
+      OptInClass optInClass = new OptInClass();
+      optInClass.Age = 26;
+      optInClass.Name = "James NK";
+      optInClass.NotIncluded = "Poor me :(";
+
+      string json = JsonConvert.SerializeObject(optInClass, Formatting.Indented);
+
+      Assert.AreEqual(@"{
+  ""Name"": ""James NK"",
+  ""Age"": 26
+}", json);
+
+      OptInClass newOptInClass = JsonConvert.DeserializeObject<OptInClass>(@"{
+  ""Name"": ""James NK"",
+  ""NotIncluded"": ""Ignore me!"",
+  ""Age"": 26
+}");
+      Assert.AreEqual(26, newOptInClass.Age);
+      Assert.AreEqual("James NK", newOptInClass.Name);
+      Assert.AreEqual(null, newOptInClass.NotIncluded);
+    }
+#endif
+
+#if !PocketPC && !NET20
+    [DataContract]
+    public class DataContractPrivateMembers
+    {
+      public DataContractPrivateMembers()
+      {
+      }
+
+      public DataContractPrivateMembers(string name, int age, int rank, string title)
+      {
+        _name = name;
+        Age = age;
+        Rank = rank;
+        Title = title;
+      }
+
+      [DataMember]
+      private string _name;
+      [DataMember(Name = "_age")]
+      private int Age { get; set; }
+      [JsonProperty]
+      private int Rank { get; set; }
+      [JsonProperty(PropertyName = "JsonTitle")]
+      [DataMember(Name = "DataTitle")]
+      private string Title { get; set; }
+
+      public string NotIncluded { get; set; }
+
+      public override string ToString()
+      {
+        return "_name: " + _name + ", _age: " + Age + ", Rank: " + Rank + ", JsonTitle: " + Title;
+      }
+    }
+
+    [Test]
+    public void SerializeDataContractPrivateMembers()
+    {
+      DataContractPrivateMembers c = new DataContractPrivateMembers("Jeff", 26, 10, "Dr");
+      c.NotIncluded = "Hi";
+      string json = JsonConvert.SerializeObject(c, Formatting.Indented);
+
+      Assert.AreEqual(@"{
+  ""_name"": ""Jeff"",
+  ""_age"": 26,
+  ""Rank"": 10,
+  ""JsonTitle"": ""Dr""
+}", json);
+
+      DataContractPrivateMembers cc = JsonConvert.DeserializeObject<DataContractPrivateMembers>(json);
+      Assert.AreEqual("_name: Jeff, _age: 26, Rank: 10, JsonTitle: Dr", cc.ToString());
+    }
+#endif
+
+    [Test]
+    public void DeserializeDictionaryInterface()
+    {
+      string json = @"{
+  ""Name"": ""Name!"",
+  ""Dictionary"": {
+    ""Item"": 11
+  }
+}";
+
+      DictionaryInterfaceClass c = JsonConvert.DeserializeObject<DictionaryInterfaceClass>(json,
+        new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Replace });
+      Assert.AreEqual("Name!", c.Name);
+      Assert.AreEqual(1, c.Dictionary.Count);
+      Assert.AreEqual(11, c.Dictionary["Item"]);
+    }
+
+    [Test]
+    public void DeserializeDictionaryInterfaceWithExistingValues()
+    {
+      string json = @"{
+  ""Random"": {
+    ""blah"": 1
+  },
+  ""Name"": ""Name!"",
+  ""Dictionary"": {
+    ""Item"": 11,
+    ""Item1"": 12
+  },
+  ""Collection"": [
+    999
+  ],
+  ""Employee"": {
+    ""Manager"": {
+      ""Name"": ""ManagerName!""
+    }
+  }
+}";
+
+      DictionaryInterfaceClass c = JsonConvert.DeserializeObject<DictionaryInterfaceClass>(json,
+        new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Reuse });
+
+      Assert.AreEqual("Name!", c.Name);
+      Assert.AreEqual(3, c.Dictionary.Count);
+      Assert.AreEqual(11, c.Dictionary["Item"]);
+      Assert.AreEqual(1, c.Dictionary["existing"]);
+      Assert.AreEqual(4, c.Collection.Count);
+      Assert.AreEqual(1, c.Collection.ElementAt(0));
+      Assert.AreEqual(999, c.Collection.ElementAt(3));
+      Assert.AreEqual("EmployeeName!", c.Employee.Name);
+      Assert.AreEqual("ManagerName!", c.Employee.Manager.Name);
+      Assert.IsNotNull(c.Random);
+    }
+
+    [Test]
+    public void TypedObjectDeserializationWithComments()
+    {
+      string json = @"/*comment*/ { /*comment*/
+        ""Name"": /*comment*/ ""Apple"" /*comment*/, /*comment*/
+        ""ExpiryDate"": ""\/Date(1230422400000)\/"",
+        ""Price"": 3.99,
+        ""Sizes"": /*comment*/ [ /*comment*/
+          ""Small"", /*comment*/
+          ""Medium"" /*comment*/,
+          /*comment*/ ""Large""
+        /*comment*/ ] /*comment*/
+      } /*comment*/";
+
+      Product deserializedProduct = (Product)JsonConvert.DeserializeObject(json, typeof(Product));
+
+      Assert.AreEqual("Apple", deserializedProduct.Name);
+      Assert.AreEqual(new DateTime(2008, 12, 28, 0, 0, 0, DateTimeKind.Utc), deserializedProduct.ExpiryDate);
+      Assert.AreEqual(3.99, deserializedProduct.Price);
+      Assert.AreEqual("Small", deserializedProduct.Sizes[0]);
+      Assert.AreEqual("Medium", deserializedProduct.Sizes[1]);
+      Assert.AreEqual("Large", deserializedProduct.Sizes[2]);
+    }
+
+    [Test]
+    public void NestedInsideOuterObject()
+    {
+      string json = @"{
+  ""short"": {
+    ""original"": ""http://www.contrast.ie/blog/online&#45;marketing&#45;2009/"",
+    ""short"": ""m2sqc6"",
+    ""shortened"": ""http://short.ie/m2sqc6"",
+    ""error"": {
+      ""code"": 0,
+      ""msg"": ""No action taken""
+    }
+  }
+}";
+
+      JObject o = JObject.Parse(json);
+
+      Shortie s = JsonConvert.DeserializeObject<Shortie>(o["short"].ToString());
+      Assert.IsNotNull(s);
+
+      Assert.AreEqual(s.Original, "http://www.contrast.ie/blog/online&#45;marketing&#45;2009/");
+      Assert.AreEqual(s.Short, "m2sqc6");
+      Assert.AreEqual(s.Shortened, "http://short.ie/m2sqc6");
+    }
+
+    [Test]
+    public void UriSerialization()
+    {
+      Uri uri = new Uri("http://codeplex.com");
+      string json = JsonConvert.SerializeObject(uri);
+
+      Assert.AreEqual("http://codeplex.com/", uri.ToString());
+
+      Uri newUri = JsonConvert.DeserializeObject<Uri>(json);
+      Assert.AreEqual(uri, newUri);
+    }
+
+    [Test]
+    public void AnonymousPlusLinqToSql()
+    {
+      var value = new
+        {
+          bar = new JObject(new JProperty("baz", 13))
+        };
+
+      string json = JsonConvert.SerializeObject(value);
+
+      Assert.AreEqual(@"{""bar"":{""baz"":13}}", json);
+    }
+
+    [Test]
+    public void SerializeEnumerableAsObject()
+    {
+      Content content = new Content
+        {
+          Text = "Blah, blah, blah",
+          Children = new List<Content>
+            {
+              new Content { Text = "First" },
+              new Content { Text = "Second" }
+            }
+        };
+
+      string json = JsonConvert.SerializeObject(content, Formatting.Indented);
+
+      Assert.AreEqual(@"{
+  ""Children"": [
+    {
+      ""Children"": null,
+      ""Text"": ""First""
+    },
+    {
+      ""Children"": null,
+      ""Text"": ""Second""
+    }
+  ],
+  ""Text"": ""Blah, blah, blah""
+}", json);
+    }
+
+    [Test]
+    public void DeserializeEnumerableAsObject()
+    {
+      string json = @"{
+  ""Children"": [
+    {
+      ""Children"": null,
+      ""Text"": ""First""
+    },
+    {
+      ""Children"": null,
+      ""Text"": ""Second""
+    }
+  ],
+  ""Text"": ""Blah, blah, blah""
+}";
+
+      Content content = JsonConvert.DeserializeObject<Content>(json);
+
+      Assert.AreEqual("Blah, blah, blah", content.Text);
+      Assert.AreEqual(2, content.Children.Count);
+      Assert.AreEqual("First", content.Children[0].Text);
+      Assert.AreEqual("Second", content.Children[1].Text);
+    }
+
+    [Test]
+    public void RoleTransferTest()
+    {
+      string json = @"{""Operation"":""1"",""RoleName"":""Admin"",""Direction"":""0""}";
+
+      RoleTransfer r = JsonConvert.DeserializeObject<RoleTransfer>(json);
+
+      Assert.AreEqual(RoleTransferOperation.Second, r.Operation);
+      Assert.AreEqual("Admin", r.RoleName);
+      Assert.AreEqual(RoleTransferDirection.First, r.Direction);
+    }
+
+    [Test]
+    public void PrimitiveValuesInObjectArray()
+    {
+      string json = @"{""action"":""Router"",""method"":""Navigate"",""data"":[""dashboard"",null],""type"":""rpc"",""tid"":2}";
+
+      ObjectArrayPropertyTest o = JsonConvert.DeserializeObject<ObjectArrayPropertyTest>(json);
+
+      Assert.AreEqual("Router", o.Action);
+      Assert.AreEqual("Navigate", o.Method);
+      Assert.AreEqual(2, o.Data.Length);
+      Assert.AreEqual("dashboard", o.Data[0]);
+      Assert.AreEqual(null, o.Data[1]);
+    }
+
+    [Test]
+    public void ComplexValuesInObjectArray()
+    {
+      string json = @"{""action"":""Router"",""method"":""Navigate"",""data"":[""dashboard"",[""id"", 1, ""teststring"", ""test""],{""one"":1}],""type"":""rpc"",""tid"":2}";
+
+      ObjectArrayPropertyTest o = JsonConvert.DeserializeObject<ObjectArrayPropertyTest>(json);
+
+      Assert.AreEqual("Router", o.Action);
+      Assert.AreEqual("Navigate", o.Method);
+      Assert.AreEqual(3, o.Data.Length);
+      Assert.AreEqual("dashboard", o.Data[0]);
+      Assert.IsInstanceOfType(typeof(JArray), o.Data[1]);
+      Assert.AreEqual(4, ((JArray)o.Data[1]).Count);
+      Assert.IsInstanceOfType(typeof(JObject), o.Data[2]);
+      Assert.AreEqual(1, ((JObject)o.Data[2]).Count);
+      Assert.AreEqual(1, (int)((JObject)o.Data[2])["one"]);
+    }
+
+    [Test]
+    public void DeserializeGenericDictionary()
+    {
+      string json = @"{""key1"":""value1"",""key2"":""value2""}";
+
+      Dictionary<string, string> values = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
+
+      Console.WriteLine(values.Count);
+      // 2
+
+      Console.WriteLine(values["key1"]);
+      // value1
+
+      Assert.AreEqual(2, values.Count);
+      Assert.AreEqual("value1", values["key1"]);
+      Assert.AreEqual("value2", values["key2"]);
+    }
+
+    [Test]
+    public void SerializeGenericList()
+    {
+      Product p1 = new Product
+        {
+          Name = "Product 1",
+          Price = 99.95m,
+          ExpiryDate = new DateTime(2000, 12, 29, 0, 0, 0, DateTimeKind.Utc),
+        };
+      Product p2 = new Product
+      {
+        Name = "Product 2",
+        Price = 12.50m,
+        ExpiryDate = new DateTime(2009, 7, 31, 0, 0, 0, DateTimeKind.Utc),
+      };
+
+      List<Product> products = new List<Product>();
+      products.Add(p1);
+      products.Add(p2);
+
+      string json = JsonConvert.SerializeObject(products, Formatting.Indented);
+      //[
+      //  {
+      //    "Name": "Product 1",
+      //    "ExpiryDate": "\/Date(978048000000)\/",
+      //    "Price": 99.95,
+      //    "Sizes": null
+      //  },
+      //  {
+      //    "Name": "Product 2",
+      //    "ExpiryDate": "\/Date(1248998400000)\/",
+      //    "Price": 12.50,
+      //    "Sizes": null
+      //  }
+      //]
+
+      Assert.AreEqual(@"[
+  {
+    ""Name"": ""Product 1"",
+    ""ExpiryDate"": ""\/Date(978048000000)\/"",
+    ""Price"": 99.95,
+    ""Sizes"": null
+  },
+  {
+    ""Name"": ""Product 2"",
+    ""ExpiryDate"": ""\/Date(1248998400000)\/"",
+    ""Price"": 12.50,
+    ""Sizes"": null
+  }
+]", json);
+    }
+
+    [Test]
+    public void DeserializeGenericList()
+    {
+      string json = @"[
+        {
+          ""Name"": ""Product 1"",
+          ""ExpiryDate"": ""\/Date(978048000000)\/"",
+          ""Price"": 99.95,
+          ""Sizes"": null
+        },
+        {
+          ""Name"": ""Product 2"",
+          ""ExpiryDate"": ""\/Date(1248998400000)\/"",
+          ""Price"": 12.50,
+          ""Sizes"": null
+        }
+      ]";
+
+      List<Product> products = JsonConvert.DeserializeObject<List<Product>>(json);
+
+      Console.WriteLine(products.Count);
+      // 2
+
+      Product p1 = products[0];
+
+      Console.WriteLine(p1.Name);
+      // Product 1
+
+      Assert.AreEqual(2, products.Count);
+      Assert.AreEqual("Product 1", products[0].Name);
+    }
+
+#if !PocketPC && !NET20
+    [Test]
+    public void DeserializeEmptyStringToNullableDateTime()
+    {
+      string json = @"{""DateTimeField"":""""}";
+
+      NullableDateTimeTestClass c = JsonConvert.DeserializeObject<NullableDateTimeTestClass>(json);
+      Assert.AreEqual(null, c.DateTimeField);
+    }
+#endif
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"Unable to find a constructor to use for type Newtonsoft.Json.Tests.TestObjects.Event. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute.")]
+    public void FailWhenClassWithNoDefaultConstructorHasMultipleConstructorsWithArguments()
+    {
+      string json = @"{""sublocation"":""AlertEmailSender.Program.Main"",""userId"":0,""type"":0,""summary"":""Loading settings variables"",""details"":null,""stackTrace"":""   at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)\r\n   at System.Environment.get_StackTrace()\r\n   at mr.Logging.Event..ctor(String summary) in C:\\Projects\\MRUtils\\Logging\\Event.vb:line 71\r\n   at AlertEmailSender.Program.Main(String[] args) in C:\\Projects\\AlertEmailSender\\AlertEmailSender\\Program.cs:line 25"",""tag"":null,""time"":""\/Date(1249591032026-0400)\/""}";
+
+      Event e = JsonConvert.DeserializeObject<Event>(json);
+    }
+
+    [Test]
+    public void DeserializeObjectSetOnlyProperty()
+    {
+      string json = @"{'SetOnlyProperty':[1,2,3,4,5]}";
+
+      SetOnlyPropertyClass2 setOnly = JsonConvert.DeserializeObject<SetOnlyPropertyClass2>(json);
+      JArray a = (JArray)setOnly.GetValue();
+      Assert.AreEqual(5, a.Count);
+      Assert.AreEqual(1, (int)a[0]);
+      Assert.AreEqual(5, (int)a[a.Count - 1]);
+    }
+
+    [Test]
+    public void DeserializeOptInClasses()
+    {
+      string json = @"{id: ""12"", name: ""test"", items: [{id: ""112"", name: ""testing""}]}";
+
+      ListTestClass l = JsonConvert.DeserializeObject<ListTestClass>(json);
+    }
+
+    [Test]
+    public void DeserializeNullableListWithNulls()
+    {
+      List<decimal?> l = JsonConvert.DeserializeObject<List<decimal?>>("[ 3.3, null, 1.1 ] ");
+      Assert.AreEqual(3, l.Count);
+
+      Assert.AreEqual(3.3m, l[0]);
+      Assert.AreEqual(null, l[1]);
+      Assert.AreEqual(1.1m, l[2]);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"Cannot deserialize JSON array into type 'Newtonsoft.Json.Tests.TestObjects.Person'.")]
+    public void CannotDeserializeArrayIntoObject()
+    {
+      string json = @"[]";
+
+      JsonConvert.DeserializeObject<Person>(json);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"Cannot deserialize JSON object into type 'System.Collections.Generic.List`1[Newtonsoft.Json.Tests.TestObjects.Person]'.")]
+    public void CannotDeserializeObjectIntoArray()
+    {
+      string json = @"{}";
+
+      JsonConvert.DeserializeObject<List<Person>>(json);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"Cannot populate JSON array onto type 'Newtonsoft.Json.Tests.TestObjects.Person'.")]
+    public void CannotPopulateArrayIntoObject()
+    {
+      string json = @"[]";
+
+      JsonConvert.PopulateObject(json, new Person());
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"Cannot populate JSON object onto type 'System.Collections.Generic.List`1[Newtonsoft.Json.Tests.TestObjects.Person]'.")]
+    public void CannotPopulateObjectIntoArray()
+    {
+      string json = @"{}";
+
+      JsonConvert.PopulateObject(json, new List<Person>());
+    }
+
+    [Test]
+    public void DeserializeEmptyString()
+    {
+      string json = @"{""Name"":""""}";
+
+      Person p = JsonConvert.DeserializeObject<Person>(json);
+      Assert.AreEqual("", p.Name);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"Error getting value from 'ReadTimeout' on 'System.IO.MemoryStream'.")]
+    public void SerializePropertyGetError()
+    {
+      JsonConvert.SerializeObject(new MemoryStream());
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"Error setting value to 'ReadTimeout' on 'System.IO.MemoryStream'.")]
+    public void DeserializePropertySetError()
+    {
+      JsonConvert.DeserializeObject<MemoryStream>("{ReadTimeout:0}");
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"Error converting value """" to type 'System.Int32'.")]
+    public void DeserializeEnsureTypeEmptyStringToIntError()
+    {
+      JsonConvert.DeserializeObject<MemoryStream>("{ReadTimeout:''}");
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"Error converting value {null} to type 'System.Int32'.")]
+    public void DeserializeEnsureTypeNullToIntError()
+    {
+      JsonConvert.DeserializeObject<MemoryStream>("{ReadTimeout:null}");
+    }
+
+    [Test]
+    public void SerializeGenericListOfStrings()
+    {
+      List<String> strings = new List<String>();
+
+      strings.Add("str_1");
+      strings.Add("str_2");
+      strings.Add("str_3");
+
+      string json = JsonConvert.SerializeObject(strings);
+      Assert.AreEqual(@"[""str_1"",""str_2"",""str_3""]", json);
+    }
+
+    [Test]
+    public void ConstructorReadonlyFieldsTest()
+    {
+      ConstructorReadonlyFields c1 = new ConstructorReadonlyFields("String!", int.MaxValue);
+      string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
+      Assert.AreEqual(@"{
+  ""A"": ""String!"",
+  ""B"": 2147483647
+}", json);
+
+      ConstructorReadonlyFields c2 = JsonConvert.DeserializeObject<ConstructorReadonlyFields>(json);
+      Assert.AreEqual("String!", c2.A);
+      Assert.AreEqual(int.MaxValue, c2.B);
+    }
+
+    [Test]
+    public void SerializeStruct()
+    {
+      StructTest structTest = new StructTest
+                                {
+                                  StringProperty = "StringProperty!",
+                                  StringField = "StringField",
+                                  IntProperty = 5,
+                                  IntField = 10
+                                };
+
+      string json = JsonConvert.SerializeObject(structTest, Formatting.Indented);
+      Console.WriteLine(json);
+      Assert.AreEqual(@"{
+  ""StringField"": ""StringField"",
+  ""IntField"": 10,
+  ""StringProperty"": ""StringProperty!"",
+  ""IntProperty"": 5
+}", json);
+
+      StructTest deserialized = JsonConvert.DeserializeObject<StructTest>(json);
+      Assert.AreEqual(structTest.StringProperty, deserialized.StringProperty);
+      Assert.AreEqual(structTest.StringField, deserialized.StringField);
+      Assert.AreEqual(structTest.IntProperty, deserialized.IntProperty);
+      Assert.AreEqual(structTest.IntField, deserialized.IntField);
+    }
+
+    [Test]
+    public void SerializeListWithJsonConverter()
+    {
+      Foo f = new Foo();
+      f.Bars.Add(new Bar { Id = 0 });
+      f.Bars.Add(new Bar { Id = 1 });
+      f.Bars.Add(new Bar { Id = 2 });
+
+      string json = JsonConvert.SerializeObject(f, Formatting.Indented);
+      Assert.AreEqual(@"{
+  ""Bars"": [
+    0,
+    1,
+    2
+  ]
+}", json);
+
+      Foo newFoo = JsonConvert.DeserializeObject<Foo>(json);
+      Assert.AreEqual(3, newFoo.Bars.Count);
+      Assert.AreEqual(0, newFoo.Bars[0].Id);
+      Assert.AreEqual(1, newFoo.Bars[1].Id);
+      Assert.AreEqual(2, newFoo.Bars[2].Id);
+    }
+
+    [Test]
+    public void SerializeGuidKeyedDictionary()
+    {
+      Dictionary<Guid, int> dictionary = new Dictionary<Guid, int>();
+      dictionary.Add(new Guid("F60EAEE0-AE47-488E-B330-59527B742D77"), 1);
+      dictionary.Add(new Guid("C2594C02-EBA1-426A-AA87-8DD8871350B0"), 2);
+
+      string json = JsonConvert.SerializeObject(dictionary, Formatting.Indented);
+      Assert.AreEqual(@"{
+  ""f60eaee0-ae47-488e-b330-59527b742d77"": 1,
+  ""c2594c02-eba1-426a-aa87-8dd8871350b0"": 2
+}", json);
+    }
+
+    [Test]
+    public void SerializePersonKeyedDictionary()
+    {
+      Dictionary<Person, int> dictionary = new Dictionary<Person, int>();
+      dictionary.Add(new Person { Name = "p1" }, 1);
+      dictionary.Add(new Person { Name = "p2" }, 2);
+
+      string json = JsonConvert.SerializeObject(dictionary, Formatting.Indented);
+
+      Assert.AreEqual(@"{
+  ""Newtonsoft.Json.Tests.TestObjects.Person"": 1,
+  ""Newtonsoft.Json.Tests.TestObjects.Person"": 2
+}", json);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "Could not convert string 'Newtonsoft.Json.Tests.TestObjects.Person' to dictionary key type 'Newtonsoft.Json.Tests.TestObjects.Person'. Create a TypeConverter to convert from the string to the key type object.")]
+    public void DeserializePersonKeyedDictionary()
+    {
+      string json =
+        @"{
+  ""Newtonsoft.Json.Tests.TestObjects.Person"": 1,
+  ""Newtonsoft.Json.Tests.TestObjects.Person"": 2
+}";
+
+      JsonConvert.DeserializeObject<Dictionary<Person, int>>(json);
+    }
+
+    [Test]
+    public void SerializeFragment()
+    {
+      string googleSearchText = @"{
+        ""responseData"": {
+          ""results"": [
+            {
+              ""GsearchResultClass"": ""GwebSearch"",
+              ""unescapedUrl"": ""http://en.wikipedia.org/wiki/Paris_Hilton"",
+              ""url"": ""http://en.wikipedia.org/wiki/Paris_Hilton"",
+              ""visibleUrl"": ""en.wikipedia.org"",
+              ""cacheUrl"": ""http://www.google.com/search?q=cache:TwrPfhd22hYJ:en.wikipedia.org"",
+              ""title"": ""<b>Paris Hilton</b> - Wikipedia, the free encyclopedia"",
+              ""titleNoFormatting"": ""Paris Hilton - Wikipedia, the free encyclopedia"",
+              ""content"": ""[1] In 2006, she released her debut album...""
+            },
+            {
+              ""GsearchResultClass"": ""GwebSearch"",
+              ""unescapedUrl"": ""http://www.imdb.com/name/nm0385296/"",
+              ""url"": ""http://www.imdb.com/name/nm0385296/"",
+              ""visibleUrl"": ""www.imdb.com"",
+              ""cacheUrl"": ""http://www.google.com/search?q=cache:1i34KkqnsooJ:www.imdb.com"",
+              ""title"": ""<b>Paris Hilton</b>"",
+              ""titleNoFormatting"": ""Paris Hilton"",
+              ""content"": ""Self: Zoolander. Socialite <b>Paris Hilton</b>...""
+            }
+          ],
+          ""cursor"": {
+            ""pages"": [
+              {
+                ""start"": ""0"",
+                ""label"": 1
+              },
+              {
+                ""start"": ""4"",
+                ""label"": 2
+              },
+              {
+                ""start"": ""8"",
+                ""label"": 3
+              },
+              {
+                ""start"": ""12"",
+                ""label"": 4
+              }
+            ],
+            ""estimatedResultCount"": ""59600000"",
+            ""currentPageIndex"": 0,
+            ""moreResultsUrl"": ""http://www.google.com/search?oe=utf8&ie=utf8...""
+          }
+        },
+        ""responseDetails"": null,
+        ""responseStatus"": 200
+      }";
+
+      JObject googleSearch = JObject.Parse(googleSearchText);
+
+      // get JSON result objects into a list
+      IList<JToken> results = googleSearch["responseData"]["results"].Children().ToList();
+
+      // serialize JSON results into .NET objects
+      IList<SearchResult> searchResults = new List<SearchResult>();
+      foreach (JToken result in results)
+      {
+        SearchResult searchResult = JsonConvert.DeserializeObject<SearchResult>(result.ToString());
+        searchResults.Add(searchResult);
+      }
+
+      // Title = <b>Paris Hilton</b> - Wikipedia, the free encyclopedia
+      // Content = [1] In 2006, she released her debut album...
+      // Url = http://en.wikipedia.org/wiki/Paris_Hilton
+
+      // Title = <b>Paris Hilton</b>
+      // Content = Self: Zoolander. Socialite <b>Paris Hilton</b>...
+      // Url = http://www.imdb.com/name/nm0385296/
+
+      Assert.AreEqual(2, searchResults.Count);
+      Assert.AreEqual("<b>Paris Hilton</b> - Wikipedia, the free encyclopedia", searchResults[0].Title);
+      Assert.AreEqual("<b>Paris Hilton</b>", searchResults[1].Title);
+    }
+
+    [Test]
+    public void DeserializeBaseReferenceWithDerivedValue()
+    {
+      PersonPropertyClass personPropertyClass = new PersonPropertyClass();
+      WagePerson wagePerson = (WagePerson)personPropertyClass.Person;
+
+      wagePerson.BirthDate = new DateTime(2000, 11, 29, 23, 59, 59, DateTimeKind.Utc);
+      wagePerson.Department = "McDees";
+      wagePerson.HourlyWage = 12.50m;
+      wagePerson.LastModified = new DateTime(2000, 11, 29, 23, 59, 59, DateTimeKind.Utc);
+      wagePerson.Name = "Jim Bob";
+
+      string json = JsonConvert.SerializeObject(personPropertyClass, Formatting.Indented);
+      Assert.AreEqual(
+        @"{
+  ""Person"": {
+    ""HourlyWage"": 12.50,
+    ""Name"": ""Jim Bob"",
+    ""BirthDate"": ""\/Date(975542399000)\/"",
+    ""LastModified"": ""\/Date(975542399000)\/""
+  }
+}",
+        json);
+
+      PersonPropertyClass newPersonPropertyClass = JsonConvert.DeserializeObject<PersonPropertyClass>(json);
+      Assert.AreEqual(wagePerson.HourlyWage, ((WagePerson)newPersonPropertyClass.Person).HourlyWage);
+    }
+
+    public class ExistingValueClass
+    {
+      public Dictionary<string, string> Dictionary { get; set; }
+      public List<string> List { get; set; }
+
+      public ExistingValueClass()
+      {
+        Dictionary = new Dictionary<string, string>
+                       {
+                         {"existing", "yup"}
+                       };
+        List = new List<string>
+                 {
+                   "existing"
+                 };
+      }
+    }
+
+    [Test]
+    public void DeserializePopulateDictionaryAndList()
+    {
+      ExistingValueClass d = JsonConvert.DeserializeObject<ExistingValueClass>(@"{'Dictionary':{appended:'appended',existing:'new'}}");
+
+      Assert.IsNotNull(d);
+      Assert.IsNotNull(d.Dictionary);
+      Assert.AreEqual(typeof(Dictionary<string, string>), d.Dictionary.GetType());
+      Assert.AreEqual(typeof(List<string>), d.List.GetType());
+      Assert.AreEqual(2, d.Dictionary.Count);
+      Assert.AreEqual("new", d.Dictionary["existing"]);
+      Assert.AreEqual("appended", d.Dictionary["appended"]);
+      Assert.AreEqual(1, d.List.Count);
+      Assert.AreEqual("existing", d.List[0]);
+    }
+
+    public interface IKeyValueId
+    {
+      int Id { get; set; }
+      string Key { get; set; }
+      string Value { get; set; }
+    }
+
+
+    public class KeyValueId : IKeyValueId
+    {
+      public int Id { get; set; }
+      public string Key { get; set; }
+      public string Value { get; set; }
+    }
+
+    public class ThisGenericTest<T> where T : IKeyValueId
+    {
+      private Dictionary<string, T> _dict1 = new Dictionary<string, T>();
+
+      public string MyProperty { get; set; }
+
+      public void Add(T item)
+      {
+        this._dict1.Add(item.Key, item);
+      }
+
+      public T this[string key]
+      {
+        get { return this._dict1[key]; }
+        set { this._dict1[key] = value; }
+      }
+
+      public T this[int id]
+      {
+        get { return this._dict1.Values.FirstOrDefault(x => x.Id == id); }
+        set
+        {
+          var item = this[id];
+
+          if (item == null)
+            this.Add(value);
+          else
+            this._dict1[item.Key] = value;
+        }
+      }
+
+      public string ToJson()
+      {
+        return JsonConvert.SerializeObject(this, Formatting.Indented);
+      }
+
+      public T[] TheItems
+      {
+        get { return this._dict1.Values.ToArray<T>(); }
+        set
+        {
+          foreach (var item in value)
+            this.Add(item);
+        }
+      }
+    }
+
+    [Test]
+    public void IgnoreIndexedProperties()
+    {
+      ThisGenericTest<KeyValueId> g = new ThisGenericTest<KeyValueId>();
+
+      g.Add(new KeyValueId { Id = 1, Key = "key1", Value = "value1" });
+      g.Add(new KeyValueId { Id = 2, Key = "key2", Value = "value2" });
+
+      g.MyProperty = "some value";
+
+      string json = g.ToJson();
+
+      Assert.AreEqual(@"{
+  ""MyProperty"": ""some value"",
+  ""TheItems"": [
+    {
+      ""Id"": 1,
+      ""Key"": ""key1"",
+      ""Value"": ""value1""
+    },
+    {
+      ""Id"": 2,
+      ""Key"": ""key2"",
+      ""Value"": ""value2""
+    }
+  ]
+}", json);
+
+      ThisGenericTest<KeyValueId> gen = JsonConvert.DeserializeObject<ThisGenericTest<KeyValueId>>(json);
+      Assert.AreEqual("some value", gen.MyProperty);
+    }
+
+    public class JRawValueTestObject
+    {
+      public JRaw Value { get; set; }
+    }
+
+    [Test]
+    public void JRawValue()
+    {
+      JRawValueTestObject deserialized = JsonConvert.DeserializeObject<JRawValueTestObject>("{value:3}");
+      Assert.AreEqual("3", deserialized.Value.ToString());
+
+      deserialized = JsonConvert.DeserializeObject<JRawValueTestObject>("{value:'3'}");
+      Assert.AreEqual(@"""3""", deserialized.Value.ToString());
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "Unable to find a default constructor to use for type Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+DictionaryWithNoDefaultConstructor.")]
+    public void DeserializeDictionaryWithNoDefaultConstructor()
+    {
+      string json = "{key1:'value',key2:'value',key3:'value'}";
+      JsonConvert.DeserializeObject<DictionaryWithNoDefaultConstructor>(json);
+    }
+
+    public class DictionaryWithNoDefaultConstructor : Dictionary<string, string>
+    {
+      public DictionaryWithNoDefaultConstructor(IEnumerable<KeyValuePair<string, string>> initial)
+      {
+        foreach (KeyValuePair<string, string> pair in initial)
+        {
+          Add(pair.Key, pair.Value);
+        }
+      }
+    }
+
+    [JsonObject(MemberSerialization.OptIn)]
+    public class A
+    {
+      [JsonProperty("A1")]
+      private string _A1;
+      public string A1 { get { return _A1; } set { _A1 = value; } }
+
+      [JsonProperty("A2")]
+      private string A2 { get; set; }
+    }
+
+    [JsonObject(MemberSerialization.OptIn)]
+    public class B : A
+    {
+      public string B1 { get; set; }
+
+      [JsonProperty("B2")]
+      string _B2;
+      public string B2 { get { return _B2; } set { _B2 = value; } }
+
+      [JsonProperty("B3")]
+      private string B3 { get; set; }
+    }
+
+    [Test]
+    public void SerializeNonPublicBaseJsonProperties()
+    {
+      B value = new B();
+      string json = JsonConvert.SerializeObject(value, Formatting.Indented);
+
+      Assert.AreEqual(@"{
+  ""B2"": null,
+  ""A1"": null,
+  ""B3"": null,
+  ""A2"": null
+}", json);
+    }
+
+    public class TestClass
+    {
+      public string Key { get; set; }
+      public object Value { get; set; }
+    }
+
+    [Test]
+    public void DeserializeToObjectProperty()
+    {
+      var json = "{ Key: 'abc', Value: 123 }";
+      var item = JsonConvert.DeserializeObject<TestClass>(json);
+
+      Assert.AreEqual(123, item.Value);
+    }
+
+    public abstract class Animal
+    {
+      public abstract string Name { get; }
+    }
+
+    public class Human : Animal
+    {
+      public override string Name
+      {
+        get { return typeof(Human).Name; }
+      }
+
+      public string Ethnicity { get; set; }
+    }
+
+#if !NET20 && !PocketPC && !WINDOWS_PHONE
+    public class DataContractJsonSerializerTestClass
+    {
+      public TimeSpan TimeSpanProperty { get; set; }
+      public Guid GuidProperty { get; set; }
+      public Animal AnimalProperty { get; set; }
+      public Exception ExceptionProperty { get; set; }
+    }
+
+    [Test]
+    public void DataContractJsonSerializerTest()
+    {
+      Exception ex = new Exception("Blah blah blah");
+
+      DataContractJsonSerializerTestClass c = new DataContractJsonSerializerTestClass();
+      c.TimeSpanProperty = new TimeSpan(200, 20, 59, 30, 900);
+      c.GuidProperty = new Guid("66143115-BE2A-4a59-AF0A-348E1EA15B1E");
+      c.AnimalProperty = new Human() { Ethnicity = "European" };
+      c.ExceptionProperty = ex;
+
+      MemoryStream ms = new MemoryStream();
+      DataContractJsonSerializer serializer = new DataContractJsonSerializer(
+        typeof(DataContractJsonSerializerTestClass),
+        new Type[] { typeof(Human) });
+      serializer.WriteObject(ms, c);
+
+      byte[] jsonBytes = ms.ToArray();
+      string json = Encoding.UTF8.GetString(jsonBytes, 0, jsonBytes.Length);
+
+      Console.WriteLine(JObject.Parse(json).ToString());
+      Console.WriteLine();
+
+      Console.WriteLine(JsonConvert.SerializeObject(c, Formatting.Indented, new JsonSerializerSettings
+                                                                          {
+                                                                            //               TypeNameHandling = TypeNameHandling.Objects
+                                                                          }));
+    }
+#endif
+
+    public class ModelStateDictionary<T> : IDictionary<string, T>
+    {
+
+      private readonly Dictionary<string, T> _innerDictionary = new Dictionary<string, T>(StringComparer.OrdinalIgnoreCase);
+
+      public ModelStateDictionary()
+      {
+      }
+
+      public ModelStateDictionary(ModelStateDictionary<T> dictionary)
+      {
+        if (dictionary == null)
+        {
+          throw new ArgumentNullException("dictionary");
+        }
+
+        foreach (var entry in dictionary)
+        {
+          _innerDictionary.Add(entry.Key, entry.Value);
+        }
+      }
+
+      public int Count
+      {
+        get
+        {
+          return _innerDictionary.Count;
+        }
+      }
+
+      public bool IsReadOnly
+      {
+        get
+        {
+          return ((IDictionary<string, T>)_innerDictionary).IsReadOnly;
+        }
+      }
+
+      public ICollection<string> Keys
+      {
+        get
+        {
+          return _innerDictionary.Keys;
+        }
+      }
+
+      public T this[string key]
+      {
+        get
+        {
+          T value;
+          _innerDictionary.TryGetValue(key, out value);
+          return value;
+        }
+        set
+        {
+          _innerDictionary[key] = value;
+        }
+      }
+
+      public ICollection<T> Values
+      {
+        get
+        {
+          return _innerDictionary.Values;
+        }
+      }
+
+      public void Add(KeyValuePair<string, T> item)
+      {
+        ((IDictionary<string, T>)_innerDictionary).Add(item);
+      }
+
+      public void Add(string key, T value)
+      {
+        _innerDictionary.Add(key, value);
+      }
+
+      public void Clear()
+      {
+        _innerDictionary.Clear();
+      }
+
+      public bool Contains(KeyValuePair<string, T> item)
+      {
+        return ((IDictionary<string, T>)_innerDictionary).Contains(item);
+      }
+
+      public bool ContainsKey(string key)
+      {
+        return _innerDictionary.ContainsKey(key);
+      }
+
+      public void CopyTo(KeyValuePair<string, T>[] array, int arrayIndex)
+      {
+        ((IDictionary<string, T>)_innerDictionary).CopyTo(array, arrayIndex);
+      }
+
+      public IEnumerator<KeyValuePair<string, T>> GetEnumerator()
+      {
+        return _innerDictionary.GetEnumerator();
+      }
+
+      public void Merge(ModelStateDictionary<T> dictionary)
+      {
+        if (dictionary == null)
+        {
+          return;
+        }
+
+        foreach (var entry in dictionary)
+        {
+          this[entry.Key] = entry.Value;
+        }
+      }
+
+      public bool Remove(KeyValuePair<string, T> item)
+      {
+        return ((IDictionary<string, T>)_innerDictionary).Remove(item);
+      }
+
+      public bool Remove(string key)
+      {
+        return _innerDictionary.Remove(key);
+      }
+
+      public bool TryGetValue(string key, out T value)
+      {
+        return _innerDictionary.TryGetValue(key, out value);
+      }
+
+      IEnumerator IEnumerable.GetEnumerator()
+      {
+        return ((IEnumerable)_innerDictionary).GetEnumerator();
+      }
+    }
+
+    [Test]
+    public void SerializeNonIDictionary()
+    {
+      ModelStateDictionary<string> modelStateDictionary = new ModelStateDictionary<string>();
+      modelStateDictionary.Add("key", "value");
+
+      string json = JsonConvert.SerializeObject(modelStateDictionary);
+
+      Assert.AreEqual(@"{""key"":""value""}", json);
+
+      ModelStateDictionary<string> newModelStateDictionary = JsonConvert.DeserializeObject<ModelStateDictionary<string>>(json);
+      Assert.AreEqual(1, newModelStateDictionary.Count);
+      Assert.AreEqual("value", newModelStateDictionary["key"]);
+    }
+
+#if !SILVERLIGHT && !PocketPC
+    public class ISerializableTestObject : ISerializable
+    {
+      internal string _stringValue;
+      internal int _intValue;
+      internal DateTimeOffset _dateTimeOffsetValue;
+      internal Person _personValue;
+      internal Person _nullPersonValue;
+      internal int? _nullableInt;
+      internal bool _booleanValue;
+      internal byte _byteValue;
+      internal char _charValue;
+      internal DateTime _dateTimeValue;
+      internal decimal _decimalValue;
+      internal short _shortValue;
+      internal long _longValue;
+      internal sbyte _sbyteValue;
+      internal float _floatValue;
+      internal ushort _ushortValue;
+      internal uint _uintValue;
+      internal ulong _ulongValue;
+
+      public ISerializableTestObject(string stringValue, int intValue, DateTimeOffset dateTimeOffset, Person personValue)
+      {
+        _stringValue = stringValue;
+        _intValue = intValue;
+        _dateTimeOffsetValue = dateTimeOffset;
+        _personValue = personValue;
+        _dateTimeValue = new DateTime(0, DateTimeKind.Utc);
+      }
+
+      protected ISerializableTestObject(SerializationInfo info, StreamingContext context)
+      {
+        _stringValue = info.GetString("stringValue");
+        _intValue = info.GetInt32("intValue");
+        _dateTimeOffsetValue = (DateTimeOffset)info.GetValue("dateTimeOffsetValue", typeof(DateTimeOffset));
+        _personValue = (Person)info.GetValue("personValue", typeof(Person));
+        _nullPersonValue = (Person)info.GetValue("nullPersonValue", typeof(Person));
+        _nullableInt = (int?)info.GetValue("nullableInt", typeof(int?));
+
+        _booleanValue = info.GetBoolean("booleanValue");
+        _byteValue = info.GetByte("byteValue");
+        _charValue = info.GetChar("charValue");
+        _dateTimeValue = info.GetDateTime("dateTimeValue");
+        _decimalValue = info.GetDecimal("decimalValue");
+        _shortValue = info.GetInt16("shortValue");
+        _longValue = info.GetInt64("longValue");
+        _sbyteValue = info.GetSByte("sbyteValue");
+        _floatValue = info.GetSingle("floatValue");
+        _ushortValue = info.GetUInt16("ushortValue");
+        _uintValue = info.GetUInt32("uintValue");
+        _ulongValue = info.GetUInt64("ulongValue");
+      }
+
+      public void GetObjectData(SerializationInfo info, StreamingContext context)
+      {
+        info.AddValue("stringValue", _stringValue);
+        info.AddValue("intValue", _intValue);
+        info.AddValue("dateTimeOffsetValue", _dateTimeOffsetValue);
+        info.AddValue("personValue", _personValue);
+        info.AddValue("nullPersonValue", _nullPersonValue);
+        info.AddValue("nullableInt", null);
+
+        info.AddValue("booleanValue", _booleanValue);
+        info.AddValue("byteValue", _byteValue);
+        info.AddValue("charValue", _charValue);
+        info.AddValue("dateTimeValue", _dateTimeValue);
+        info.AddValue("decimalValue", _decimalValue);
+        info.AddValue("shortValue", _shortValue);
+        info.AddValue("longValue", _longValue);
+        info.AddValue("sbyteValue", _sbyteValue);
+        info.AddValue("floatValue", _floatValue);
+        info.AddValue("ushortValue", _ushortValue);
+        info.AddValue("uintValue", _uintValue);
+        info.AddValue("ulongValue", _ulongValue);
+      }
+    }
+
+    [Test]
+    public void SerializeISerializableTestObject()
+    {
+      Person person = new Person();
+      person.BirthDate = new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc);
+      person.LastModified = person.BirthDate;
+      person.Department = "Department!";
+      person.Name = "Name!";
+
+      DateTimeOffset dateTimeOffset = new DateTimeOffset(2000, 12, 20, 22, 59, 59, TimeSpan.FromHours(2));
+      string dateTimeOffsetText;
+#if !NET20
+      dateTimeOffsetText = @"\/Date(977345999000+0200)\/";
+#else
+      dateTimeOffsetText = @"12/20/2000 22:59:59 +02:00";
+#endif
+
+      ISerializableTestObject o = new ISerializableTestObject("String!", int.MinValue, dateTimeOffset, person);
+
+      string json = JsonConvert.SerializeObject(o, Formatting.Indented);
+      Assert.AreEqual(@"{
+  ""stringValue"": ""String!"",
+  ""intValue"": -2147483648,
+  ""dateTimeOffsetValue"": """ + dateTimeOffsetText + @""",
+  ""personValue"": {
+    ""Name"": ""Name!"",
+    ""BirthDate"": ""\/Date(946688461000)\/"",
+    ""LastModified"": ""\/Date(946688461000)\/""
+  },
+  ""nullPersonValue"": null,
+  ""nullableInt"": null,
+  ""booleanValue"": false,
+  ""byteValue"": 0,
+  ""charValue"": ""\u0000"",
+  ""dateTimeValue"": ""\/Date(-62135596800000)\/"",
+  ""decimalValue"": 0.0,
+  ""shortValue"": 0,
+  ""longValue"": 0,
+  ""sbyteValue"": 0,
+  ""floatValue"": 0.0,
+  ""ushortValue"": 0,
+  ""uintValue"": 0,
+  ""ulongValue"": 0
+}", json);
+
+      ISerializableTestObject o2 = JsonConvert.DeserializeObject<ISerializableTestObject>(json);
+      Assert.AreEqual("String!", o2._stringValue);
+      Assert.AreEqual(int.MinValue, o2._intValue);
+      Assert.AreEqual(dateTimeOffset, o2._dateTimeOffsetValue);
+      Assert.AreEqual("Name!", o2._personValue.Name);
+      Assert.AreEqual(null, o2._nullPersonValue);
+      Assert.AreEqual(null, o2._nullableInt);
+    }
+#endif
+
+    public class KVPair<TKey, TValue>
+    {
+      public TKey Key { get; set; }
+      public TValue Value { get; set; }
+
+      public KVPair(TKey k, TValue v)
+      {
+        Key = k;
+        Value = v;
+      }
+    }
+
+    [Test]
+    public void DeserializeUsingNonDefaultConstructorWithLeftOverValues()
+    {
+      List<KVPair<string, string>> kvPairs =
+        JsonConvert.DeserializeObject<List<KVPair<string, string>>>(
+          "[{\"Key\":\"Two\",\"Value\":\"2\"},{\"Key\":\"One\",\"Value\":\"1\"}]");
+
+      Assert.AreEqual(2, kvPairs.Count);
+      Assert.AreEqual("Two", kvPairs[0].Key);
+      Assert.AreEqual("2", kvPairs[0].Value);
+      Assert.AreEqual("One", kvPairs[1].Key);
+      Assert.AreEqual("1", kvPairs[1].Value);
+    }
+
+    [Test]
+    public void SerializeClassWithInheritedProtectedMember()
+    {
+      AA myA = new AA(2);
+      string json = JsonConvert.SerializeObject(myA, Formatting.Indented);
+      Assert.AreEqual(@"{
+  ""AA_field1"": 2,
+  ""AA_property1"": 2,
+  ""AA_property2"": 2,
+  ""AA_property3"": 2,
+  ""AA_property4"": 2
+}", json);
+
+      BB myB = new BB(3, 4);
+      json = JsonConvert.SerializeObject(myB, Formatting.Indented);
+      Assert.AreEqual(@"{
+  ""BB_field1"": 4,
+  ""BB_field2"": 4,
+  ""AA_field1"": 3,
+  ""BB_property1"": 4,
+  ""BB_property2"": 4,
+  ""BB_property3"": 4,
+  ""BB_property4"": 4,
+  ""BB_property5"": 4,
+  ""BB_property7"": 4,
+  ""AA_property1"": 3,
+  ""AA_property2"": 3,
+  ""AA_property3"": 3,
+  ""AA_property4"": 3
+}", json);
+    }
+
+    [Test]
+    public void DeserializeClassWithInheritedProtectedMember()
+    {
+      AA myA = JsonConvert.DeserializeObject<AA>(
+          @"{
+  ""AA_field1"": 2,
+  ""AA_field2"": 2,
+  ""AA_property1"": 2,
+  ""AA_property2"": 2,
+  ""AA_property3"": 2,
+  ""AA_property4"": 2,
+  ""AA_property5"": 2,
+  ""AA_property6"": 2
+}");
+
+      Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetField("AA_field1", BindingFlags.Instance | BindingFlags.NonPublic), myA));
+      Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetField("AA_field2", BindingFlags.Instance | BindingFlags.NonPublic), myA));
+      Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property1", BindingFlags.Instance | BindingFlags.NonPublic), myA));
+      Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property2", BindingFlags.Instance | BindingFlags.NonPublic), myA));
+      Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property3", BindingFlags.Instance | BindingFlags.NonPublic), myA));
+      Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property4", BindingFlags.Instance | BindingFlags.NonPublic), myA));
+      Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property5", BindingFlags.Instance | BindingFlags.NonPublic), myA));
+      Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property6", BindingFlags.Instance | BindingFlags.NonPublic), myA));
+
+      BB myB = JsonConvert.DeserializeObject<BB>(
+          @"{
+  ""BB_field1"": 4,
+  ""BB_field2"": 4,
+  ""AA_field1"": 3,
+  ""AA_field2"": 3,
+  ""AA_property1"": 2,
+  ""AA_property2"": 2,
+  ""AA_property3"": 2,
+  ""AA_property4"": 2,
+  ""AA_property5"": 2,
+  ""AA_property6"": 2,
+  ""BB_property1"": 3,
+  ""BB_property2"": 3,
+  ""BB_property3"": 3,
+  ""BB_property4"": 3,
+  ""BB_property5"": 3,
+  ""BB_property6"": 3,
+  ""BB_property7"": 3,
+  ""BB_property8"": 3
+}");
+
+      Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(AA).GetField("AA_field1", BindingFlags.Instance | BindingFlags.NonPublic), myB));
+      Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetField("AA_field2", BindingFlags.Instance | BindingFlags.NonPublic), myB));
+      Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property1", BindingFlags.Instance | BindingFlags.NonPublic), myB));
+      Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property2", BindingFlags.Instance | BindingFlags.NonPublic), myB));
+      Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property3", BindingFlags.Instance | BindingFlags.NonPublic), myB));
+      Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property4", BindingFlags.Instance | BindingFlags.NonPublic), myB));
+      Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property5", BindingFlags.Instance | BindingFlags.NonPublic), myB));
+      Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property6", BindingFlags.Instance | BindingFlags.NonPublic), myB));
+
+      Assert.AreEqual(4, myB.BB_field1);
+      Assert.AreEqual(4, myB.BB_field2);
+      Assert.AreEqual(3, myB.BB_property1);
+      Assert.AreEqual(3, myB.BB_property2);
+      Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(BB).GetProperty("BB_property3", BindingFlags.Instance | BindingFlags.Public), myB));
+      Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(BB).GetProperty("BB_property4", BindingFlags.Instance | BindingFlags.NonPublic), myB));
+      Assert.AreEqual(0, myB.BB_property5);
+      Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(BB).GetProperty("BB_property6", BindingFlags.Instance | BindingFlags.Public), myB));
+      Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(BB).GetProperty("BB_property7", BindingFlags.Instance | BindingFlags.Public), myB));
+      Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(BB).GetProperty("BB_property8", BindingFlags.Instance | BindingFlags.Public), myB));
+    }
+
+    public class AA
+    {
+      [JsonProperty]
+      protected int AA_field1;
+      protected int AA_field2;
+      [JsonProperty]
+      protected int AA_property1 { get; set; }
+      [JsonProperty]
+      protected int AA_property2 { get; private set; }
+      [JsonProperty]
+      protected int AA_property3 { private get; set; }
+      [JsonProperty]
+      private int AA_property4 { get; set; }
+      protected int AA_property5 { get; private set; }
+      protected int AA_property6 { private get; set; }
+
+      public AA()
+      {
+      }
+
+      public AA(int f)
+      {
+        AA_field1 = f;
+        AA_field2 = f;
+        AA_property1 = f;
+        AA_property2 = f;
+        AA_property3 = f;
+        AA_property4 = f;
+        AA_property5 = f;
+        AA_property6 = f;
+      }
+    }
+
+    public class BB : AA
+    {
+      [JsonProperty]
+      public int BB_field1;
+      public int BB_field2;
+      [JsonProperty]
+      public int BB_property1 { get; set; }
+      [JsonProperty]
+      public int BB_property2 { get; private set; }
+      [JsonProperty]
+      public int BB_property3 { private get; set; }
+      [JsonProperty]
+      private int BB_property4 { get; set; }
+      public int BB_property5 { get; private set; }
+      public int BB_property6 { private get; set; }
+      [JsonProperty]
+      public int BB_property7 { protected get; set; }
+      public int BB_property8 { protected get; set; }
+
+      public BB()
+      {
+      }
+
+      public BB(int f, int g)
+        : base(f)
+      {
+        BB_field1 = g;
+        BB_field2 = g;
+        BB_property1 = g;
+        BB_property2 = g;
+        BB_property3 = g;
+        BB_property4 = g;
+        BB_property5 = g;
+        BB_property6 = g;
+        BB_property7 = g;
+        BB_property8 = g;
+      }
+    }
+
+#if !NET20 && !SILVERLIGHT
+    public class XNodeTestObject
+    {
+      public XDocument Document { get; set; }
+      public XElement Element { get; set; }
+    }
+#endif
+
+#if !SILVERLIGHT
+    public class XmlNodeTestObject
+    {
+      public XmlDocument Document { get; set; }
+    }
+#endif
+
+#if !NET20 && !SILVERLIGHT
+    [Test]
+    public void SerializeDeserializeXNodeProperties()
+    {
+      XNodeTestObject testObject = new XNodeTestObject();
+      testObject.Document = XDocument.Parse("<root>hehe, root</root>");
+      testObject.Element = XElement.Parse(@"<fifth xmlns:json=""http://json.org"" json:Awesome=""true"">element</fifth>");
+
+      string json = JsonConvert.SerializeObject(testObject, Formatting.Indented);
+      string expected = @"{
+  ""Document"": {
+    ""root"": ""hehe, root""
+  },
+  ""Element"": {
+    ""fifth"": {
+      ""@xmlns:json"": ""http://json.org"",
+      ""@json:Awesome"": ""true"",
+      ""#text"": ""element""
+    }
+  }
+}";
+      Assert.AreEqual(expected, json);
+
+      XNodeTestObject newTestObject = JsonConvert.DeserializeObject<XNodeTestObject>(json);
+      Assert.AreEqual(testObject.Document.ToString(), newTestObject.Document.ToString());
+      Assert.AreEqual(testObject.Element.ToString(), newTestObject.Element.ToString());
+
+      Assert.IsNull(newTestObject.Element.Parent);
+    }
+#endif
+
+#if !SILVERLIGHT
+    [Test]
+    public void SerializeDeserializeXmlNodeProperties()
+    {
+      XmlNodeTestObject testObject = new XmlNodeTestObject();
+      XmlDocument document = new XmlDocument();
+      document.LoadXml("<root>hehe, root</root>");
+      testObject.Document = document;
+
+      string json = JsonConvert.SerializeObject(testObject, Formatting.Indented);
+      string expected = @"{
+  ""Document"": {
+    ""root"": ""hehe, root""
+  }
+}";
+      Assert.AreEqual(expected, json);
+
+      XmlNodeTestObject newTestObject = JsonConvert.DeserializeObject<XmlNodeTestObject>(json);
+      Assert.AreEqual(testObject.Document.InnerXml, newTestObject.Document.InnerXml);
+    }
+#endif
+
+    [Test]
+    public void FullClientMapSerialization()
+    {
+      ClientMap source = new ClientMap()
+      {
+        position = new Pos() { X = 100, Y = 200 },
+        center = new PosDouble() { X = 251.6, Y = 361.3 }
+      };
+
+      string json = JsonConvert.SerializeObject(source, new PosConverter(), new PosDoubleConverter());
+      Assert.AreEqual("{\"position\":new Pos(100,200),\"center\":new PosD(251.6,361.3)}", json);
+    }
+
+    public class ClientMap
+    {
+      public Pos position { get; set; }
+      public PosDouble center { get; set; }
+    }
+
+    public class Pos
+    {
+      public int X { get; set; }
+      public int Y { get; set; }
+    }
+
+    public class PosDouble
+    {
+      public double X { get; set; }
+      public double Y { get; set; }
+    }
+
+    public class PosConverter : JsonConverter
+    {
+      public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+      {
+        Pos p = (Pos)value;
+
+        if (p != null)
+          writer.WriteRawValue(String.Format("new Pos({0},{1})", p.X, p.Y));
+        else
+          writer.WriteNull();
+      }
+
+      public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+      {
+        throw new NotImplementedException();
+      }
+
+      public override bool CanConvert(Type objectType)
+      {
+        return objectType.IsAssignableFrom(typeof(Pos));
+      }
+    }
+
+    public class PosDoubleConverter : JsonConverter
+    {
+      public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+      {
+        PosDouble p = (PosDouble)value;
+
+        if (p != null)
+          writer.WriteRawValue(String.Format(CultureInfo.InvariantCulture, "new PosD({0},{1})", p.X, p.Y));
+        else
+          writer.WriteNull();
+      }
+
+      public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+      {
+        throw new NotImplementedException();
+      }
+
+      public override bool CanConvert(Type objectType)
+      {
+        return objectType.IsAssignableFrom(typeof(PosDouble));
+      }
+    }
+
+    [Test]
+    public void TestEscapeDictionaryStrings()
+    {
+      const string s = @"host\user";
+      string serialized = JsonConvert.SerializeObject(s);
+      Assert.AreEqual(@"""host\\user""", serialized);
+
+      Dictionary<int, object> d1 = new Dictionary<int, object>();
+      d1.Add(5, s);
+      Assert.AreEqual(@"{""5"":""host\\user""}", JsonConvert.SerializeObject(d1));
+
+      Dictionary<string, object> d2 = new Dictionary<string, object>();
+      d2.Add(s, 5);
+      Assert.AreEqual(@"{""host\\user"":5}", JsonConvert.SerializeObject(d2));
+    }
+
+    public class GenericListTestClass
+    {
+      public List<string> GenericList { get; set; }
+
+      public GenericListTestClass()
+      {
+        GenericList = new List<string>();
+      }
+    }
+
+    [Test]
+    public void DeserializeExistingGenericList()
+    {
+      GenericListTestClass c = new GenericListTestClass();
+      c.GenericList.Add("1");
+      c.GenericList.Add("2");
+
+      string json = JsonConvert.SerializeObject(c, Formatting.Indented);
+
+      GenericListTestClass newValue = JsonConvert.DeserializeObject<GenericListTestClass>(json);
+      Assert.AreEqual(2, newValue.GenericList.Count);
+      Assert.AreEqual(typeof(List<string>), newValue.GenericList.GetType());
+    }
+
+    [Test]
+    public void DeserializeSimpleKeyValuePair()
+    {
+      List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>();
+      list.Add(new KeyValuePair<string, string>("key1", "value1"));
+      list.Add(new KeyValuePair<string, string>("key2", "value2"));
+
+      string json = JsonConvert.SerializeObject(list);
+
+      Assert.AreEqual(@"[{""Key"":""key1"",""Value"":""value1""},{""Key"":""key2"",""Value"":""value2""}]", json);
+
+      List<KeyValuePair<string, string>> result = JsonConvert.DeserializeObject<List<KeyValuePair<string, string>>>(json);
+      Assert.AreEqual(2, result.Count);
+      Assert.AreEqual("key1", result[0].Key);
+      Assert.AreEqual("value1", result[0].Value);
+      Assert.AreEqual("key2", result[1].Key);
+      Assert.AreEqual("value2", result[1].Value);
+    }
+
+    [Test]
+    public void DeserializeComplexKeyValuePair()
+    {
+      DateTime dateTime = new DateTime(2000, 12, 1, 23, 1, 1, DateTimeKind.Utc);
+
+      List<KeyValuePair<string, WagePerson>> list = new List<KeyValuePair<string, WagePerson>>();
+      list.Add(new KeyValuePair<string, WagePerson>("key1", new WagePerson
+                                                              {
+                                                                BirthDate = dateTime,
+                                                                Department = "Department1",
+                                                                LastModified = dateTime,
+                                                                HourlyWage = 1
+                                                              }));
+      list.Add(new KeyValuePair<string, WagePerson>("key2", new WagePerson
+      {
+        BirthDate = dateTime,
+        Department = "Department2",
+        LastModified = dateTime,
+        HourlyWage = 2
+      }));
+
+      string json = JsonConvert.SerializeObject(list, Formatting.Indented);
+
+      Assert.AreEqual(@"[
+  {
+    ""Key"": ""key1"",
+    ""Value"": {
+      ""HourlyWage"": 1.0,
+      ""Name"": null,
+      ""BirthDate"": ""\/Date(975711661000)\/"",
+      ""LastModified"": ""\/Date(975711661000)\/""
+    }
+  },
+  {
+    ""Key"": ""key2"",
+    ""Value"": {
+      ""HourlyWage"": 2.0,
+      ""Name"": null,
+      ""BirthDate"": ""\/Date(975711661000)\/"",
+      ""LastModified"": ""\/Date(975711661000)\/""
+    }
+  }
+]", json);
+
+      List<KeyValuePair<string, WagePerson>> result = JsonConvert.DeserializeObject<List<KeyValuePair<string, WagePerson>>>(json);
+      Assert.AreEqual(2, result.Count);
+      Assert.AreEqual("key1", result[0].Key);
+      Assert.AreEqual(1, result[0].Value.HourlyWage);
+      Assert.AreEqual("key2", result[1].Key);
+      Assert.AreEqual(2, result[1].Value.HourlyWage);
+    }
+
+    public class StringListAppenderConverter : JsonConverter
+    {
+      public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+      {
+        writer.WriteValue(value);
+      }
+
+      public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+      {
+        List<string> existingStrings = (List<string>)existingValue;
+        List<string> newStrings = new List<string>(existingStrings);
+
+        reader.Read();
+
+        while (reader.TokenType != JsonToken.EndArray)
+        {
+          string s = (string)reader.Value;
+          newStrings.Add(s);
+
+          reader.Read();
+        }
+
+        return newStrings;
+      }
+
+      public override bool CanConvert(Type objectType)
+      {
+        return (objectType == typeof(List<string>));
+      }
+    }
+
+    [Test]
+    public void StringListAppenderConverterTest()
+    {
+      Movie p = new Movie();
+      p.ReleaseCountries = new List<string> { "Existing" };
+
+      JsonConvert.PopulateObject("{'ReleaseCountries':['Appended']}", p, new JsonSerializerSettings
+        {
+          Converters = new List<JsonConverter> { new StringListAppenderConverter() }
+        });
+
+      Assert.AreEqual(2, p.ReleaseCountries.Count);
+      Assert.AreEqual("Existing", p.ReleaseCountries[0]);
+      Assert.AreEqual("Appended", p.ReleaseCountries[1]);
+    }
+
+    public class StringAppenderConverter : JsonConverter
+    {
+      public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+      {
+        writer.WriteValue(value);
+      }
+
+      public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+      {
+        string existingString = (string)existingValue;
+        string newString = existingString + (string)reader.Value;
+
+        return newString;
+      }
+
+      public override bool CanConvert(Type objectType)
+      {
+        return (objectType == typeof(string));
+      }
+    }
+
+    [Test]
+    public void StringAppenderConverterTest()
+    {
+      Movie p = new Movie();
+      p.Name = "Existing,";
+
+      JsonConvert.PopulateObject("{'Name':'Appended'}", p, new JsonSerializerSettings
+      {
+        Converters = new List<JsonConverter> { new StringAppenderConverter() }
+      });
+
+      Assert.AreEqual(p.Name, "Existing,Appended");
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "Additional content found in JSON reference object. A JSON reference object should only have a $ref property.")]
+    public void SerializeRefAdditionalContent()
+    {
+      //Additional text found in JSON string after finishing deserializing object.
+      //Test 1
+      var reference = new Dictionary<string, object>();
+      reference.Add("$ref", "Persons");
+      reference.Add("$id", 1);
+
+      var child = new Dictionary<string, object>();
+      child.Add("_id", 2);
+      child.Add("Name", "Isabell");
+      child.Add("Father", reference);
+
+      var json = JsonConvert.SerializeObject(child);
+      JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "JSON reference $ref property must have a string value.")]
+    public void SerializeRefBadType()
+    {
+      //Additional text found in JSON string after finishing deserializing object.
+      //Test 1
+      var reference = new Dictionary<string, object>();
+      reference.Add("$ref", 1);
+      reference.Add("$id", 1);
+
+      var child = new Dictionary<string, object>();
+      child.Add("_id", 2);
+      child.Add("Name", "Isabell");
+      child.Add("Father", reference);
+
+      var json = JsonConvert.SerializeObject(child);
+      JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
+    }
+
+    public class ConstructorCompexIgnoredProperty
+    {
+      [JsonIgnore]
+      public Product Ignored { get; set; }
+      public string First { get; set; }
+      public int Second { get; set; }
+
+      public ConstructorCompexIgnoredProperty(string first, int second)
+      {
+        First = first;
+        Second = second;
+      }
+    }
+
+    [Test]
+    public void DeserializeIgnoredPropertyInConstructor()
+    {
+      string json = @"{""First"":""First"",""Second"":2,""Ignored"":{""Name"":""James""},""AdditionalContent"":{""LOL"":true}}";
+
+      ConstructorCompexIgnoredProperty cc = JsonConvert.DeserializeObject<ConstructorCompexIgnoredProperty>(json);
+      Assert.AreEqual("First", cc.First);
+      Assert.AreEqual(2, cc.Second);
+      Assert.AreEqual(null, cc.Ignored);
+    }
+
+    public class ShouldSerializeTestClass
+    {
+      internal bool _shouldSerializeName;
+
+      public string Name { get; set; }
+      public int Age { get; set; }
+
+      public void ShouldSerializeAge()
+      {
+        // dummy. should never be used because it doesn't return bool
+      }
+
+      public bool ShouldSerializeName()
+      {
+        return _shouldSerializeName;
+      }
+    }
+
+    [Test]
+    public void ShouldSerializeTest()
+    {
+      ShouldSerializeTestClass c = new ShouldSerializeTestClass();
+      c.Name = "James";
+      c.Age = 27;
+
+      string json = JsonConvert.SerializeObject(c, Formatting.Indented);
+
+      Assert.AreEqual(@"{
+  ""Age"": 27
+}", json);
+
+      c._shouldSerializeName = true;
+      json = JsonConvert.SerializeObject(c, Formatting.Indented);
+
+      Assert.AreEqual(@"{
+  ""Name"": ""James"",
+  ""Age"": 27
+}", json);
+
+      ShouldSerializeTestClass deserialized = JsonConvert.DeserializeObject<ShouldSerializeTestClass>(json);
+      Assert.AreEqual("James", deserialized.Name);
+      Assert.AreEqual(27, deserialized.Age);
+    }
+
+    public class Employee
+    {
+      public string Name { get; set; }
+      public Employee Manager { get; set; }
+
+      public bool ShouldSerializeManager()
+      {
+        return (Manager != this);
+      }
+    }
+
+    [Test]
+    public void ShouldSerializeExample()
+    {
+      Employee joe = new Employee();
+      joe.Name = "Joe Employee";
+      Employee mike = new Employee();
+      mike.Name = "Mike Manager";
+
+      joe.Manager = mike;
+      mike.Manager = mike;
+
+      string json = JsonConvert.SerializeObject(new[] { joe, mike }, Formatting.Indented);
+      // [
+      //   {
+      //     "Name": "Joe Employee",
+      //     "Manager": {
+      //       "Name": "Mike Manager"
+      //     }
+      //   },
+      //   {
+      //     "Name": "Mike Manager"
+      //   }
+      // ]
+
+      Console.WriteLine(json);
+    }
+
+    public class SpecifiedTestClass
+    {
+      private bool _nameSpecified;
+
+      public string Name { get; set; }
+      public int Age { get; set; }
+      public int Weight { get; set; }
+      public int Height { get; set; }
+
+      // dummy. should never be used because it isn't of type bool
+      [JsonIgnore]
+      public long AgeSpecified { get; set; }
+
+      [JsonIgnore]
+      public bool NameSpecified
+      {
+        get { return _nameSpecified; }
+        set { _nameSpecified = value; }
+      }
+
+      [JsonIgnore]
+      public bool WeightSpecified;
+
+      [JsonIgnore]
+      [System.Xml.Serialization.XmlIgnoreAttribute]
+      public bool HeightSpecified;
+    }
+
+    [Test]
+    public void SpecifiedTest()
+    {
+      SpecifiedTestClass c = new SpecifiedTestClass();
+      c.Name = "James";
+      c.Age = 27;
+      c.NameSpecified = false;
+
+      string json = JsonConvert.SerializeObject(c, Formatting.Indented);
+
+      Assert.AreEqual(@"{
+  ""Age"": 27
+}", json);
+
+      SpecifiedTestClass deserialized = JsonConvert.DeserializeObject<SpecifiedTestClass>(json);
+      Assert.IsNull(deserialized.Name);
+      Assert.IsFalse(deserialized.NameSpecified);
+      Assert.IsFalse(deserialized.WeightSpecified);
+      Assert.IsFalse(deserialized.HeightSpecified);
+      Assert.AreEqual(27, deserialized.Age);
+
+      c.NameSpecified = true;
+      c.WeightSpecified = true;
+      c.HeightSpecified = true;
+      json = JsonConvert.SerializeObject(c, Formatting.Indented);
+
+      Assert.AreEqual(@"{
+  ""Name"": ""James"",
+  ""Age"": 27,
+  ""Weight"": 0,
+  ""Height"": 0
+}", json);
+
+      deserialized = JsonConvert.DeserializeObject<SpecifiedTestClass>(json);
+      Assert.AreEqual("James", deserialized.Name);
+      Assert.IsTrue(deserialized.NameSpecified);
+      Assert.IsTrue(deserialized.WeightSpecified);
+      Assert.IsTrue(deserialized.HeightSpecified);
+      Assert.AreEqual(27, deserialized.Age);
+    }
+
+    //    [Test]
+    //    public void XmlSerializerSpecifiedTrueTest()
+    //    {
+    //      XmlSerializer s = new XmlSerializer(typeof(OptionalOrder));
+
+    //      StringWriter sw = new StringWriter();
+    //      s.Serialize(sw, new OptionalOrder() { FirstOrder = "First", FirstOrderSpecified = true });
+
+    //      Console.WriteLine(sw.ToString());
+
+    //      string xml = @"<?xml version=""1.0"" encoding=""utf-16""?>
+    //<OptionalOrder xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
+    //  <FirstOrder>First</FirstOrder>
+    //</OptionalOrder>";
+
+    //      OptionalOrder o = (OptionalOrder)s.Deserialize(new StringReader(xml));
+    //      Console.WriteLine(o.FirstOrder);
+    //      Console.WriteLine(o.FirstOrderSpecified);
+    //    }
+
+    //    [Test]
+    //    public void XmlSerializerSpecifiedFalseTest()
+    //    {
+    //      XmlSerializer s = new XmlSerializer(typeof(OptionalOrder));
+
+    //      StringWriter sw = new StringWriter();
+    //      s.Serialize(sw, new OptionalOrder() { FirstOrder = "First", FirstOrderSpecified = false });
+
+    //      Console.WriteLine(sw.ToString());
+
+    //      //      string xml = @"<?xml version=""1.0"" encoding=""utf-16""?>
+    //      //<OptionalOrder xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
+    //      //  <FirstOrder>First</FirstOrder>
+    //      //</OptionalOrder>";
+
+    //      //      OptionalOrder o = (OptionalOrder)s.Deserialize(new StringReader(xml));
+    //      //      Console.WriteLine(o.FirstOrder);
+    //      //      Console.WriteLine(o.FirstOrderSpecified);
+    //    }
+
+    public class OptionalOrder
+    {
+      // This field shouldn't be serialized 
+      // if it is uninitialized.
+      public string FirstOrder;
+      // Use the XmlIgnoreAttribute to ignore the 
+      // special field named "FirstOrderSpecified".
+      [System.Xml.Serialization.XmlIgnoreAttribute]
+      public bool FirstOrderSpecified;
+    }
+
+    public class FamilyDetails
+    {
+      public string Name { get; set; }
+      public int NumberOfChildren { get; set; }
+
+      [JsonIgnore]
+      public bool NumberOfChildrenSpecified { get; set; }
+    }
+
+    [Test]
+    public void SpecifiedExample()
+    {
+      FamilyDetails joe = new FamilyDetails();
+      joe.Name = "Joe Family Details";
+      joe.NumberOfChildren = 4;
+      joe.NumberOfChildrenSpecified = true;
+
+      FamilyDetails martha = new FamilyDetails();
+      martha.Name = "Martha Family Details";
+      martha.NumberOfChildren = 3;
+      martha.NumberOfChildrenSpecified = false;
+
+      string json = JsonConvert.SerializeObject(new[] { joe, martha }, Formatting.Indented);
+      //[
+      //  {
+      //    "Name": "Joe Family Details",
+      //    "NumberOfChildren": 4
+      //  },
+      //  {
+      //    "Name": "Martha Family Details"
+      //  }
+      //]
+      Console.WriteLine(json);
+
+      string mikeString = "{\"Name\": \"Mike Person\"}";
+      FamilyDetails mike = JsonConvert.DeserializeObject<FamilyDetails>(mikeString);
+
+      Console.WriteLine("mikeString specifies number of children: {0}", mike.NumberOfChildrenSpecified);
+
+      string mikeFullDisclosureString = "{\"Name\": \"Mike Person\", \"NumberOfChildren\": \"0\"}";
+      mike = JsonConvert.DeserializeObject<FamilyDetails>(mikeFullDisclosureString);
+
+      Console.WriteLine("mikeString specifies number of children: {0}", mike.NumberOfChildrenSpecified);
+    }
+
+    public class DictionaryKey
+    {
+      public string Value { get; set; }
+
+      public override string ToString()
+      {
+        return Value;
+      }
+
+      public static implicit operator DictionaryKey(string value)
+      {
+        return new DictionaryKey() { Value = value };
+      }
+    }
+
+    [Test]
+    public void SerializeDeserializeDictionaryKey()
+    {
+      Dictionary<DictionaryKey, string> dictionary = new Dictionary<DictionaryKey, string>();
+
+      dictionary.Add(new DictionaryKey() { Value = "First!" }, "First");
+      dictionary.Add(new DictionaryKey() { Value = "Second!" }, "Second");
+
+      string json = JsonConvert.SerializeObject(dictionary, Formatting.Indented);
+
+      Assert.AreEqual(@"{
+  ""First!"": ""First"",
+  ""Second!"": ""Second""
+}", json);
+
+      Dictionary<DictionaryKey, string> newDictionary =
+        JsonConvert.DeserializeObject<Dictionary<DictionaryKey, string>>(json);
+
+      Assert.AreEqual(2, newDictionary.Count);
+    }
+
+    [Test]
+    public void SerializeNullableArray()
+    {
+      string jsonText = JsonConvert.SerializeObject(new double?[] { 2.4, 4.3, null }, Formatting.Indented);
+
+      Assert.AreEqual(@"[
+  2.4,
+  4.3,
+  null
+]", jsonText);
+
+      double?[] d = (double?[])JsonConvert.DeserializeObject(jsonText, typeof(double?[]));
+
+      Assert.AreEqual(3, d.Length);
+      Assert.AreEqual(2.4, d[0]);
+      Assert.AreEqual(4.3, d[1]);
+      Assert.AreEqual(null, d[2]);
+    }
+
+#if !SILVERLIGHT && !NET20 && !PocketPC
+    [Test]
+    public void SerializeHashSet()
+    {
+      string jsonText = JsonConvert.SerializeObject(new HashSet<string>()
+                                                      {
+                                                        "One",
+                                                        "2",
+                                                        "III"
+                                                      }, Formatting.Indented);
+
+      Assert.AreEqual(@"[
+  ""One"",
+  ""2"",
+  ""III""
+]", jsonText);
+
+      HashSet<string> d = JsonConvert.DeserializeObject<HashSet<string>>(jsonText);
+
+      Assert.AreEqual(3, d.Count);
+      Assert.IsTrue(d.Contains("One"));
+      Assert.IsTrue(d.Contains("2"));
+      Assert.IsTrue(d.Contains("III"));
+    }
+#endif
+
+    private class MyClass
+    {
+      public byte[] Prop1 { get; set; }
+
+      public MyClass()
+      {
+        Prop1 = new byte[0];
+      }
+    }
+
+    [Test]
+    public void DeserializeByteArray()
+    {
+      JsonSerializer serializer1 = new JsonSerializer();
+      serializer1.Converters.Add(new IsoDateTimeConverter());
+      serializer1.NullValueHandling = NullValueHandling.Ignore;
+
+      string json = @"[{""Prop1"":""""},{""Prop1"":""""}]";
+
+      JsonTextReader reader = new JsonTextReader(new StringReader(json));
+
+      MyClass[] z = (MyClass[])serializer1.Deserialize(reader, typeof(MyClass[]));
+      Assert.AreEqual(2, z.Length);
+      Assert.AreEqual(0, z[0].Prop1.Length);
+      Assert.AreEqual(0, z[1].Prop1.Length);
+    }
+
+#if !NET20 && !PocketPC && !SILVERLIGHT
+    public class StringDictionaryTestClass
+    {
+      public StringDictionary StringDictionaryProperty { get; set; }
+    }
+
+    [Test]
+    [ExpectedException(typeof(Exception), ExpectedMessage = "Cannot create and populate list type System.Collections.Specialized.StringDictionary.")]
+    public void StringDictionaryTest()
+    {
+      StringDictionaryTestClass s1 = new StringDictionaryTestClass()
+        {
+          StringDictionaryProperty = new StringDictionary()
+            {
+              {"1", "One"},
+              {"2", "II"},
+              {"3", "3"}              
+            }
+        };
+
+      string json = JsonConvert.SerializeObject(s1, Formatting.Indented);
+
+      JsonConvert.DeserializeObject<StringDictionaryTestClass>(json);
+    }
+#endif
+
+    [JsonObject(MemberSerialization.OptIn)]
+    public struct StructWithAttribute
+    {
+      public string MyString { get; set; }
+      [JsonProperty]
+      public int MyInt { get; set; }
+    }
+
+    [Test]
+    public void SerializeStructWithJsonObjectAttribute()
+    {
+      StructWithAttribute testStruct = new StructWithAttribute
+        {
+          MyInt = int.MaxValue
+        };
+
+      string json = JsonConvert.SerializeObject(testStruct, Formatting.Indented);
+
+      Assert.AreEqual(@"{
+  ""MyInt"": 2147483647
+}", json);
+
+      StructWithAttribute newStruct = JsonConvert.DeserializeObject<StructWithAttribute>(json);
+
+      Assert.AreEqual(int.MaxValue, newStruct.MyInt);
+    }
+
+    public class TimeZoneOffsetObject
+    {
+      public DateTimeOffset Offset { get; set; }
+    }
+
+#if !NET20
+    [Test]
+    public void ReadWriteTimeZoneOffset()
+    {
+      var serializeObject = JsonConvert.SerializeObject(new TimeZoneOffsetObject
+      {
+        Offset = new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(6))
+      });
+
+      Assert.AreEqual("{\"Offset\":\"\\/Date(946663200000+0600)\\/\"}", serializeObject);
+      var deserializeObject = JsonConvert.DeserializeObject<TimeZoneOffsetObject>(serializeObject);
+      Assert.AreEqual(TimeSpan.FromHours(6), deserializeObject.Offset.Offset);
+      Assert.AreEqual(new DateTime(2000, 1, 1), deserializeObject.Offset.Date);
+    }
+
+    [Test]
+    public void DeserializePropertyNullableDateTimeOffsetExact()
+    {
+      NullableDateTimeTestClass d = JsonConvert.DeserializeObject<NullableDateTimeTestClass>("{\"DateTimeOffsetField\":\"\\/Date(946663200000+0600)\\/\"}");
+      Assert.AreEqual(new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(6)), d.DateTimeOffsetField);
+    }
+#endif
+
+    public abstract class LogEvent
+    {
+      [JsonProperty("event")]
+      public abstract string EventName { get; }
+    }
+
+    public class DerivedEvent : LogEvent
+    {
+      public override string EventName { get { return "derived"; } }
+    }
+
+    [Test]
+    public void OverridenPropertyMembers()
+    {
+      string json = JsonConvert.SerializeObject(new DerivedEvent(), Formatting.Indented);
+
+      Assert.AreEqual(@"{
+  ""event"": ""derived""
+}", json);
+    }
+
+#if !(NET35 || NET20 || WINDOWS_PHONE)
+    [Test]
+    public void SerializeExpandoObject()
+    {
+      dynamic expando = new ExpandoObject();
+      expando.Int = 1;
+      expando.Decimal = 99.9d;
+      expando.Complex = new ExpandoObject();
+      expando.Complex.String = "I am a string";
+      expando.Complex.DateTime = new DateTime(2000, 12, 20, 18, 55, 0, DateTimeKind.Utc);
+
+      string json = JsonConvert.SerializeObject(expando, Formatting.Indented);
+      Assert.AreEqual(@"{
+  ""Int"": 1,
+  ""Decimal"": 99.9,
+  ""Complex"": {
+    ""String"": ""I am a string"",
+    ""DateTime"": ""\/Date(977338500000)\/""
+  }
+}", json);
+
+      IDictionary<string, object> newExpando = JsonConvert.DeserializeObject<ExpandoObject>(json);
+
+      Assert.IsInstanceOfType(typeof(long), newExpando["Int"]);
+      Assert.AreEqual(expando.Int, newExpando["Int"]);
+
+      Assert.IsInstanceOfType(typeof(double), newExpando["Decimal"]);
+      Assert.AreEqual(expando.Decimal, newExpando["Decimal"]);
+
+      Assert.IsInstanceOfType(typeof(ExpandoObject), newExpando["Complex"]);
+      IDictionary<string, object> o = (ExpandoObject)newExpando["Complex"];
+
+      Assert.IsInstanceOfType(typeof(string), o["String"]);
+      Assert.AreEqual(expando.Complex.String, o["String"]);
+
+      Assert.IsInstanceOfType(typeof(DateTime), o["DateTime"]);
+      Assert.AreEqual(expando.Complex.DateTime, o["DateTime"]);
+    }
+#endif
+
+    [Test]
+    public void DeserializeDecimalExact()
+    {
+      decimal d = JsonConvert.DeserializeObject<decimal>("123456789876543.21");
+      Assert.AreEqual(123456789876543.21m, d);
+    }
+
+    [Test]
+    public void DeserializeNullableDecimalExact()
+    {
+      decimal? d = JsonConvert.DeserializeObject<decimal?>("123456789876543.21");
+      Assert.AreEqual(123456789876543.21m, d);
+    }
+
+    [Test]
+    public void DeserializeDecimalPropertyExact()
+    {
+      string json = "{Amount:123456789876543.21}";
+      Invoice i = JsonConvert.DeserializeObject<Invoice>(json);
+      Assert.AreEqual(123456789876543.21m, i.Amount);
+    }
+
+    [Test]
+    public void DeserializeDecimalArrayExact()
+    {
+      string json = "[123456789876543.21]";
+      IList<decimal> a = JsonConvert.DeserializeObject<IList<decimal>>(json);
+      Assert.AreEqual(123456789876543.21m, a[0]);
+    }
+
+    [Test]
+    public void DeserializeDecimalDictionaryExact()
+    {
+      string json = "{'Value':123456789876543.21}";
+      IDictionary<string, decimal> d = JsonConvert.DeserializeObject<IDictionary<string, decimal>>(json);
+      Assert.AreEqual(123456789876543.21m, d["Value"]);
+    }
+
+    public struct Vector
+    {
+      public float X;
+      public float Y;
+      public float Z;
+
+      public override string ToString()
+      {
+        return string.Format("({0},{1},{2})", X, Y, Z);
+      }
+    }
+
+    public class VectorParent
+    {
+      public Vector Position;
+    }
+
+    [Test]
+    public void DeserializeStructProperty()
+    {
+      VectorParent obj = new VectorParent();
+      obj.Position = new Vector { X = 1, Y = 2, Z = 3 };
+
+      string str = JsonConvert.SerializeObject(obj);
+
+      obj = JsonConvert.DeserializeObject<VectorParent>(str);
+
+      Assert.AreEqual(1, obj.Position.X);
+      Assert.AreEqual(2, obj.Position.Y);
+      Assert.AreEqual(3, obj.Position.Z);
+    }
+
+    [JsonObject(MemberSerialization.OptIn)]
+    public class Derived : Base
+    {
+      [JsonProperty]
+      public string IDoWork { get; private set; }
+
+      private Derived() { }
+
+      internal Derived(string dontWork, string doWork)
+        : base(dontWork)
+      {
+        IDoWork = doWork;
+      }
+    }
+
+    [JsonObject(MemberSerialization.OptIn)]
+    public class Base
+    {
+      [JsonProperty]
+      public string IDontWork { get; private set; }
+
+      protected Base() { }
+
+      internal Base(string dontWork)
+      {
+        IDontWork = dontWork;
+      }
+    }
+
+    [Test]
+    public void PrivateSetterOnBaseClassProperty()
+    {
+      var derived = new Derived("meh", "woo");
+
+      var settings = new JsonSerializerSettings
+      {
+        TypeNameHandling = TypeNameHandling.Objects,
+        ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
+      };
+
+      string json = JsonConvert.SerializeObject(derived, Formatting.Indented, settings);
+
+      var meh = JsonConvert.DeserializeObject<Base>(json, settings);
+
+      Assert.AreEqual(((Derived)meh).IDoWork, "woo");
+      Assert.AreEqual(meh.IDontWork, "meh");
+    }
+
+#if !(SILVERLIGHT || PocketPC || NET20)
+    [DataContract]
+    public struct StructISerializable : ISerializable
+    {
+      private string _name;
+
+      public StructISerializable(SerializationInfo info, StreamingContext context)
+      {
+        _name = info.GetString("Name");
+      }
+
+      [DataMember]
+      public string Name
+      {
+        get { return _name; }
+        set { _name = value; }
+      }
+
+      public void GetObjectData(SerializationInfo info, StreamingContext context)
+      {
+        info.AddValue("Name", _name);
+      }
+    }
+
+    [DataContract]
+    public class NullableStructPropertyClass
+    {
+      private StructISerializable _foo1;
+      private StructISerializable? _foo2;
+
+      [DataMember]
+      public StructISerializable Foo1
+      {
+        get { return _foo1; }
+        set { _foo1 = value; }
+      }
+
+      [DataMember]
+      public StructISerializable? Foo2
+      {
+        get { return _foo2; }
+        set { _foo2 = value; }
+      }
+    }
+
+    [Test]
+    public void DeserializeNullableStruct()
+    {
+      NullableStructPropertyClass nullableStructPropertyClass = new NullableStructPropertyClass();
+      nullableStructPropertyClass.Foo1 = new StructISerializable() { Name = "foo 1" };
+      nullableStructPropertyClass.Foo2 = new StructISerializable() { Name = "foo 2" };
+
+      NullableStructPropertyClass barWithNull = new NullableStructPropertyClass();
+      barWithNull.Foo1 = new StructISerializable() { Name = "foo 1" };
+      barWithNull.Foo2 = null;
+
+      //throws error on deserialization because bar1.Foo2 is of type Foo?
+      string s = JsonConvert.SerializeObject(nullableStructPropertyClass);
+      NullableStructPropertyClass deserialized = deserialize(s);
+      Assert.AreEqual(deserialized.Foo1.Name, "foo 1");
+      Assert.AreEqual(deserialized.Foo2.Value.Name, "foo 2");
+
+      //no error Foo2 is null
+      s = JsonConvert.SerializeObject(barWithNull);
+      deserialized = deserialize(s);
+      Assert.AreEqual(deserialized.Foo1.Name, "foo 1");
+      Assert.AreEqual(deserialized.Foo2, null);
+    }
+
+
+    static NullableStructPropertyClass deserialize(string serStr)
+    {
+      return JsonConvert.DeserializeObject<NullableStructPropertyClass>(
+        serStr,
+        new JsonSerializerSettings
+        {
+          NullValueHandling = NullValueHandling.Ignore,
+          MissingMemberHandling = MissingMemberHandling.Ignore
+        });
+    }
+#endif
+
+    public class Response
+    {
+      public string Name { get; set; }
+      public JToken Data { get; set; }
+    }
+
+    [Test]
+    public void DeserializeJToken()
+    {
+      Response response = new Response
+        {
+          Name = "Success",
+          Data = new JObject(new JProperty("First", "Value1"), new JProperty("Second", "Value2"))
+        };
+
+      string json = JsonConvert.SerializeObject(response, Formatting.Indented);
+
+      Response deserializedResponse = JsonConvert.DeserializeObject<Response>(json);
+
+      Assert.AreEqual("Success", deserializedResponse.Name);
+      Assert.IsTrue(deserializedResponse.Data.DeepEquals(response.Data));
+    }
+
+    public abstract class Test<T>
+    {
+      public abstract T Value { get; set; }
+    }
+
+    [JsonObject(MemberSerialization.OptIn)]
+    public class DecimalTest : Test<decimal>
+    {
+      protected DecimalTest() { }
+      public DecimalTest(decimal val)
+      {
+        Value = val;
+      }
+
+      [JsonProperty]
+      public override decimal Value { get; set; }
+    }
+
+    [Test]
+    public void OnError()
+    {
+      var data = new DecimalTest(decimal.MinValue);
+      var json = JsonConvert.SerializeObject(data);
+      var obj = JsonConvert.DeserializeObject<DecimalTest>(json);
+
+      Assert.AreEqual(decimal.MinValue, obj.Value);
+    }
+
+    public class NonPublicConstructorWithJsonConstructor
+    {
+      public string Value { get; private set; }
+      public string Constructor { get; private set; }
+
+      [JsonConstructor]
+      private NonPublicConstructorWithJsonConstructor()
+      {
+        Constructor = "NonPublic";
+      }
+
+      public NonPublicConstructorWithJsonConstructor(string value)
+      {
+        Value = value;
+        Constructor = "Public Paramatized";
+      }
+    }
+
+    [Test]
+    public void NonPublicConstructorWithJsonConstructorTest()
+    {
+      NonPublicConstructorWithJsonConstructor c = JsonConvert.DeserializeObject<NonPublicConstructorWithJsonConstructor>("{}");
+      Assert.AreEqual("NonPublic", c.Constructor);
+    }
+
+    public class PublicConstructorOverridenByJsonConstructor
+    {
+      public string Value { get; private set; }
+      public string Constructor { get; private set; }
+
+      public PublicConstructorOverridenByJsonConstructor()
+      {
+        Constructor = "NonPublic";
+      }
+
+      [JsonConstructor]
+      public PublicConstructorOverridenByJsonConstructor(string value)
+      {
+        Value = value;
+        Constructor = "Public Paramatized";
+      }
+    }
+
+    [Test]
+    public void PublicConstructorOverridenByJsonConstructorTest()
+    {
+      PublicConstructorOverridenByJsonConstructor c = JsonConvert.DeserializeObject<PublicConstructorOverridenByJsonConstructor>("{Value:'value!'}");
+      Assert.AreEqual("Public Paramatized", c.Constructor);
+      Assert.AreEqual("value!", c.Value);
+    }
+
+    public class MultipleParamatrizedConstructorsJsonConstructor
+    {
+      public string Value { get; private set; }
+      public int Age { get; private set; }
+      public string Constructor { get; private set; }
+
+      public MultipleParamatrizedConstructorsJsonConstructor(string value)
+      {
+        Value = value;
+        Constructor = "Public Paramatized 1";
+      }
+
+      [JsonConstructor]
+      public MultipleParamatrizedConstructorsJsonConstructor(string value, int age)
+      {
+        Value = value;
+        Age = age;
+        Constructor = "Public Paramatized 2";
+      }
+    }
+
+    [Test]
+    public void MultipleParamatrizedConstructorsJsonConstructorTest()
+    {
+      MultipleParamatrizedConstructorsJsonConstructor c = JsonConvert.DeserializeObject<MultipleParamatrizedConstructorsJsonConstructor>("{Value:'value!', Age:1}");
+      Assert.AreEqual("Public Paramatized 2", c.Constructor);
+      Assert.AreEqual("value!", c.Value);
+      Assert.AreEqual(1, c.Age);
+    }
+
+    public class EnumerableClass
+    {
+      public IEnumerable<string> Enumerable { get; set; }
+    }
+
+    [Test]
+    public void DeserializeEnumerable()
+    {
+      EnumerableClass c = new EnumerableClass
+        {
+          Enumerable = new List<string> { "One", "Two", "Three" }
+        };
+
+      string json = JsonConvert.SerializeObject(c, Formatting.Indented);
+
+      Assert.AreEqual(@"{
+  ""Enumerable"": [
+    ""One"",
+    ""Two"",
+    ""Three""
+  ]
+}", json);
+
+      EnumerableClass c2 = JsonConvert.DeserializeObject<EnumerableClass>(json);
+
+      Assert.AreEqual("One", c2.Enumerable.ElementAt(0));
+      Assert.AreEqual("Two", c2.Enumerable.ElementAt(1));
+      Assert.AreEqual("Three", c2.Enumerable.ElementAt(2));
+    }
+
+    [JsonObject(MemberSerialization.OptIn)]
+    public class ItemBase
+    {
+      [JsonProperty]
+      public string Name { get; set; }
+    }
+
+    public class ComplexItem : ItemBase
+    {
+      public Stream Source { get; set; }
+    }
+
+    [Test]
+    public void SerializeAttributesOnBase()
+    {
+      ComplexItem i = new ComplexItem();
+
+      string json = JsonConvert.SerializeObject(i, Formatting.Indented);
+
+      Assert.AreEqual(@"{
+  ""Name"": null
+}", json);
+    }
+
+    public class DeserializeStringConvert
+    {
+      public string Name { get; set; }
+      public int Age { get; set; }
+      public double Height { get; set; }
+      public decimal Price { get; set; }
+    }
+
+    [Test]
+    public void DeserializeStringEnglish()
+    {
+      string json = @"{
+  'Name': 'James Hughes',
+  'Age': '40',
+  'Height': '44.4',
+  'Price': '4'
+}";
+
+      DeserializeStringConvert p = JsonConvert.DeserializeObject<DeserializeStringConvert>(json);
+      Assert.AreEqual(40, p.Age);
+      Assert.AreEqual(44.4, p.Height);
+      Assert.AreEqual(4d, p.Price);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "Error converting value {null} to type 'System.DateTime'.")]
+    public void DeserializeNullDateTimeValueTest()
+    {
+      JsonConvert.DeserializeObject("null", typeof(DateTime));
+    }
+
+    [Test]
+    public void DeserializeNullNullableDateTimeValueTest()
+    {
+      object dateTime = JsonConvert.DeserializeObject("null", typeof(DateTime?));
+
+      Assert.IsNull(dateTime);
+    }
+
+    [Test]
+    public void MultiIndexSuperTest()
+    {
+      MultiIndexSuper e = new MultiIndexSuper();
+
+      string json = JsonConvert.SerializeObject(e, Formatting.Indented);
+
+      Assert.AreEqual(@"{}", json);
+    }
+
+    public class MultiIndexSuper : MultiIndexBase
+    {
+      
+    }
+
+    public abstract class MultiIndexBase
+    {
+      protected internal object this[string propertyName]
+      {
+        get { return null; }
+        set { }
+      }
+      protected internal object this[object property]
+      {
+        get { return null; }
+        set { }
+      }
+    }
+
+    public class CommentTestClass
+    {
+      public bool Indexed { get; set; }
+      public int StartYear { get; set; }
+      public IList<decimal> Values { get; set; }
+    }
+
+    [Test]
+    public void CommentTestClassTest()
+    {
+      string json = @"{""indexed"":true, ""startYear"":1939, ""values"":
+                            [  3000,  /* 1940-1949 */
+                               3000,   3600,   3600,   3600,   3600,   4200,   4200,   4200,   4200,   4800,  /* 1950-1959 */
+                               4800,   4800,   4800,   4800,   4800,   4800,   6600,   6600,   7800,   7800,  /* 1960-1969 */
+                               7800,   7800,   9000,  10800,  13200,  14100,  15300,  16500,  17700,  22900,  /* 1970-1979 */
+                              25900,  29700,  32400,  35700,  37800,  39600,  42000,  43800,  45000,  48000,  /* 1980-1989 */
+                              51300,  53400,  55500,  57600,  60600,  61200,  62700,  65400,  68400,  72600,  /* 1990-1999 */
+                              76200,  80400,  84900,  87000,  87900,  90000,  94200,  97500, 102000, 106800,  /* 2000-2009 */
+                             106800, 106800]  /* 2010-2011 */
+                                }";
+
+      CommentTestClass commentTestClass = JsonConvert.DeserializeObject<CommentTestClass>(json);
+
+      Assert.AreEqual(true, commentTestClass.Indexed);
+      Assert.AreEqual(1939, commentTestClass.StartYear);
+      Assert.AreEqual(63, commentTestClass.Values.Count);
+    }
+
+    class DTOWithParameterisedConstructor
+    {
+      public DTOWithParameterisedConstructor(string A)
+      {
+        this.A = A;
+        B = 2;
+      }
+
+      public string A { get; set; }
+      public int? B { get; set; }
+    }
+
+    class DTOWithoutParameterisedConstructor
+    {
+      public DTOWithoutParameterisedConstructor()
+      {
+        B = 2;
+      }
+
+      public string A { get; set; }
+      public int? B { get; set; }
+    }
+
+    [Test]
+    public void PopulationBehaviourForOmittedPropertiesIsTheSameForParameterisedConstructorAsForDefaultConstructor()
+    {
+      string json = @"{A:""Test""}";
+
+      var withoutParameterisedConstructor = JsonConvert.DeserializeObject<DTOWithoutParameterisedConstructor>(json);
+      var withParameterisedConstructor = JsonConvert.DeserializeObject<DTOWithParameterisedConstructor>(json);
+      Assert.AreEqual(withoutParameterisedConstructor.B, withParameterisedConstructor.B);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/MissingMemberHandlingTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/MissingMemberHandlingTests.cs
new file mode 100644 (file)
index 0000000..fcdef4c
--- /dev/null
@@ -0,0 +1,137 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.IO;
+using Newtonsoft.Json.Converters;
+using Newtonsoft.Json.Tests.TestObjects;
+using NUnit.Framework;
+
+namespace Newtonsoft.Json.Tests.Serialization
+{
+  public class MissingMemberHandlingTests : TestFixtureBase
+  {
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"Could not find member 'Price' on object of type 'ProductShort'")]
+    public void MissingMemberDeserialize()
+    {
+      Product product = new Product();
+
+      product.Name = "Apple";
+      product.ExpiryDate = new DateTime(2008, 12, 28);
+      product.Price = 3.99M;
+      product.Sizes = new string[] { "Small", "Medium", "Large" };
+
+      string output = JsonConvert.SerializeObject(product);
+      //{
+      //  "Name": "Apple",
+      //  "ExpiryDate": new Date(1230422400000),
+      //  "Price": 3.99,
+      //  "Sizes": [
+      //    "Small",
+      //    "Medium",
+      //    "Large"
+      //  ]
+      //}
+
+      ProductShort deserializedProductShort = (ProductShort)JsonConvert.DeserializeObject(output, typeof(ProductShort), new JsonSerializerSettings { MissingMemberHandling = MissingMemberHandling.Error });
+    }
+
+    [Test]
+    public void MissingMemberDeserializeOkay()
+    {
+      Product product = new Product();
+
+      product.Name = "Apple";
+      product.ExpiryDate = new DateTime(2008, 12, 28);
+      product.Price = 3.99M;
+      product.Sizes = new string[] { "Small", "Medium", "Large" };
+
+      string output = JsonConvert.SerializeObject(product);
+      //{
+      //  "Name": "Apple",
+      //  "ExpiryDate": new Date(1230422400000),
+      //  "Price": 3.99,
+      //  "Sizes": [
+      //    "Small",
+      //    "Medium",
+      //    "Large"
+      //  ]
+      //}
+
+      JsonSerializer jsonSerializer = new JsonSerializer();
+      jsonSerializer.MissingMemberHandling = MissingMemberHandling.Ignore;
+
+      object deserializedValue;
+
+      using (JsonReader jsonReader = new JsonTextReader(new StringReader(output)))
+      {
+        deserializedValue = jsonSerializer.Deserialize(jsonReader, typeof(ProductShort));
+      }
+
+      ProductShort deserializedProductShort = (ProductShort)deserializedValue;
+
+      Assert.AreEqual("Apple", deserializedProductShort.Name);
+      Assert.AreEqual(new DateTime(2008, 12, 28), deserializedProductShort.ExpiryDate);
+      Assert.AreEqual("Small", deserializedProductShort.Sizes[0]);
+      Assert.AreEqual("Medium", deserializedProductShort.Sizes[1]);
+      Assert.AreEqual("Large", deserializedProductShort.Sizes[2]);
+    }
+
+    [Test]
+    public void MissingMemberIgnoreComplexValue()
+    {
+      JsonSerializer serializer = new JsonSerializer { MissingMemberHandling = MissingMemberHandling.Ignore };
+      serializer.Converters.Add(new JavaScriptDateTimeConverter());
+
+      string response = @"{""PreProperty"":1,""DateProperty"":new Date(1225962698973),""PostProperty"":2}";
+
+      MyClass myClass = (MyClass)serializer.Deserialize(new StringReader(response), typeof(MyClass));
+
+      Assert.AreEqual(1, myClass.PreProperty);
+      Assert.AreEqual(2, myClass.PostProperty);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "Could not find member 'Missing' on object of type 'DoubleClass'")]
+    public void MissingMemeber()
+    {
+      string json = @"{""Missing"":1}";
+
+      JsonConvert.DeserializeObject<DoubleClass>(json, new JsonSerializerSettings { MissingMemberHandling = MissingMemberHandling.Error });
+    }
+
+    [Test]
+    public void MissingJson()
+    {
+      string json = @"{}";
+
+      JsonConvert.DeserializeObject<DoubleClass>(json, new JsonSerializerSettings
+        {
+          MissingMemberHandling = MissingMemberHandling.Error
+        });
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/NullValueHandlingTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/NullValueHandlingTests.cs
new file mode 100644 (file)
index 0000000..93acb9f
--- /dev/null
@@ -0,0 +1,121 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Tests.TestObjects;
+using NUnit.Framework;
+
+namespace Newtonsoft.Json.Tests.Serialization
+{
+  public class NullValueHandlingTests : TestFixtureBase
+  {
+    [Test]
+    public void DeserializeNullIntoDateTime()
+    {
+      DateTimeTestClass c = JsonConvert.DeserializeObject<DateTimeTestClass>(@"{DateTimeField:null}", new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
+      Assert.AreEqual(c.DateTimeField, default(DateTime));
+    }
+
+    [Test]
+    public void DeserializeEmptyStringIntoDateTimeWithEmptyStringDefaultValue()
+    {
+      DateTimeTestClass c = JsonConvert.DeserializeObject<DateTimeTestClass>(@"{DateTimeField:""""}", new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
+      Assert.AreEqual(c.DateTimeField, default(DateTime));
+    }
+
+    [Test]
+    public void NullValueHandlingSerialization()
+    {
+      Store s1 = new Store();
+
+      JsonSerializer jsonSerializer = new JsonSerializer();
+      jsonSerializer.NullValueHandling = NullValueHandling.Ignore;
+
+      StringWriter sw = new StringWriter();
+      jsonSerializer.Serialize(sw, s1);
+
+      //JsonConvert.ConvertDateTimeToJavaScriptTicks(s1.Establised.DateTime)
+
+      Assert.AreEqual(@"{""Color"":4,""Establised"":""\/Date(1264122061000)\/"",""Width"":1.1,""Employees"":999,""RoomsPerFloor"":[1,2,3,4,5,6,7,8,9],""Open"":false,""Symbol"":""@"",""Mottos"":[""Hello World"",""öäüÖÄÜ\\'{new Date(12345);}[222]_µ@²³~"",null,"" ""],""Cost"":100980.1,""Escape"":""\r\n\t\f\b?{\\r\\n\""'"",""product"":[{""Name"":""Rocket"",""ExpiryDate"":""\/Date(949532490000)\/"",""Price"":0.0},{""Name"":""Alien"",""ExpiryDate"":""\/Date(946684800000)\/"",""Price"":0.0}]}", sw.GetStringBuilder().ToString());
+
+      Store s2 = (Store)jsonSerializer.Deserialize(new JsonTextReader(new StringReader("{}")), typeof(Store));
+      Assert.AreEqual("\r\n\t\f\b?{\\r\\n\"\'", s2.Escape);
+
+      Store s3 = (Store)jsonSerializer.Deserialize(new JsonTextReader(new StringReader(@"{""Escape"":null}")), typeof(Store));
+      Assert.AreEqual("\r\n\t\f\b?{\\r\\n\"\'", s3.Escape);
+
+      Store s4 = (Store)jsonSerializer.Deserialize(new JsonTextReader(new StringReader(@"{""Color"":2,""Establised"":""\/Date(1264071600000+1300)\/"",""Width"":1.1,""Employees"":999,""RoomsPerFloor"":[1,2,3,4,5,6,7,8,9],""Open"":false,""Symbol"":""@"",""Mottos"":[""Hello World"",""öäüÖÄÜ\\'{new Date(12345);}[222]_µ@²³~"",null,"" ""],""Cost"":100980.1,""Escape"":""\r\n\t\f\b?{\\r\\n\""'"",""product"":[{""Name"":""Rocket"",""ExpiryDate"":""\/Date(949485690000+1300)\/"",""Price"":0},{""Name"":""Alien"",""ExpiryDate"":""\/Date(946638000000)\/"",""Price"":0.0}]}")), typeof(Store));
+      Assert.AreEqual(s1.Establised, s3.Establised);
+    }
+
+    [Test]
+    public void NullValueHandlingBlogPost()
+    {
+      Movie movie = new Movie();
+      movie.Name = "Bad Boys III";
+      movie.Description = "It's no Bad Boys";
+
+      string included = JsonConvert.SerializeObject(movie,
+        Formatting.Indented,
+        new JsonSerializerSettings { });
+
+      // {
+      //   "Name": "Bad Boys III",
+      //   "Description": "It's no Bad Boys",
+      //   "Classification": null,
+      //   "Studio": null,
+      //   "ReleaseDate": null,
+      //   "ReleaseCountries": null
+      // }
+
+      string ignored = JsonConvert.SerializeObject(movie,
+        Formatting.Indented,
+        new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
+
+      // {
+      //   "Name": "Bad Boys III",
+      //   "Description": "It's no Bad Boys"
+      // }
+
+      Assert.AreEqual(@"{
+  ""Name"": ""Bad Boys III"",
+  ""Description"": ""It's no Bad Boys"",
+  ""Classification"": null,
+  ""Studio"": null,
+  ""ReleaseDate"": null,
+  ""ReleaseCountries"": null
+}", included);
+
+      Assert.AreEqual(@"{
+  ""Name"": ""Bad Boys III"",
+  ""Description"": ""It's no Bad Boys""
+}", ignored);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/PopulateTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/PopulateTests.cs
new file mode 100644 (file)
index 0000000..8985f98
--- /dev/null
@@ -0,0 +1,143 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Tests.TestObjects;
+using NUnit.Framework;
+using Newtonsoft.Json.Linq;
+
+namespace Newtonsoft.Json.Tests.Serialization
+{
+  public class PopulateTests : TestFixtureBase
+  {
+    [Test]
+    public void PopulatePerson()
+    {
+      Person p = new Person();
+
+      JsonConvert.PopulateObject(@"{""Name"":""James""}", p);
+
+      Assert.AreEqual("James", p.Name);
+    }
+
+    [Test]
+    public void PopulateStore()
+    {
+      Store s = new Store();
+      s.Color = StoreColor.Red;
+      s.product = new List<Product>
+        {
+          new Product
+            {
+              ExpiryDate = new DateTime(2000, 12, 3, 0, 0, 0, DateTimeKind.Utc),
+              Name = "ProductName!",
+              Price = 9.9m
+            }
+        };
+      s.Width = 99.99d;
+      s.Mottos = new List<string> { "Can do!", "We deliver!" };
+
+      string json = @"{
+  ""Color"": 2,
+  ""Establised"": ""\/Date(1264122061000+0000)\/"",
+  ""Width"": 99.99,
+  ""Employees"": 999,
+  ""RoomsPerFloor"": [
+    1,
+    2,
+    3,
+    4,
+    5,
+    6,
+    7,
+    8,
+    9
+  ],
+  ""Open"": false,
+  ""Symbol"": ""@"",
+  ""Mottos"": [
+    ""Fail whale""
+  ],
+  ""Cost"": 100980.1,
+  ""Escape"": ""\r\n\t\f\b?{\\r\\n\""'"",
+  ""product"": [
+    {
+      ""Name"": ""ProductName!"",
+      ""ExpiryDate"": ""\/Date(975801600000)\/"",
+      ""Price"": 9.9,
+      ""Sizes"": null
+    }
+  ]
+}";
+
+      JsonConvert.PopulateObject(json, s, new JsonSerializerSettings
+        {
+          ObjectCreationHandling = ObjectCreationHandling.Replace
+        });
+
+      Assert.AreEqual(1, s.Mottos.Count);
+      Assert.AreEqual("Fail whale", s.Mottos[0]);
+      Assert.AreEqual(1, s.product.Count);
+
+      //Assert.AreEqual("James", p.Name);
+    }
+
+    [Test]
+    public void PopulateListOfPeople()
+    {
+      List<Person> p = new List<Person>();
+
+      JsonSerializer serializer = new JsonSerializer();
+      serializer.Populate(new StringReader(@"[{""Name"":""James""},{""Name"":""Jim""}]"), p);
+
+      Assert.AreEqual(2, p.Count);
+      Assert.AreEqual("James", p[0].Name);
+      Assert.AreEqual("Jim", p[1].Name);
+    }
+
+    [Test]
+    public void PopulateDictionary()
+    {
+      Dictionary<string, string> p = new Dictionary<string, string>();
+
+      JsonSerializer serializer = new JsonSerializer();
+      serializer.Populate(new StringReader(@"{""Name"":""James""}"), p);
+
+      Assert.AreEqual(1, p.Count);
+      Assert.AreEqual("James", p["Name"]);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "Unexpected initial token 'Integer' when populating object. Expected JSON object or array.")]
+    public void PopulateWithBadJson()
+    {
+      JsonConvert.PopulateObject("1", new Person());
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/PreserveReferencesHandlingTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/PreserveReferencesHandlingTests.cs
new file mode 100644 (file)
index 0000000..1bbef89
--- /dev/null
@@ -0,0 +1,863 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Tests.TestObjects;
+using NUnit.Framework;
+
+namespace Newtonsoft.Json.Tests.Serialization
+{
+  public class PreserveReferencesHandlingTests : TestFixtureBase
+  {
+    [Test]
+    public void SerializeDictionarysWithPreserveObjectReferences()
+    {
+      CircularDictionary circularDictionary = new CircularDictionary();
+      circularDictionary.Add("other", new CircularDictionary { { "blah", null } });
+      circularDictionary.Add("self", circularDictionary);
+
+      string json = JsonConvert.SerializeObject(circularDictionary, Formatting.Indented,
+        new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.All });
+
+      Assert.AreEqual(@"{
+  ""$id"": ""1"",
+  ""other"": {
+    ""$id"": ""2"",
+    ""blah"": null
+  },
+  ""self"": {
+    ""$ref"": ""1""
+  }
+}", json);
+    }
+
+    [Test]
+    public void DeserializeDictionarysWithPreserveObjectReferences()
+    {
+      string json = @"{
+  ""$id"": ""1"",
+  ""other"": {
+    ""$id"": ""2"",
+    ""blah"": null
+  },
+  ""self"": {
+    ""$ref"": ""1""
+  }
+}";
+
+      CircularDictionary circularDictionary = JsonConvert.DeserializeObject<CircularDictionary>(json,
+        new JsonSerializerSettings
+        {
+          PreserveReferencesHandling = PreserveReferencesHandling.All
+        });
+
+      Assert.AreEqual(2, circularDictionary.Count);
+      Assert.AreEqual(1, circularDictionary["other"].Count);
+      Assert.AreEqual(circularDictionary, circularDictionary["self"]);
+    }
+
+    public class CircularList : List<CircularList>
+    {
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException))]
+    public void SerializeCircularListsError()
+    {
+      CircularList circularList = new CircularList();
+      circularList.Add(null);
+      circularList.Add(new CircularList { null });
+      circularList.Add(new CircularList { new CircularList { circularList } });
+
+      JsonConvert.SerializeObject(circularList, Formatting.Indented);
+    }
+
+    [Test]
+    public void SerializeCircularListsIgnore()
+    {
+      CircularList circularList = new CircularList();
+      circularList.Add(null);
+      circularList.Add(new CircularList { null });
+      circularList.Add(new CircularList { new CircularList { circularList } });
+
+      string json = JsonConvert.SerializeObject(circularList,
+                                                Formatting.Indented,
+                                                new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
+
+      Assert.AreEqual(@"[
+  null,
+  [
+    null
+  ],
+  [
+    []
+  ]
+]", json);
+    }
+
+    [Test]
+    public void SerializeListsWithPreserveObjectReferences()
+    {
+      CircularList circularList = new CircularList();
+      circularList.Add(null);
+      circularList.Add(new CircularList { null });
+      circularList.Add(new CircularList { new CircularList { circularList } });
+
+      string json = JsonConvert.SerializeObject(circularList, Formatting.Indented,
+        new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.All });
+
+      WriteEscapedJson(json);
+      Assert.AreEqual(@"{
+  ""$id"": ""1"",
+  ""$values"": [
+    null,
+    {
+      ""$id"": ""2"",
+      ""$values"": [
+        null
+      ]
+    },
+    {
+      ""$id"": ""3"",
+      ""$values"": [
+        {
+          ""$id"": ""4"",
+          ""$values"": [
+            {
+              ""$ref"": ""1""
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}", json);
+    }
+
+    [Test]
+    public void DeserializeListsWithPreserveObjectReferences()
+    {
+      string json = @"{
+  ""$id"": ""1"",
+  ""$values"": [
+    null,
+    {
+      ""$id"": ""2"",
+      ""$values"": [
+        null
+      ]
+    },
+    {
+      ""$id"": ""3"",
+      ""$values"": [
+        {
+          ""$id"": ""4"",
+          ""$values"": [
+            {
+              ""$ref"": ""1""
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}";
+
+      CircularList circularList = JsonConvert.DeserializeObject<CircularList>(json,
+        new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.All });
+
+      Assert.AreEqual(3, circularList.Count);
+      Assert.AreEqual(null, circularList[0]);
+      Assert.AreEqual(1, circularList[1].Count);
+      Assert.AreEqual(1, circularList[2].Count);
+      Assert.AreEqual(1, circularList[2][0].Count);
+      Assert.IsTrue(ReferenceEquals(circularList, circularList[2][0][0]));
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"Cannot preserve reference to array or readonly list: System.String[][]")]
+    public void DeserializeArraysWithPreserveObjectReferences()
+    {
+      string json = @"{
+  ""$id"": ""1"",
+  ""$values"": [
+    null,
+    {
+      ""$id"": ""2"",
+      ""$values"": [
+        null
+      ]
+    },
+    {
+      ""$id"": ""3"",
+      ""$values"": [
+        {
+          ""$id"": ""4"",
+          ""$values"": [
+            {
+              ""$ref"": ""1""
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}";
+
+      JsonConvert.DeserializeObject<string[][]>(json,
+        new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.All });
+    }
+
+    public class CircularDictionary : Dictionary<string, CircularDictionary>
+    {
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException))]
+    public void SerializeCircularDictionarysError()
+    {
+      CircularDictionary circularDictionary = new CircularDictionary();
+      circularDictionary.Add("other", new CircularDictionary { { "blah", null } });
+      circularDictionary.Add("self", circularDictionary);
+
+      JsonConvert.SerializeObject(circularDictionary, Formatting.Indented);
+    }
+
+    [Test]
+    public void SerializeCircularDictionarysIgnore()
+    {
+      CircularDictionary circularDictionary = new CircularDictionary();
+      circularDictionary.Add("other", new CircularDictionary { { "blah", null } });
+      circularDictionary.Add("self", circularDictionary);
+
+      string json = JsonConvert.SerializeObject(circularDictionary, Formatting.Indented,
+        new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
+
+      Assert.AreEqual(@"{
+  ""other"": {
+    ""blah"": null
+  }
+}", json);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"Unexpected end when deserializing object.")]
+    public void UnexpectedEnd()
+    {
+      string json = @"{
+  ""$id"":";
+
+      JsonConvert.DeserializeObject<string[][]>(json,
+        new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.All });
+    }
+
+    public class CircularReferenceClassConverter : JsonConverter
+    {
+      public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+      {
+        CircularReferenceClass circularReferenceClass = (CircularReferenceClass)value;
+
+        string reference = serializer.ReferenceResolver.GetReference(serializer, circularReferenceClass);
+
+        JObject me = new JObject();
+        me["$id"] = new JValue(reference);
+        me["$type"] = new JValue(value.GetType().Name);
+        me["Name"] = new JValue(circularReferenceClass.Name);
+
+        JObject o = JObject.FromObject(circularReferenceClass.Child, serializer);
+        me["Child"] = o;
+
+        me.WriteTo(writer);
+      }
+
+      public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+      {
+        JObject o = JObject.Load(reader);
+        string id = (string)o["$id"];
+        if (id != null)
+        {
+          CircularReferenceClass circularReferenceClass = new CircularReferenceClass();
+          serializer.Populate(o.CreateReader(), circularReferenceClass);
+          return circularReferenceClass;
+        }
+        else
+        {
+          string reference = (string)o["$ref"];
+          return serializer.ReferenceResolver.ResolveReference(serializer, reference);
+        }
+      }
+
+      public override bool CanConvert(Type objectType)
+      {
+        return (objectType == typeof(CircularReferenceClass));
+      }
+    }
+
+    [Test]
+    public void SerializeCircularReferencesWithConverter()
+    {
+      CircularReferenceClass c1 = new CircularReferenceClass { Name = "c1" };
+      CircularReferenceClass c2 = new CircularReferenceClass { Name = "c2" };
+      CircularReferenceClass c3 = new CircularReferenceClass { Name = "c3" };
+
+      c1.Child = c2;
+      c2.Child = c3;
+      c3.Child = c1;
+
+      string json = JsonConvert.SerializeObject(c1, Formatting.Indented, new JsonSerializerSettings
+      {
+        PreserveReferencesHandling = PreserveReferencesHandling.Objects,
+        Converters = new List<JsonConverter> { new CircularReferenceClassConverter() }
+      });
+
+      Assert.AreEqual(@"{
+  ""$id"": ""1"",
+  ""$type"": ""CircularReferenceClass"",
+  ""Name"": ""c1"",
+  ""Child"": {
+    ""$id"": ""2"",
+    ""$type"": ""CircularReferenceClass"",
+    ""Name"": ""c2"",
+    ""Child"": {
+      ""$id"": ""3"",
+      ""$type"": ""CircularReferenceClass"",
+      ""Name"": ""c3"",
+      ""Child"": {
+        ""$ref"": ""1""
+      }
+    }
+  }
+}", json);
+    }
+
+    [Test]
+    public void DeserializeCircularReferencesWithConverter()
+    {
+      string json = @"{
+  ""$id"": ""1"",
+  ""$type"": ""CircularReferenceClass"",
+  ""Name"": ""c1"",
+  ""Child"": {
+    ""$id"": ""2"",
+    ""$type"": ""CircularReferenceClass"",
+    ""Name"": ""c2"",
+    ""Child"": {
+      ""$id"": ""3"",
+      ""$type"": ""CircularReferenceClass"",
+      ""Name"": ""c3"",
+      ""Child"": {
+        ""$ref"": ""1""
+      }
+    }
+  }
+}";
+
+      CircularReferenceClass c1 = JsonConvert.DeserializeObject<CircularReferenceClass>(json, new JsonSerializerSettings
+      {
+        PreserveReferencesHandling = PreserveReferencesHandling.Objects,
+        Converters = new List<JsonConverter> { new CircularReferenceClassConverter() }
+      });
+
+      Assert.AreEqual("c1", c1.Name);
+      Assert.AreEqual("c2", c1.Child.Name);
+      Assert.AreEqual("c3", c1.Child.Child.Name);
+      Assert.AreEqual("c1", c1.Child.Child.Child.Name);
+    }
+
+    [Test]
+    public void SerializeEmployeeReference()
+    {
+      EmployeeReference mikeManager = new EmployeeReference
+      {
+        Name = "Mike Manager"
+      };
+      EmployeeReference joeUser = new EmployeeReference
+      {
+        Name = "Joe User",
+        Manager = mikeManager
+      };
+
+      List<EmployeeReference> employees = new List<EmployeeReference>
+        {
+          mikeManager,
+          joeUser
+        };
+
+      string json = JsonConvert.SerializeObject(employees, Formatting.Indented);
+      Assert.AreEqual(@"[
+  {
+    ""$id"": ""1"",
+    ""Name"": ""Mike Manager"",
+    ""Manager"": null
+  },
+  {
+    ""$id"": ""2"",
+    ""Name"": ""Joe User"",
+    ""Manager"": {
+      ""$ref"": ""1""
+    }
+  }
+]", json);
+    }
+
+    [Test]
+    public void DeserializeEmployeeReference()
+    {
+      string json = @"[
+  {
+    ""$id"": ""1"",
+    ""Name"": ""Mike Manager"",
+    ""Manager"": null
+  },
+  {
+    ""$id"": ""2"",
+    ""Name"": ""Joe User"",
+    ""Manager"": {
+      ""$ref"": ""1""
+    }
+  }
+]";
+
+      List<EmployeeReference> employees = JsonConvert.DeserializeObject<List<EmployeeReference>>(json);
+
+      Assert.AreEqual(2, employees.Count);
+      Assert.AreEqual("Mike Manager", employees[0].Name);
+      Assert.AreEqual("Joe User", employees[1].Name);
+      Assert.AreEqual(employees[0], employees[1].Manager);
+    }
+
+    [Test]
+    public void SerializeCircularReference()
+    {
+      CircularReferenceClass c1 = new CircularReferenceClass { Name = "c1" };
+      CircularReferenceClass c2 = new CircularReferenceClass { Name = "c2" };
+      CircularReferenceClass c3 = new CircularReferenceClass { Name = "c3" };
+
+      c1.Child = c2;
+      c2.Child = c3;
+      c3.Child = c1;
+
+      string json = JsonConvert.SerializeObject(c1, Formatting.Indented, new JsonSerializerSettings
+      {
+        PreserveReferencesHandling = PreserveReferencesHandling.Objects
+      });
+
+      Assert.AreEqual(@"{
+  ""$id"": ""1"",
+  ""Name"": ""c1"",
+  ""Child"": {
+    ""$id"": ""2"",
+    ""Name"": ""c2"",
+    ""Child"": {
+      ""$id"": ""3"",
+      ""Name"": ""c3"",
+      ""Child"": {
+        ""$ref"": ""1""
+      }
+    }
+  }
+}", json);
+    }
+
+    [Test]
+    public void DeserializeCircularReference()
+    {
+      string json = @"{
+  ""$id"": ""1"",
+  ""Name"": ""c1"",
+  ""Child"": {
+    ""$id"": ""2"",
+    ""Name"": ""c2"",
+    ""Child"": {
+      ""$id"": ""3"",
+      ""Name"": ""c3"",
+      ""Child"": {
+        ""$ref"": ""1""
+      }
+    }
+  }
+}";
+
+      CircularReferenceClass c1 =
+        JsonConvert.DeserializeObject<CircularReferenceClass>(json, new JsonSerializerSettings
+        {
+          PreserveReferencesHandling = PreserveReferencesHandling.Objects
+        });
+
+      Assert.AreEqual("c1", c1.Name);
+      Assert.AreEqual("c2", c1.Child.Name);
+      Assert.AreEqual("c3", c1.Child.Child.Name);
+      Assert.AreEqual("c1", c1.Child.Child.Child.Name);
+    }
+
+    [Test]
+    public void SerializeReferenceInList()
+    {
+      EmployeeReference e1 = new EmployeeReference { Name = "e1" };
+      EmployeeReference e2 = new EmployeeReference { Name = "e2" };
+
+      List<EmployeeReference> employees = new List<EmployeeReference> { e1, e2, e1, e2 };
+
+      string json = JsonConvert.SerializeObject(employees, Formatting.Indented);
+
+      Assert.AreEqual(@"[
+  {
+    ""$id"": ""1"",
+    ""Name"": ""e1"",
+    ""Manager"": null
+  },
+  {
+    ""$id"": ""2"",
+    ""Name"": ""e2"",
+    ""Manager"": null
+  },
+  {
+    ""$ref"": ""1""
+  },
+  {
+    ""$ref"": ""2""
+  }
+]", json);
+    }
+
+    [Test]
+    public void DeserializeReferenceInList()
+    {
+      string json = @"[
+  {
+    ""$id"": ""1"",
+    ""Name"": ""e1"",
+    ""Manager"": null
+  },
+  {
+    ""$id"": ""2"",
+    ""Name"": ""e2"",
+    ""Manager"": null
+  },
+  {
+    ""$ref"": ""1""
+  },
+  {
+    ""$ref"": ""2""
+  }
+]";
+
+      List<EmployeeReference> employees = JsonConvert.DeserializeObject<List<EmployeeReference>>(json);
+      Assert.AreEqual(4, employees.Count);
+
+      Assert.AreEqual("e1", employees[0].Name);
+      Assert.AreEqual("e2", employees[1].Name);
+      Assert.AreEqual("e1", employees[2].Name);
+      Assert.AreEqual("e2", employees[3].Name);
+
+      Assert.AreEqual(employees[0], employees[2]);
+      Assert.AreEqual(employees[1], employees[3]);
+    }
+
+    [Test]
+    public void SerializeReferenceInDictionary()
+    {
+      EmployeeReference e1 = new EmployeeReference { Name = "e1" };
+      EmployeeReference e2 = new EmployeeReference { Name = "e2" };
+
+      Dictionary<string, EmployeeReference> employees = new Dictionary<string, EmployeeReference>
+        {
+          {"One", e1},
+          {"Two", e2},
+          {"Three", e1},
+          {"Four", e2}
+        };
+
+      string json = JsonConvert.SerializeObject(employees, Formatting.Indented);
+
+      Assert.AreEqual(@"{
+  ""One"": {
+    ""$id"": ""1"",
+    ""Name"": ""e1"",
+    ""Manager"": null
+  },
+  ""Two"": {
+    ""$id"": ""2"",
+    ""Name"": ""e2"",
+    ""Manager"": null
+  },
+  ""Three"": {
+    ""$ref"": ""1""
+  },
+  ""Four"": {
+    ""$ref"": ""2""
+  }
+}", json);
+    }
+
+    [Test]
+    public void DeserializeReferenceInDictionary()
+    {
+      string json = @"{
+  ""One"": {
+    ""$id"": ""1"",
+    ""Name"": ""e1"",
+    ""Manager"": null
+  },
+  ""Two"": {
+    ""$id"": ""2"",
+    ""Name"": ""e2"",
+    ""Manager"": null
+  },
+  ""Three"": {
+    ""$ref"": ""1""
+  },
+  ""Four"": {
+    ""$ref"": ""2""
+  }
+}";
+
+      Dictionary<string, EmployeeReference> employees = JsonConvert.DeserializeObject<Dictionary<string, EmployeeReference>>(json);
+      Assert.AreEqual(4, employees.Count);
+
+      EmployeeReference e1 = employees["One"];
+      EmployeeReference e2 = employees["Two"];
+
+      Assert.AreEqual("e1", e1.Name);
+      Assert.AreEqual("e2", e2.Name);
+
+      Assert.AreEqual(e1, employees["Three"]);
+      Assert.AreEqual(e2, employees["Four"]);
+    }
+
+    [Test]
+    public void ExampleWithout()
+    {
+      Person p = new Person
+        {
+          BirthDate = new DateTime(1980, 12, 23, 0, 0, 0, DateTimeKind.Utc),
+          LastModified = new DateTime(2009, 2, 20, 12, 59, 21, DateTimeKind.Utc),
+          Department = "IT",
+          Name = "James"
+        };
+
+      List<Person> people = new List<Person>();
+      people.Add(p);
+      people.Add(p);
+
+      string json = JsonConvert.SerializeObject(people, Formatting.Indented);
+      //[
+      //  {
+      //    "Name": "James",
+      //    "BirthDate": "\/Date(346377600000)\/",
+      //    "LastModified": "\/Date(1235134761000)\/"
+      //  },
+      //  {
+      //    "Name": "James",
+      //    "BirthDate": "\/Date(346377600000)\/",
+      //    "LastModified": "\/Date(1235134761000)\/"
+      //  }
+      //]
+    }
+
+    [Test]
+    public void ExampleWith()
+    {
+      Person p = new Person
+      {
+        BirthDate = new DateTime(1980, 12, 23, 0, 0, 0, DateTimeKind.Utc),
+        LastModified = new DateTime(2009, 2, 20, 12, 59, 21, DateTimeKind.Utc),
+        Department = "IT",
+        Name = "James"
+      };
+
+      List<Person> people = new List<Person>();
+      people.Add(p);
+      people.Add(p);
+
+      string json = JsonConvert.SerializeObject(people, Formatting.Indented,
+        new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects });
+      //[
+      //  {
+      //    "$id": "1",
+      //    "Name": "James",
+      //    "BirthDate": "\/Date(346377600000)\/",
+      //    "LastModified": "\/Date(1235134761000)\/"
+      //  },
+      //  {
+      //    "$ref": "1"
+      //  }
+      //]
+
+      List<Person> deserializedPeople = JsonConvert.DeserializeObject<List<Person>>(json,
+        new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects });
+
+      Console.WriteLine(deserializedPeople.Count);
+      // 2
+
+      Person p1 = deserializedPeople[0];
+      Person p2 = deserializedPeople[1];
+
+      Console.WriteLine(p1.Name);
+      // James
+      Console.WriteLine(p2.Name);
+      // James
+
+      bool equal = Object.ReferenceEquals(p1, p2);
+      // true
+    }
+
+    [JsonObject(MemberSerialization = MemberSerialization.OptIn)]
+    public class User
+    {
+      #region properties
+
+      [JsonProperty(Required = Required.Always, PropertyName = "SecretType")]
+      private string secretType;
+
+      [JsonProperty(Required = Required.Always)]
+      public string Login { get; set; }
+
+      public Type SecretType
+      {
+        get { return Type.GetType(secretType); }
+        set { secretType = value.AssemblyQualifiedName; }
+      }
+
+      [JsonProperty]
+      public User Friend { get; set; }
+
+      #endregion
+
+      #region constructors
+
+      public User()
+      {
+
+      }
+
+      public User(string login, Type secretType)
+        : this()
+      {
+        this.Login = login;
+        this.SecretType = secretType;
+      }
+
+      #endregion
+
+      #region methods
+
+      public override int GetHashCode()
+      {
+        return SecretType.GetHashCode();
+      }
+
+      public override string ToString()
+      {
+        return string.Format("SecretType: {0}, Login: {1}", secretType, Login);
+      }
+
+      #endregion
+    }
+
+    [Test]
+    public void DeserializeTypeWithDubiousGetHashcode()
+    {
+      User user1 = new User("Peter", typeof(Version));
+      User user2 = new User("Michael", typeof(Version));
+
+      user1.Friend = user2;
+
+      JsonSerializerSettings serializerSettings = new JsonSerializerSettings
+      {
+        TypeNameHandling = TypeNameHandling.All,
+        ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
+        ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor,
+        PreserveReferencesHandling = PreserveReferencesHandling.Objects
+      };
+
+      string json = JsonConvert.SerializeObject(user1, Formatting.Indented, serializerSettings);
+
+      User deserializedUser = JsonConvert.DeserializeObject<User>(json, serializerSettings);
+      Assert.IsNotNull(deserializedUser);
+    }
+
+    [Test]
+    public void PreserveReferencesHandlingWithReusedJsonSerializer()
+    {
+      MyClass c = new MyClass();
+
+      IList<MyClass> myClasses1 = new List<MyClass>
+        {
+          c,
+          c
+        };
+
+      var ser = new JsonSerializer()
+      {
+        PreserveReferencesHandling = PreserveReferencesHandling.All
+      };
+
+      MemoryStream ms = new MemoryStream();
+
+      using (var sw = new StreamWriter(ms))
+      using (var writer = new JsonTextWriter(sw) { Formatting = Formatting.Indented })
+      {
+        ser.Serialize(writer, myClasses1);
+      }
+
+      byte[] data = ms.ToArray();
+      string json = Encoding.UTF8.GetString(data, 0, data.Length);
+
+      Assert.AreEqual(@"{
+  ""$id"": ""1"",
+  ""$values"": [
+    {
+      ""$id"": ""2"",
+      ""PreProperty"": 0,
+      ""PostProperty"": 0
+    },
+    {
+      ""$ref"": ""2""
+    }
+  ]
+}", json);
+
+      ms = new MemoryStream(data);
+      IList<MyClass> myClasses2;
+
+      using (var sr = new StreamReader(ms))
+      using (var reader = new JsonTextReader(sr))
+      {
+        myClasses2 = ser.Deserialize<IList<MyClass>>(reader);
+      }
+
+      Assert.AreEqual(2, myClasses2.Count);
+      Assert.AreEqual(myClasses2[0], myClasses2[1]);
+
+      Assert.AreNotEqual(myClasses1[0], myClasses2[0]);
+    }
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/SerializationErrorHandlingTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/SerializationErrorHandlingTests.cs
new file mode 100644 (file)
index 0000000..b28954c
--- /dev/null
@@ -0,0 +1,294 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Converters;
+using Newtonsoft.Json.Tests.TestObjects;
+using NUnit.Framework;
+using Newtonsoft.Json.Serialization;
+using System.IO;
+using ErrorEventArgs=Newtonsoft.Json.Serialization.ErrorEventArgs;
+
+namespace Newtonsoft.Json.Tests.Serialization
+{
+  public class SerializationErrorHandlingTests : TestFixtureBase
+  {
+    [Test]
+    public void ErrorDeserializingListHandled()
+    {
+      string json = @"[
+  {
+    ""Name"": ""Jim"",
+    ""BirthDate"": ""\/Date(978048000000)\/"",
+    ""LastModified"": ""\/Date(978048000000)\/""
+  },
+  {
+    ""Name"": ""Jim"",
+    ""BirthDate"": ""\/Date(978048000000)\/"",
+    ""LastModified"": ""\/Date(978048000000)\/""
+  }
+]";
+
+      VersionKeyedCollection c = JsonConvert.DeserializeObject<VersionKeyedCollection>(json);
+      Assert.AreEqual(1, c.Count);
+      Assert.AreEqual(1, c.Messages.Count);
+      Assert.AreEqual("Error message for member 1 = An item with the same key has already been added.", c.Messages[0]);
+    }
+
+    [Test]
+    public void DeserializingErrorInChildObject()
+    {
+      ListErrorObjectCollection c = JsonConvert.DeserializeObject<ListErrorObjectCollection>(@"[
+  {
+    ""Member"": ""Value1"",
+    ""Member2"": null
+  },
+  {
+    ""Member"": ""Value2""
+  },
+  {
+    ""ThrowError"": ""Value"",
+    ""Object"": {
+      ""Array"": [
+        1,
+        2
+      ]
+    }
+  },
+  {
+    ""ThrowError"": ""Handle this!"",
+    ""Member"": ""Value3""
+  }
+]");
+
+      Assert.AreEqual(3, c.Count);
+      Assert.AreEqual("Value1", c[0].Member);
+      Assert.AreEqual("Value2", c[1].Member);
+      Assert.AreEqual("Value3", c[2].Member);
+      Assert.AreEqual("Handle this!", c[2].ThrowError);
+    }
+
+    [Test]
+    public void SerializingErrorInChildObject()
+    {
+      ListErrorObjectCollection c = new ListErrorObjectCollection
+        {
+          new ListErrorObject
+            {
+              Member = "Value1",
+              ThrowError = "Handle this!",
+              Member2 = "Member1"
+            },
+          new ListErrorObject
+            {
+              Member = "Value2",
+              Member2 = "Member2"
+            },
+          new ListErrorObject
+            {
+              Member = "Value3",
+              ThrowError = "Handle that!",
+              Member2 = "Member3"
+            }
+        };
+
+      string json = JsonConvert.SerializeObject(c, Formatting.Indented);
+
+      Assert.AreEqual(@"[
+  {
+    ""Member"": ""Value1"",
+    ""ThrowError"": ""Handle this!"",
+    ""Member2"": ""Member1""
+  },
+  {
+    ""Member"": ""Value2""
+  },
+  {
+    ""Member"": ""Value3"",
+    ""ThrowError"": ""Handle that!"",
+    ""Member2"": ""Member3""
+  }
+]", json);
+    }
+
+    [Test]
+    public void DeserializingErrorInDateTimeCollection()
+    {
+      DateTimeErrorObjectCollection c = JsonConvert.DeserializeObject<DateTimeErrorObjectCollection>(@"[
+  ""2009-09-09T00:00:00Z"",
+  ""kjhkjhkjhkjh"",
+  [
+    1
+  ],
+  ""1977-02-20T00:00:00Z"",
+  null,
+  ""2000-12-01T00:00:00Z""
+]", new IsoDateTimeConverter());
+
+      Assert.AreEqual(3, c.Count);
+      Assert.AreEqual(new DateTime(2009, 9, 9, 0, 0, 0, DateTimeKind.Utc), c[0]);
+      Assert.AreEqual(new DateTime(1977, 2, 20, 0, 0, 0, DateTimeKind.Utc), c[1]);
+      Assert.AreEqual(new DateTime(2000, 12, 1, 0, 0, 0, DateTimeKind.Utc), c[2]);
+    }
+
+    [Test]
+    public void DeserializingErrorHandlingUsingEvent()
+    {
+      List<string> errors = new List<string>();
+
+      List<DateTime> c = JsonConvert.DeserializeObject<List<DateTime>>(@"[
+        ""2009-09-09T00:00:00Z"",
+        ""I am not a date and will error!"",
+        [
+          1
+        ],
+        ""1977-02-20T00:00:00Z"",
+        null,
+        ""2000-12-01T00:00:00Z""
+      ]",
+        new JsonSerializerSettings
+          {
+            Error = delegate(object sender, ErrorEventArgs args)
+              {
+                errors.Add(args.ErrorContext.Error.Message);
+                args.ErrorContext.Handled = true;
+              },
+            Converters = { new IsoDateTimeConverter() }
+          });
+
+      // 2009-09-09T00:00:00Z
+      // 1977-02-20T00:00:00Z
+      // 2000-12-01T00:00:00Z
+
+      // The string was not recognized as a valid DateTime. There is a unknown word starting at index 0.
+      // Unexpected token parsing date. Expected String, got StartArray.
+      // Cannot convert null value to System.DateTime.
+
+      Assert.AreEqual(3, c.Count);
+      Assert.AreEqual(new DateTime(2009, 9, 9, 0, 0, 0, DateTimeKind.Utc), c[0]);
+      Assert.AreEqual(new DateTime(1977, 2, 20, 0, 0, 0, DateTimeKind.Utc), c[1]);
+      Assert.AreEqual(new DateTime(2000, 12, 1, 0, 0, 0, DateTimeKind.Utc), c[2]);
+
+      Assert.AreEqual(3, errors.Count);
+#if !(NET20 || NET35 || WINDOWS_PHONE)
+      Assert.AreEqual("The string was not recognized as a valid DateTime. There is an unknown word starting at index 0.", errors[0]);
+#else
+      Assert.AreEqual("The string was not recognized as a valid DateTime. There is a unknown word starting at index 0.", errors[0]);
+#endif
+      Assert.AreEqual("Unexpected token parsing date. Expected String, got StartArray.", errors[1]);
+      Assert.AreEqual("Cannot convert null value to System.DateTime.", errors[2]);
+    }
+
+    [Test]
+    public void DeserializingErrorInDateTimeCollectionWithAttributeWithEventNotCalled()
+    {
+      bool eventErrorHandlerCalled = false;
+
+      DateTimeErrorObjectCollection c = JsonConvert.DeserializeObject<DateTimeErrorObjectCollection>(@"[
+  ""2009-09-09T00:00:00Z"",
+  ""kjhkjhkjhkjh"",
+  [
+    1
+  ],
+  ""1977-02-20T00:00:00Z"",
+  null,
+  ""2000-12-01T00:00:00Z""
+]",
+        new JsonSerializerSettings
+        {
+          Error = (s, a) => eventErrorHandlerCalled = true,
+          Converters =
+              {
+                new IsoDateTimeConverter()
+              }
+        });
+
+      Assert.AreEqual(3, c.Count);
+      Assert.AreEqual(new DateTime(2009, 9, 9, 0, 0, 0, DateTimeKind.Utc), c[0]);
+      Assert.AreEqual(new DateTime(1977, 2, 20, 0, 0, 0, DateTimeKind.Utc), c[1]);
+      Assert.AreEqual(new DateTime(2000, 12, 1, 0, 0, 0, DateTimeKind.Utc), c[2]);
+
+      Assert.AreEqual(false, eventErrorHandlerCalled);
+    }
+
+    [Test]
+    public void SerializePerson()
+    {
+      PersonError person = new PersonError
+        {
+          Name = "George Michael Bluth",
+          Age = 16,
+          Roles = null,
+          Title = "Mister Manager"
+        };
+
+      string json = JsonConvert.SerializeObject(person, Formatting.Indented);
+
+      Console.WriteLine(json);
+      //{
+      //  "Name": "George Michael Bluth",
+      //  "Age": 16,
+      //  "Title": "Mister Manager"
+      //}
+
+      Assert.AreEqual(@"{
+  ""Name"": ""George Michael Bluth"",
+  ""Age"": 16,
+  ""Title"": ""Mister Manager""
+}", json);
+    }
+
+    [Test]
+    public void DeserializeNestedUnhandled()
+    {
+      List<string> errors = new List<string>();
+
+      string json = @"[[""kjhkjhkjhkjh""]]";
+
+      try
+      {
+        JsonSerializer serializer = new JsonSerializer();
+        serializer.Error += delegate(object sender, ErrorEventArgs args)
+          {
+            // only log an error once
+            if (args.CurrentObject == args.ErrorContext.OriginalObject)
+              errors.Add(args.ErrorContext.Error.Message);
+          };
+
+        serializer.Deserialize(new StringReader(json), typeof(List<List<DateTime>>));
+      }
+      catch (Exception ex)
+      {
+        Console.WriteLine(ex.Message);
+      }
+
+      Assert.AreEqual(1, errors.Count);
+      Assert.AreEqual(@"Error converting value ""kjhkjhkjhkjh"" to type 'System.DateTime'.", errors[0]);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/SerializationEventAttributeTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/SerializationEventAttributeTests.cs
new file mode 100644 (file)
index 0000000..e4abd52
--- /dev/null
@@ -0,0 +1,267 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+#if !PocketPC
+using System;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.Serialization;
+using System.Text;
+using Newtonsoft.Json.Tests;
+using Newtonsoft.Json.Tests.TestObjects;
+using NUnit.Framework;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Converters;
+
+namespace Newtonsoft.Json.Tests.Serialization
+{
+  public class SerializationEventAttributeTests : TestFixtureBase
+  {
+    [Test]
+    public void ObjectEvents()
+    {
+      SerializationEventTestObject obj = new SerializationEventTestObject();
+
+      Assert.AreEqual(11, obj.Member1);
+      Assert.AreEqual("Hello World!", obj.Member2);
+      Assert.AreEqual("This is a nonserialized value", obj.Member3);
+      Assert.AreEqual(null, obj.Member4);
+      Assert.AreEqual(null, obj.Member5);
+
+      string json = JsonConvert.SerializeObject(obj, Formatting.Indented);
+      Assert.AreEqual(@"{
+  ""Member1"": 11,
+  ""Member2"": ""This value went into the data file during serialization."",
+  ""Member4"": null
+}", json);
+
+      Assert.AreEqual(11, obj.Member1);
+      Assert.AreEqual("This value was reset after serialization.", obj.Member2);
+      Assert.AreEqual("This is a nonserialized value", obj.Member3);
+      Assert.AreEqual(null, obj.Member4);
+      Assert.AreEqual("Error message for member Member6 = Error getting value from 'Member6' on 'Newtonsoft.Json.Tests.TestObjects.SerializationEventTestObject'.", obj.Member5);
+
+      JObject o = JObject.Parse(@"{
+  ""Member1"": 11,
+  ""Member2"": ""This value went into the data file during serialization."",
+  ""Member4"": null
+}");
+      o["Member6"] = "Dummy text for error";
+
+      obj = JsonConvert.DeserializeObject<SerializationEventTestObject>(o.ToString());
+
+      Assert.AreEqual(11, obj.Member1);
+      Assert.AreEqual("This value went into the data file during serialization.", obj.Member2);
+      Assert.AreEqual("This value was set during deserialization", obj.Member3);
+      Assert.AreEqual("This value was set after deserialization.", obj.Member4);
+      Assert.AreEqual("Error message for member Member6 = Error setting value to 'Member6' on 'Newtonsoft.Json.Tests.TestObjects.SerializationEventTestObject'.", obj.Member5);
+    }
+
+    [Test]
+    public void ObjectWithConstructorEvents()
+    {
+      SerializationEventTestObjectWithConstructor obj = new SerializationEventTestObjectWithConstructor(11, "Hello World!", null);
+
+      Assert.AreEqual(11, obj.Member1);
+      Assert.AreEqual("Hello World!", obj.Member2);
+      Assert.AreEqual("This is a nonserialized value", obj.Member3);
+      Assert.AreEqual(null, obj.Member4);
+
+      string json = JsonConvert.SerializeObject(obj, Formatting.Indented);
+      Assert.AreEqual(@"{
+  ""Member1"": 11,
+  ""Member2"": ""This value went into the data file during serialization."",
+  ""Member4"": null
+}", json);
+
+      Assert.AreEqual(11, obj.Member1);
+      Assert.AreEqual("This value was reset after serialization.", obj.Member2);
+      Assert.AreEqual("This is a nonserialized value", obj.Member3);
+      Assert.AreEqual(null, obj.Member4);
+
+      obj = JsonConvert.DeserializeObject<SerializationEventTestObjectWithConstructor>(json);
+
+      Assert.AreEqual(11, obj.Member1);
+      Assert.AreEqual("This value went into the data file during serialization.", obj.Member2);
+      Assert.AreEqual("This value was set during deserialization", obj.Member3);
+      Assert.AreEqual("This value was set after deserialization.", obj.Member4);
+    }
+
+    [Test]
+    public void ListEvents()
+    {
+      SerializationEventTestList obj = new SerializationEventTestList
+        {
+          1.1m,
+          2.222222222m,
+          int.MaxValue,
+          Convert.ToDecimal(Math.PI)
+        };
+
+      Assert.AreEqual(11, obj.Member1);
+      Assert.AreEqual("Hello World!", obj.Member2);
+      Assert.AreEqual("This is a nonserialized value", obj.Member3);
+      Assert.AreEqual(null, obj.Member4);
+
+      string json = JsonConvert.SerializeObject(obj, Formatting.Indented);
+      Assert.AreEqual(@"[
+  -1.0,
+  1.1,
+  2.222222222,
+  2147483647.0,
+  3.14159265358979
+]", json);
+
+      Assert.AreEqual(11, obj.Member1);
+      Assert.AreEqual("This value was reset after serialization.", obj.Member2);
+      Assert.AreEqual("This is a nonserialized value", obj.Member3);
+      Assert.AreEqual(null, obj.Member4);
+
+      obj = JsonConvert.DeserializeObject<SerializationEventTestList>(json);
+
+      Assert.AreEqual(11, obj.Member1);
+      Assert.AreEqual("Hello World!", obj.Member2);
+      Assert.AreEqual("This value was set during deserialization", obj.Member3);
+      Assert.AreEqual("This value was set after deserialization.", obj.Member4);
+    }
+
+    [Test]
+    public void DictionaryEvents()
+    {
+      SerializationEventTestDictionary obj = new SerializationEventTestDictionary
+        {
+          { 1.1m, "first" },
+          { 2.222222222m, "second" },
+          { int.MaxValue, "third" },
+          { Convert.ToDecimal(Math.PI), "fourth" }
+        };
+
+      Assert.AreEqual(11, obj.Member1);
+      Assert.AreEqual("Hello World!", obj.Member2);
+      Assert.AreEqual("This is a nonserialized value", obj.Member3);
+      Assert.AreEqual(null, obj.Member4);
+
+      string json = JsonConvert.SerializeObject(obj, Formatting.Indented);
+      Assert.AreEqual(@"{
+  ""1.1"": ""first"",
+  ""2.222222222"": ""second"",
+  ""2147483647"": ""third"",
+  ""3.14159265358979"": ""fourth"",
+  ""79228162514264337593543950335"": ""Inserted on serializing""
+}", json);
+
+      Assert.AreEqual(11, obj.Member1);
+      Assert.AreEqual("This value was reset after serialization.", obj.Member2);
+      Assert.AreEqual("This is a nonserialized value", obj.Member3);
+      Assert.AreEqual(null, obj.Member4);
+
+      obj = JsonConvert.DeserializeObject<SerializationEventTestDictionary>(json);
+
+      Assert.AreEqual(11, obj.Member1);
+      Assert.AreEqual("Hello World!", obj.Member2);
+      Assert.AreEqual("This value was set during deserialization", obj.Member3);
+      Assert.AreEqual("This value was set after deserialization.", obj.Member4);
+    }
+
+    [Test]
+    public void ObjectEventsDocumentationExample()
+    {
+      SerializationEventTestObject obj = new SerializationEventTestObject();
+
+      Console.WriteLine(obj.Member1);
+      // 11
+      Console.WriteLine(obj.Member2);
+      // Hello World!
+      Console.WriteLine(obj.Member3);
+      // This is a nonserialized value
+      Console.WriteLine(obj.Member4);
+      // null
+      Console.WriteLine(obj.Member5);
+      // null
+
+      string json = JsonConvert.SerializeObject(obj, Formatting.Indented);
+      // {
+      //   "Member1": 11,
+      //   "Member2": "This value went into the data file during serialization.",
+      //   "Member4": null
+      // }
+
+      Console.WriteLine(obj.Member1);
+      // 11
+      Console.WriteLine(obj.Member2);
+      // This value was reset after serialization.
+      Console.WriteLine(obj.Member3);
+      // This is a nonserialized value
+      Console.WriteLine(obj.Member4);
+      // null
+      Console.WriteLine(obj.Member5);
+      // Error message for member Member6 = Exception has been thrown by the target of an invocation.
+
+      obj = JsonConvert.DeserializeObject<SerializationEventTestObject>(json);
+
+      Console.WriteLine(obj.Member1);
+      // 11
+      Console.WriteLine(obj.Member2);
+      // This value went into the data file during serialization.
+      Console.WriteLine(obj.Member3);
+      // This value was set during deserialization
+      Console.WriteLine(obj.Member4);
+      // This value was set after deserialization.
+    }
+
+#if !SILVERLIGHT
+    public class SerializationEventContextTestObject
+    {
+      public string TestMember { get; set; }
+
+      [OnSerializing]
+      internal void OnSerializingMethod(StreamingContext context)
+      {
+        TestMember = context.State + " " + context.Context;
+      }
+    }
+
+    [Test]
+    public void SerializationEventContextTest()
+    {
+      SerializationEventContextTestObject value = new SerializationEventContextTestObject();
+
+      string json = JsonConvert.SerializeObject(value, Formatting.Indented, new JsonSerializerSettings
+                                                                              {
+                                                                                Context =
+                                                                                  new StreamingContext(
+                                                                                  StreamingContextStates.Remoting,
+                                                                                  "ContextValue")
+                                                                              });
+
+      Assert.AreEqual(@"{
+  ""TestMember"": ""Remoting ContextValue""
+}", json);
+    }
+#endif
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs
new file mode 100644 (file)
index 0000000..a3e9b19
--- /dev/null
@@ -0,0 +1,721 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.Serialization.Formatters;
+using System.Text;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Tests.TestObjects;
+using NUnit.Framework;
+using Newtonsoft.Json.Utilities;
+using System.Net;
+using System.Runtime.Serialization;
+using System.IO;
+
+namespace Newtonsoft.Json.Tests.Serialization
+{
+  public class TypeNameHandlingTests : TestFixtureBase
+  {
+    [Test]
+    public void WriteTypeNameForObjects()
+    {
+      string employeeRef = ReflectionUtils.GetTypeName(typeof(EmployeeReference), FormatterAssemblyStyle.Simple);
+
+      EmployeeReference employee = new EmployeeReference();
+
+      string json = JsonConvert.SerializeObject(employee, Formatting.Indented, new JsonSerializerSettings
+      {
+        TypeNameHandling = TypeNameHandling.Objects
+      });
+
+      Assert.AreEqual(@"{
+  ""$id"": ""1"",
+  ""$type"": """ + employeeRef + @""",
+  ""Name"": null,
+  ""Manager"": null
+}", json);
+    }
+
+    [Test]
+    public void DeserializeTypeName()
+    {
+      string employeeRef = ReflectionUtils.GetTypeName(typeof(EmployeeReference), FormatterAssemblyStyle.Simple);
+
+      string json = @"{
+  ""$id"": ""1"",
+  ""$type"": """ + employeeRef + @""",
+  ""Name"": ""Name!"",
+  ""Manager"": null
+}";
+
+      object employee = JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings
+      {
+        TypeNameHandling = TypeNameHandling.Objects
+      });
+
+      Assert.IsInstanceOfType(typeof(EmployeeReference), employee);
+      Assert.AreEqual("Name!", ((EmployeeReference)employee).Name);
+    }
+
+#if !SILVERLIGHT && !PocketPC
+    [Test]
+    public void DeserializeTypeNameFromGacAssembly()
+    {
+      string cookieRef = ReflectionUtils.GetTypeName(typeof(Cookie), FormatterAssemblyStyle.Simple);
+
+      string json = @"{
+  ""$id"": ""1"",
+  ""$type"": """ + cookieRef + @"""
+}";
+
+      object cookie = JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings
+      {
+        TypeNameHandling = TypeNameHandling.Objects
+      });
+
+      Assert.IsInstanceOfType(typeof(Cookie), cookie);
+    }
+#endif
+
+    [Test]
+    public void SerializeGenericObjectListWithTypeName()
+    {
+      string employeeRef = typeof(EmployeeReference).AssemblyQualifiedName;
+      string personRef = typeof(Person).AssemblyQualifiedName;
+
+      List<object> values = new List<object>
+        {
+          new EmployeeReference
+            {
+              Name = "Bob",
+              Manager = new EmployeeReference {Name = "Frank"}
+            },
+          new Person
+            {
+              Department = "Department",
+              BirthDate = new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc),
+              LastModified = new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc)
+            },
+          "String!",
+          int.MinValue
+        };
+
+      string json = JsonConvert.SerializeObject(values, Formatting.Indented, new JsonSerializerSettings
+      {
+        TypeNameHandling = TypeNameHandling.Objects,
+        TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
+      });
+
+      Assert.AreEqual(@"[
+  {
+    ""$id"": ""1"",
+    ""$type"": """ + employeeRef + @""",
+    ""Name"": ""Bob"",
+    ""Manager"": {
+      ""$id"": ""2"",
+      ""$type"": """ + employeeRef + @""",
+      ""Name"": ""Frank"",
+      ""Manager"": null
+    }
+  },
+  {
+    ""$type"": """ + personRef + @""",
+    ""Name"": null,
+    ""BirthDate"": ""\/Date(978134400000)\/"",
+    ""LastModified"": ""\/Date(978134400000)\/""
+  },
+  ""String!"",
+  -2147483648
+]", json);
+    }
+
+    [Test]
+    public void DeserializeGenericObjectListWithTypeName()
+    {
+      string employeeRef = typeof(EmployeeReference).AssemblyQualifiedName;
+      string personRef = typeof(Person).AssemblyQualifiedName;
+
+      string json = @"[
+  {
+    ""$id"": ""1"",
+    ""$type"": """ + employeeRef + @""",
+    ""Name"": ""Bob"",
+    ""Manager"": {
+      ""$id"": ""2"",
+      ""$type"": """ + employeeRef + @""",
+      ""Name"": ""Frank"",
+      ""Manager"": null
+    }
+  },
+  {
+    ""$type"": """ + personRef + @""",
+    ""Name"": null,
+    ""BirthDate"": ""\/Date(978134400000)\/"",
+    ""LastModified"": ""\/Date(978134400000)\/""
+  },
+  ""String!"",
+  -2147483648
+]";
+
+      List<object> values = (List<object>)JsonConvert.DeserializeObject(json, typeof(List<object>), new JsonSerializerSettings
+      {
+        TypeNameHandling = TypeNameHandling.Objects,
+        TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
+      });
+
+      Assert.AreEqual(4, values.Count);
+
+      EmployeeReference e = (EmployeeReference)values[0];
+      Person p = (Person)values[1];
+
+      Assert.AreEqual("Bob", e.Name);
+      Assert.AreEqual("Frank", e.Manager.Name);
+
+      Assert.AreEqual(null, p.Name);
+      Assert.AreEqual(new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc), p.BirthDate);
+      Assert.AreEqual(new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc), p.LastModified);
+
+      Assert.AreEqual("String!", values[2]);
+      Assert.AreEqual(int.MinValue, values[3]);
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException))]
+    public void DeserializeWithBadTypeName()
+    {
+      string employeeRef = typeof(EmployeeReference).AssemblyQualifiedName;
+
+      string json = @"{
+  ""$id"": ""1"",
+  ""$type"": """ + employeeRef + @""",
+  ""Name"": ""Name!"",
+  ""Manager"": null
+}";
+
+      JsonConvert.DeserializeObject(json, typeof(Person), new JsonSerializerSettings
+      {
+        TypeNameHandling = TypeNameHandling.Objects,
+        TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
+      });
+    }
+
+    [Test]
+    public void DeserializeTypeNameWithNoTypeNameHandling()
+    {
+      string employeeRef = typeof(EmployeeReference).AssemblyQualifiedName;
+
+      string json = @"{
+  ""$id"": ""1"",
+  ""$type"": """ + employeeRef + @""",
+  ""Name"": ""Name!"",
+  ""Manager"": null
+}";
+
+      JObject o = (JObject)JsonConvert.DeserializeObject(json);
+
+      Assert.AreEqual(@"{
+  ""Name"": ""Name!"",
+  ""Manager"": null
+}", o.ToString());
+    }
+
+    [Test]
+    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "Type specified in JSON 'Newtonsoft.Json.Tests.TestObjects.Employee' was not resolved.")]
+    public void DeserializeTypeNameOnly()
+    {
+      string json = @"{
+  ""$id"": ""1"",
+  ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Employee"",
+  ""Name"": ""Name!"",
+  ""Manager"": null
+}";
+
+      JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings
+      {
+        TypeNameHandling = TypeNameHandling.Objects
+      });
+    }
+
+    public interface ICorrelatedMessage
+    {
+      string CorrelationId { get; set; }
+    }
+
+    public class SendHttpRequest : ICorrelatedMessage
+    {
+      public SendHttpRequest()
+      {
+        RequestEncoding = "UTF-8";
+        Method = "GET";
+      }
+      public string Method { get; set; }
+      public Dictionary<string, string> Headers { get; set; }
+      public string Url { get; set; }
+      public Dictionary<string, string> RequestData;
+      public string RequestBodyText { get; set; }
+      public string User { get; set; }
+      public string Passwd { get; set; }
+      public string RequestEncoding { get; set; }
+      public string CorrelationId { get; set; }
+    }
+
+    [Test]
+    public void DeserializeGenericTypeName()
+    {
+      string typeName = typeof(SendHttpRequest).AssemblyQualifiedName;
+
+      string json = @"{
+""$type"": """ + typeName + @""",
+""RequestData"": {
+""$type"": ""System.Collections.Generic.Dictionary`2[[System.String, mscorlib,Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"",
+""Id"": ""siedemnaście"",
+""X"": ""323""
+},
+""Method"": ""GET"",
+""Url"": ""http://www.onet.pl"",
+""RequestEncoding"": ""UTF-8"",
+""CorrelationId"": ""xyz""
+}";
+
+      ICorrelatedMessage message = JsonConvert.DeserializeObject<ICorrelatedMessage>(json, new JsonSerializerSettings
+        {
+          TypeNameHandling = TypeNameHandling.Objects,
+          TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
+        });
+
+      Assert.IsInstanceOfType(typeof(SendHttpRequest), message);
+
+      SendHttpRequest request = (SendHttpRequest)message;
+      Assert.AreEqual("xyz", request.CorrelationId);
+      Assert.AreEqual(2, request.RequestData.Count);
+      Assert.AreEqual("siedemnaście", request.RequestData["Id"]);
+    }
+
+    [Test]
+    public void SerializeObjectWithMultipleGenericLists()
+    {
+      string containerTypeName = typeof(Container).AssemblyQualifiedName;
+      string productListTypeName = typeof(List<Product>).AssemblyQualifiedName;
+
+      Container container = new Container
+                          {
+                            In = new List<Product>(),
+                            Out = new List<Product>()
+                          };
+
+      string json = JsonConvert.SerializeObject(container, Formatting.Indented,
+          new JsonSerializerSettings
+              {
+                NullValueHandling = NullValueHandling.Ignore,
+                TypeNameHandling = TypeNameHandling.All,
+                TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
+              });
+
+      Assert.AreEqual(@"{
+  ""$type"": """ + containerTypeName + @""",
+  ""In"": {
+    ""$type"": """ + productListTypeName + @""",
+    ""$values"": []
+  },
+  ""Out"": {
+    ""$type"": """ + productListTypeName + @""",
+    ""$values"": []
+  }
+}", json);
+    }
+
+    public class TypeNameProperty
+    {
+      public string Name { get; set; }
+      [JsonProperty(TypeNameHandling = TypeNameHandling.All)]
+      public object Value { get; set; }
+    }
+
+    [Test]
+    public void WriteObjectTypeNameForProperty()
+    {
+      string typeNamePropertyRef = ReflectionUtils.GetTypeName(typeof(TypeNameProperty), FormatterAssemblyStyle.Simple);
+
+      TypeNameProperty typeNameProperty = new TypeNameProperty
+                                            {
+                                              Name = "Name!",
+                                              Value = new TypeNameProperty
+                                                        {
+                                                          Name = "Nested!"
+                                                        }
+                                            };
+
+      string json = JsonConvert.SerializeObject(typeNameProperty, Formatting.Indented);
+
+      Assert.AreEqual(@"{
+  ""Name"": ""Name!"",
+  ""Value"": {
+    ""$type"": """ + typeNamePropertyRef + @""",
+    ""Name"": ""Nested!"",
+    ""Value"": null
+  }
+}", json);
+
+      TypeNameProperty deserialized = JsonConvert.DeserializeObject<TypeNameProperty>(json);
+      Assert.AreEqual("Name!", deserialized.Name);
+      Assert.IsInstanceOfType(typeof(TypeNameProperty), deserialized.Value);
+
+      TypeNameProperty nested = (TypeNameProperty)deserialized.Value;
+      Assert.AreEqual("Nested!", nested.Name);
+      Assert.AreEqual(null, nested.Value);
+    }
+
+    [Test]
+    public void WriteListTypeNameForProperty()
+    {
+      string listRef = ReflectionUtils.GetTypeName(typeof(List<int>), FormatterAssemblyStyle.Simple);
+
+      TypeNameProperty typeNameProperty = new TypeNameProperty
+      {
+        Name = "Name!",
+        Value = new List<int> { 1, 2, 3, 4, 5 }
+      };
+
+      string json = JsonConvert.SerializeObject(typeNameProperty, Formatting.Indented);
+
+      Assert.AreEqual(@"{
+  ""Name"": ""Name!"",
+  ""Value"": {
+    ""$type"": """ + listRef + @""",
+    ""$values"": [
+      1,
+      2,
+      3,
+      4,
+      5
+    ]
+  }
+}", json);
+
+      TypeNameProperty deserialized = JsonConvert.DeserializeObject<TypeNameProperty>(json);
+      Assert.AreEqual("Name!", deserialized.Name);
+      Assert.IsInstanceOfType(typeof(List<int>), deserialized.Value);
+
+      List<int> nested = (List<int>)deserialized.Value;
+      Assert.AreEqual(5, nested.Count);
+      Assert.AreEqual(1, nested[0]);
+      Assert.AreEqual(2, nested[1]);
+      Assert.AreEqual(3, nested[2]);
+      Assert.AreEqual(4, nested[3]);
+      Assert.AreEqual(5, nested[4]);
+    }
+
+#if !SILVERLIGHT && !PocketPC
+    [Test]
+    public void DeserializeUsingCustomBinder()
+    {
+      string json = @"{
+  ""$id"": ""1"",
+  ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Employee"",
+  ""Name"": ""Name!""
+}";
+
+      object p = JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings
+      {
+        TypeNameHandling = TypeNameHandling.Objects,
+        Binder = new CustomSerializationBinder()
+      });
+
+      Assert.IsInstanceOfType(typeof(Person), p);
+
+      Person person = (Person)p;
+
+      Assert.AreEqual("Name!", person.Name);
+    }
+
+    public class CustomSerializationBinder : SerializationBinder
+    {
+      public override Type BindToType(string assemblyName, string typeName)
+      {
+        return typeof (Person);
+      }
+    }
+#endif
+
+    [Test]
+    public void CollectionWithAbstractItems()
+    {
+      HolderClass testObject = new HolderClass();
+      testObject.TestMember = new ContentSubClass("First One");
+      testObject.AnotherTestMember = new Dictionary<int, IList<ContentBaseClass>>();
+      testObject.AnotherTestMember.Add(1, new List<ContentBaseClass>());
+      testObject.AnotherTestMember[1].Add(new ContentSubClass("Second One"));
+      testObject.AThirdTestMember = new ContentSubClass("Third One");
+
+
+      JsonSerializer serializingTester = new JsonSerializer();
+      serializingTester.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
+
+      StringWriter sw = new StringWriter();
+      using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
+      {
+        jsonWriter.Formatting = Formatting.Indented;
+        serializingTester.TypeNameHandling = TypeNameHandling.Auto;
+        serializingTester.Serialize(jsonWriter, testObject);
+      }
+
+      string json = sw.ToString();
+
+      string contentSubClassRef = ReflectionUtils.GetTypeName(typeof(ContentSubClass), FormatterAssemblyStyle.Simple);
+      string dictionaryRef = ReflectionUtils.GetTypeName(typeof(Dictionary<int, IList<ContentBaseClass>>), FormatterAssemblyStyle.Simple);
+      string listRef = ReflectionUtils.GetTypeName(typeof(List<ContentBaseClass>), FormatterAssemblyStyle.Simple);
+
+
+      Assert.AreEqual(@"{
+  ""TestMember"": {
+    ""$type"": """ + contentSubClassRef + @""",
+    ""SomeString"": ""First One""
+  },
+  ""AnotherTestMember"": {
+    ""$type"": """ + dictionaryRef + @""",
+    ""1"": {
+      ""$type"": """ + listRef + @""",
+      ""$values"": [
+        {
+          ""$type"": """ + contentSubClassRef + @""",
+          ""SomeString"": ""Second One""
+        }
+      ]
+    }
+  },
+  ""AThirdTestMember"": {
+    ""$type"": """ + contentSubClassRef + @""",
+    ""SomeString"": ""Third One""
+  }
+}", json);
+      Console.WriteLine(json);
+
+      StringReader sr = new StringReader(json);
+
+      JsonSerializer deserializingTester = new JsonSerializer();
+
+      HolderClass anotherTestObject;
+
+      using (JsonTextReader jsonReader = new JsonTextReader(sr))
+      {
+        deserializingTester.TypeNameHandling = TypeNameHandling.Auto;
+
+        anotherTestObject = deserializingTester.Deserialize<HolderClass>(jsonReader);
+      }
+
+      Assert.IsNotNull(anotherTestObject);
+      Assert.IsInstanceOfType(typeof(ContentSubClass), anotherTestObject.TestMember);
+      Assert.IsInstanceOfType(typeof(Dictionary<int, IList<ContentBaseClass>>), anotherTestObject.AnotherTestMember);
+      Assert.AreEqual(1, anotherTestObject.AnotherTestMember.Count);
+
+      IList<ContentBaseClass> list = anotherTestObject.AnotherTestMember[1];
+
+      Assert.IsInstanceOfType(typeof(List<ContentBaseClass>), list);
+      Assert.AreEqual(1, list.Count);
+      Assert.IsInstanceOfType(typeof(ContentSubClass), list[0]);
+    }
+
+    [Test]
+    public void WriteObjectTypeNameForPropertyDemo()
+    {
+      Message message = new Message();
+      message.Address = "http://www.google.com";
+      message.Body = new SearchDetails
+        {
+          Query = "Json.NET",
+          Language = "en-us"
+        };
+
+      string json = JsonConvert.SerializeObject(message, Formatting.Indented);
+      // {
+      //   "Address": "http://www.google.com",
+      //   "Body": {
+      //     "$type": "Newtonsoft.Json.Tests.Serialization.SearchDetails, Newtonsoft.Json.Tests",
+      //     "Query": "Json.NET",
+      //     "Language": "en-us"
+      //   }
+      // }
+
+      Message deserialized = JsonConvert.DeserializeObject<Message>(json);
+
+      SearchDetails searchDetails = (SearchDetails) deserialized.Body;
+      // Json.NET
+    }
+
+    public class UrlStatus
+    {
+      public int Status { get; set; }
+      public string Url { get; set; }
+    }
+
+
+    [Test]
+    public void GenericDictionaryObject()
+    {
+      Dictionary<string, object> collection = new Dictionary<string, object>()
+        {
+          {"First", new UrlStatus{ Status = 404, Url = @"http://www.bing.com"}},
+          {"Second", new UrlStatus{Status = 400, Url = @"http://www.google.com"}},
+          {"List", new List<UrlStatus>
+            {
+              new UrlStatus {Status = 300, Url = @"http://www.yahoo.com"},
+              new UrlStatus {Status = 200, Url = @"http://www.askjeeves.com"}
+            }
+          }
+        };
+
+      string json = JsonConvert.SerializeObject(collection, Formatting.Indented, new JsonSerializerSettings
+      {
+        TypeNameHandling = TypeNameHandling.All,
+        TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple
+      });
+
+      string urlStatusTypeName = ReflectionUtils.GetTypeName(typeof (UrlStatus), FormatterAssemblyStyle.Simple);
+
+      Assert.AreEqual(@"{
+  ""$type"": ""System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Object, mscorlib]], mscorlib"",
+  ""First"": {
+    ""$type"": """ + urlStatusTypeName + @""",
+    ""Status"": 404,
+    ""Url"": ""http://www.bing.com""
+  },
+  ""Second"": {
+    ""$type"": """ + urlStatusTypeName + @""",
+    ""Status"": 400,
+    ""Url"": ""http://www.google.com""
+  },
+  ""List"": {
+    ""$type"": ""System.Collections.Generic.List`1[[" + urlStatusTypeName + @"]], mscorlib"",
+    ""$values"": [
+      {
+        ""$type"": """ + urlStatusTypeName + @""",
+        ""Status"": 300,
+        ""Url"": ""http://www.yahoo.com""
+      },
+      {
+        ""$type"": """ + urlStatusTypeName + @""",
+        ""Status"": 200,
+        ""Url"": ""http://www.askjeeves.com""
+      }
+    ]
+  }
+}", json);
+
+      object c = JsonConvert.DeserializeObject(json, new JsonSerializerSettings
+      {
+        TypeNameHandling = TypeNameHandling.All,
+        TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple
+      });
+
+      Assert.IsInstanceOfType(typeof(Dictionary<string, object>), c);
+
+      Dictionary<string, object> newCollection = (Dictionary<string, object>)c;
+      Assert.AreEqual(3, newCollection.Count);
+      Assert.AreEqual(@"http://www.bing.com", ((UrlStatus)newCollection["First"]).Url);
+
+      List<UrlStatus> statues = (List<UrlStatus>) newCollection["List"];
+      Assert.AreEqual(2, statues.Count);
+    }
+
+
+    [Test]
+    public void SerializingIEnumerableOfTShouldRetainGenericTypeInfo()
+    {
+      string productClassRef = ReflectionUtils.GetTypeName(typeof(Product[]), FormatterAssemblyStyle.Simple);
+
+      CustomEnumerable<Product> products = new CustomEnumerable<Product>();
+
+      string json = JsonConvert.SerializeObject(products, Formatting.Indented, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All });
+
+      Assert.AreEqual(@"{
+  ""$type"": """ + productClassRef + @""",
+  ""$values"": []
+}", json);
+    }
+
+    public class CustomEnumerable<T> : IEnumerable<T>
+    {
+      //NOTE: a simple linked list
+      private readonly T value;
+      private readonly CustomEnumerable<T> next;
+      private readonly int count;
+
+      private CustomEnumerable(T value, CustomEnumerable<T> next)
+      {
+        this.value = value;
+        this.next = next;
+        count = this.next.count + 1;
+      }
+
+      public CustomEnumerable()
+      {
+        count = 0;
+      }
+
+      public CustomEnumerable<T> AddFirst(T newVal)
+      {
+        return new CustomEnumerable<T>(newVal, this);
+      }
+
+      public IEnumerator<T> GetEnumerator()
+      {
+        if (count == 0) // last node
+          yield break;
+        yield return value;
+
+        var nextInLine = next;
+        while (nextInLine != null)
+        {
+          if (nextInLine.count != 0)
+            yield return nextInLine.value;
+          nextInLine = nextInLine.next;
+        }
+      }
+
+      IEnumerator IEnumerable.GetEnumerator()
+      {
+        return GetEnumerator();
+      }
+    }
+
+  }
+
+  public class Message
+  {
+    public string Address { get; set; }
+
+    [JsonProperty(TypeNameHandling = TypeNameHandling.All)]
+    public object Body { get; set; }
+  }
+
+  public class SearchDetails
+  {
+    public string Query { get; set; }
+    public string Language { get; set; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/SilverlightTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/SilverlightTests.cs
new file mode 100644 (file)
index 0000000..4b1b579
--- /dev/null
@@ -0,0 +1,21 @@
+using System;
+using System.Reflection;
+using NUnit.Framework;
+
+namespace Newtonsoft.Json.Tests
+{
+  // todo: need to fix this to get WP unit tests running off right dlls
+#if SILVERLIGHT
+  [TestFixture]
+  public class SilverlightTests
+  {
+    [Test]
+    public void SystemVersion()
+    {
+      Assembly systemAssembly = typeof(Uri).Assembly;
+      StringAssert.Contains("=4.0.0.0,", systemAssembly.FullName,
+          "Check we're testing a Silverlight 4.0 assembly");
+    }
+  }
+#endif
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestFixtureBase.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestFixtureBase.cs
new file mode 100644 (file)
index 0000000..73690c9
--- /dev/null
@@ -0,0 +1,64 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using NUnit.Framework;
+
+namespace Newtonsoft.Json.Tests
+{
+  [TestFixture]
+  public abstract class TestFixtureBase
+  {
+    [SetUp]
+    protected void TestSetup()
+    {
+      //CultureInfo turkey = CultureInfo.CreateSpecificCulture("tr");
+      //Thread.CurrentThread.CurrentCulture = turkey;
+      //Thread.CurrentThread.CurrentUICulture = turkey;
+    }
+
+    //public string GetOffset(DateTime value)
+    //{
+    //  TimeSpan utcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(value.ToLocalTime());
+
+    //  return utcOffset.Hours.ToString("+00;-00") + utcOffset.Minutes.ToString("00;00");
+    //}
+
+    protected void WriteEscapedJson(string json)
+    {
+      Console.WriteLine(EscapeJson(json));
+    }
+
+    protected string EscapeJson(string json)
+    {
+      return @"@""" + json.Replace(@"""", @"""""") + @"""";
+    }
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/AbstractGenericBase.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/AbstractGenericBase.cs
new file mode 100644 (file)
index 0000000..942f684
--- /dev/null
@@ -0,0 +1,32 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public abstract class AbstractGenericBase<TKey>
+  {
+    public abstract TKey Id { get; set; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ArgumentConverterPrecedenceClassConverter.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ArgumentConverterPrecedenceClassConverter.cs
new file mode 100644 (file)
index 0000000..9c29d1a
--- /dev/null
@@ -0,0 +1,35 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class ArgumentConverterPrecedenceClassConverter : ConverterPrecedenceClassConverter
+  {
+    public override string ConverterType
+    {
+      get { return "Argument"; }
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Article.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Article.cs
new file mode 100644 (file)
index 0000000..dfde60c
--- /dev/null
@@ -0,0 +1,41 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class Article
+  {
+    public string Name;
+
+    public Article()
+    {
+    }
+
+    public Article(string name)
+    {
+      Name = name;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ArticleCollection.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ArticleCollection.cs
new file mode 100644 (file)
index 0000000..e7f4ae1
--- /dev/null
@@ -0,0 +1,33 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System.Collections.Generic;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class ArticleCollection : List<Article>
+  {
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/BadJsonPropertyClass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/BadJsonPropertyClass.cs
new file mode 100644 (file)
index 0000000..18d0a03
--- /dev/null
@@ -0,0 +1,35 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class BadJsonPropertyClass
+  {
+    [JsonProperty("pie")]
+    public string Pie = "Yum";
+
+    public string pie = "PieChart!";
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Bar.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Bar.cs
new file mode 100644 (file)
index 0000000..d70adc6
--- /dev/null
@@ -0,0 +1,32 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class Bar
+  {
+    public int Id { get; set; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Car.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Car.cs
new file mode 100644 (file)
index 0000000..7071d6c
--- /dev/null
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class Car
+  {
+    // included in JSON
+    public string Model { get; set; }
+    public DateTime Year { get; set; }
+    public List<string> Features { get; set; }
+
+    // ignored
+    [JsonIgnore]
+    public DateTime LastModified { get; set; }
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/CircularReferenceClass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/CircularReferenceClass.cs
new file mode 100644 (file)
index 0000000..4db092c
--- /dev/null
@@ -0,0 +1,40 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class CircularReferenceClass
+  {
+    [JsonProperty(Required = Required.Always)]
+    public string Name { get; set; }
+    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
+    public CircularReferenceClass Child { get; set; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/CircularReferenceWithIdClass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/CircularReferenceWithIdClass.cs
new file mode 100644 (file)
index 0000000..f852d8f
--- /dev/null
@@ -0,0 +1,40 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  [JsonObject(Id = "MyExplicitId")]
+  public class CircularReferenceWithIdClass
+  {
+    [JsonProperty(Required = Required.AllowNull)]
+    public string Name { get; set; }
+    public CircularReferenceWithIdClass Child { get; set; }
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ClassAndMemberConverterClass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ClassAndMemberConverterClass.cs
new file mode 100644 (file)
index 0000000..98bd253
--- /dev/null
@@ -0,0 +1,34 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class ClassAndMemberConverterClass
+  {
+    public ConverterPrecedenceClass DefaultConverter { get; set; }
+    [JsonConverter(typeof(MemberConverterPrecedenceClassConverter))]
+    public ConverterPrecedenceClass MemberConverter { get; set; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ClassConverterPrecedenceClassConverter.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ClassConverterPrecedenceClassConverter.cs
new file mode 100644 (file)
index 0000000..892fe29
--- /dev/null
@@ -0,0 +1,35 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class ClassConverterPrecedenceClassConverter : ConverterPrecedenceClassConverter
+  {
+    public override string ConverterType
+    {
+      get { return "Class"; }
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ClassWithArray.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ClassWithArray.cs
new file mode 100644 (file)
index 0000000..74c042e
--- /dev/null
@@ -0,0 +1,54 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class ClassWithArray
+  {
+    private readonly IList<long> bar;
+    private string foo;
+
+    public ClassWithArray()
+    {
+      bar = new List<Int64>() { int.MaxValue };
+    }
+
+    [JsonProperty("foo")]
+    public string Foo
+    {
+      get { return foo; }
+      set { foo = value; }
+    }
+
+    [JsonProperty(PropertyName = "bar")]
+    public IList<long> Bar
+    {
+      get { return bar; }
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ClassWithGuid.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ClassWithGuid.cs
new file mode 100644 (file)
index 0000000..82e345a
--- /dev/null
@@ -0,0 +1,34 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class ClassWithGuid
+  {
+    public Guid GuidField;
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Computer.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Computer.cs
new file mode 100644 (file)
index 0000000..25b0bab
--- /dev/null
@@ -0,0 +1,48 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Runtime.Serialization;
+
+#if !PocketPC && !NET20
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  [DataContract]
+  public class Computer
+  {
+    // included in JSON
+    [DataMember]
+    public string Name { get; set; }
+    [DataMember]
+    public decimal SalePrice { get; set; }
+
+    // ignored
+    public string Manufacture { get; set; }
+    public int StockCount { get; set; }
+    public decimal WholeSalePrice { get; set; }
+    public DateTime NextShipmentDate { get; set; }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ConstructorCaseSensitivityClass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ConstructorCaseSensitivityClass.cs
new file mode 100644 (file)
index 0000000..17edf25
--- /dev/null
@@ -0,0 +1,41 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class ConstructorCaseSensitivityClass
+  {
+    public string param1 { get; set; }
+    public string Param1 { get; set; }
+    public string Param2 { get; set; }
+
+    public ConstructorCaseSensitivityClass(string param1, string Param1, string param2)
+    {
+      this.param1 = param1;
+      this.Param1 = Param1;
+      this.Param2 = param2;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ConstructorReadonlyFields.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ConstructorReadonlyFields.cs
new file mode 100644 (file)
index 0000000..4bbaf35
--- /dev/null
@@ -0,0 +1,39 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class ConstructorReadonlyFields
+  {
+    public readonly string A;
+    public readonly int B;
+
+    public ConstructorReadonlyFields(string a, int b)
+    {
+      A = a;
+      B = b;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Container.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Container.cs
new file mode 100644 (file)
index 0000000..451149a
--- /dev/null
@@ -0,0 +1,10 @@
+using System.Collections.Generic;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class Container
+  {
+    public IList<Product> In { get; set; }
+    public IList<Product> Out { get; set; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Content.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Content.cs
new file mode 100644 (file)
index 0000000..6f8ae78
--- /dev/null
@@ -0,0 +1,49 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  [JsonObject(MemberSerialization = MemberSerialization.OptIn)]
+  public class Content : IEnumerable<Content>
+  {
+    [JsonProperty]
+    public List<Content> Children;
+    [JsonProperty]
+    public string Text;
+
+    public IEnumerator GetEnumerator()
+    {
+      return Children.GetEnumerator();
+    }
+
+    IEnumerator<Content> IEnumerable<Content>.GetEnumerator()
+    {
+      return Children.GetEnumerator();
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ContentBaseClass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ContentBaseClass.cs
new file mode 100644 (file)
index 0000000..210242e
--- /dev/null
@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public abstract class ContentBaseClass
+  {
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ContentSubClass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ContentSubClass.cs
new file mode 100644 (file)
index 0000000..6df0229
--- /dev/null
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class ContentSubClass : ContentBaseClass
+  {
+    public ContentSubClass() { }
+    public ContentSubClass(string EasyIn)
+    {
+      SomeString = EasyIn;
+    }
+
+    public string SomeString { get; set; }
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ConverableMembers.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ConverableMembers.cs
new file mode 100644 (file)
index 0000000..4fcc93b
--- /dev/null
@@ -0,0 +1,48 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  [JsonObject]
+  public class ConverableMembers
+  {
+    public string String = "string";
+    public int Int32 = int.MaxValue;
+    public uint UInt32 = uint.MaxValue;
+    public byte Byte = byte.MaxValue;
+    public sbyte SByte = sbyte.MaxValue;
+    public short Short = short.MaxValue;
+    public ushort UShort = ushort.MaxValue;
+    public long Long = long.MaxValue;
+    public ulong ULong = long.MaxValue;
+    public double Double = double.MaxValue;
+    public float Float = float.MaxValue;
+    public DBNull DBNull = DBNull.Value;
+    public bool Bool = true;
+    public char Char = '\0';
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ConverterPrecedenceClass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ConverterPrecedenceClass.cs
new file mode 100644 (file)
index 0000000..145427c
--- /dev/null
@@ -0,0 +1,38 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  [JsonConverter(typeof(ClassConverterPrecedenceClassConverter))]
+  public class ConverterPrecedenceClass
+  {
+    public string TestValue { get; set; }
+
+    public ConverterPrecedenceClass(string testValue)
+    {
+      TestValue = testValue;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ConverterPrecedenceClassConverter.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ConverterPrecedenceClassConverter.cs
new file mode 100644 (file)
index 0000000..f605b22
--- /dev/null
@@ -0,0 +1,63 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Globalization;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public abstract class ConverterPrecedenceClassConverter : JsonConverter
+  {
+    public abstract string ConverterType { get; }
+
+    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+    {
+      ConverterPrecedenceClass c = (ConverterPrecedenceClass)value;
+
+      JToken j = new JArray(ConverterType, c.TestValue);
+
+      j.WriteTo(writer);
+    }
+
+    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+    {
+      JToken j = JArray.Load(reader);
+
+      string converter = (string)j[0];
+      if (converter != ConverterType)
+        throw new Exception(StringUtils.FormatWith("Serialize converter {0} and deserialize converter {1} do not match.", CultureInfo.InvariantCulture, converter, ConverterType));
+
+      string testValue = (string)j[1];
+      return new ConverterPrecedenceClass(testValue);
+    }
+
+    public override bool CanConvert(Type objectType)
+    {
+      return (objectType == typeof(ConverterPrecedenceClass));
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/DateTimeErrorObjectCollection.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/DateTimeErrorObjectCollection.cs
new file mode 100644 (file)
index 0000000..0f4d724
--- /dev/null
@@ -0,0 +1,41 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.ObjectModel;
+using System.Runtime.Serialization;
+using Newtonsoft.Json.Serialization;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class DateTimeErrorObjectCollection : Collection<DateTime>
+  {
+    [OnError]
+    internal void OnErrorMethod(StreamingContext context, ErrorContext errorContext)
+    {
+      errorContext.Handled = true;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/DateTimeTestClass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/DateTimeTestClass.cs
new file mode 100644 (file)
index 0000000..17d328c
--- /dev/null
@@ -0,0 +1,45 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+#if !PocketPC && !NET20
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class DateTimeTestClass
+  {
+    public string PreField { get; set; }
+    [DefaultValue("")]
+    [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
+    public DateTime DateTimeField { get; set; }
+    public DateTimeOffset DateTimeOffsetField { get; set; }
+    public string PostField { get; set; }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/DefaultValueAttributeTestClass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/DefaultValueAttributeTestClass.cs
new file mode 100644 (file)
index 0000000..b6b7c69
--- /dev/null
@@ -0,0 +1,41 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System.ComponentModel;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+#if !PocketPC
+  [Description("DefaultValueAttributeTestClass description!")]
+#endif
+  public sealed class DefaultValueAttributeTestClass
+  {
+    [DefaultValue("TestProperty1Value")]
+    public string TestProperty1 { get; set; }
+
+    [DefaultValue(21)]
+    public int TestField1;
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/DictionaryInterfaceClass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/DictionaryInterfaceClass.cs
new file mode 100644 (file)
index 0000000..6d8e12a
--- /dev/null
@@ -0,0 +1,57 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System.Collections.Generic;
+using Newtonsoft.Json.Tests.TestObjects;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class DictionaryInterfaceClass
+  {
+    public string Name { get; set; }
+    public IDictionary<string, int> Dictionary { get; set; }
+    public ICollection<int> Collection { get; set; }
+    public EmployeeReference Employee { get; set; }
+    public object Random { get; set; }
+
+    public DictionaryInterfaceClass()
+    {
+      Dictionary = new Dictionary<string, int>
+        {
+          { "existing", 1 }
+        };
+      Collection = new List<int>
+        {
+          1,
+          2,
+          3
+        };
+      Employee = new EmployeeReference
+        {
+          Name = "EmployeeName!"
+        };
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/DoubleClass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/DoubleClass.cs
new file mode 100644 (file)
index 0000000..df110cb
--- /dev/null
@@ -0,0 +1,32 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class DoubleClass
+  {
+    public double? Height { get; set; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/EmployeeReference.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/EmployeeReference.cs
new file mode 100644 (file)
index 0000000..241fb65
--- /dev/null
@@ -0,0 +1,39 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  [JsonObject(IsReference = true)]
+  public class EmployeeReference
+  {
+    public string Name { get; set; }
+    public EmployeeReference Manager { get; set; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Event.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Event.cs
new file mode 100644 (file)
index 0000000..b58b126
--- /dev/null
@@ -0,0 +1,148 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  /// <summary>
+  /// What types of events are there? Just sticking to a basic set of four for now.
+  /// </summary>
+  /// <remarks></remarks>
+  public enum EventType
+  {
+    Debug = 0,
+    Info = 1,
+    Warning = 2,
+    Error = 3
+  }
+
+  public sealed class Event
+  {
+
+    /// <summary>
+    /// If no current user is specified, returns Nothing (0 from VB)
+    /// </summary>
+    /// <returns></returns>
+    /// <remarks></remarks>
+    private static int GetCurrentUserId()
+    {
+      return 0;
+    }
+
+    /// <summary>
+    /// Gets either the application path or the current stack trace.
+    /// NOTE: You MUST call this from the top level entry point. Otherwise,
+    /// the stack trace will be buried in Logger itself.
+    /// </summary>
+    /// <returns></returns>
+    /// <remarks></remarks>
+    private static string GetCurrentSubLocation()
+    {
+      return "";
+    }
+
+    private string _sublocation;
+    private int _userId;
+    private EventType _type;
+    private string _summary;
+    private string _details;
+    private string _stackTrace;
+    private string _tag;
+    private DateTime _time;
+
+    public Event(string summary)
+    {
+      _summary = summary;
+      _time = DateTime.Now;
+
+      if (_userId == 0) _userId = GetCurrentUserId();
+      //This call only works at top level for now.
+      //If _stackTrace = Nothing Then _stackTrace = Environment.StackTrace
+      if (_sublocation == null) _sublocation = GetCurrentSubLocation();
+    }
+
+    public Event(string sublocation, int userId, EventType type, string summary, string details, string stackTrace, string tag)
+    {
+      _sublocation = sublocation;
+      _userId = userId;
+      _type = type;
+      _summary = summary;
+      _details = details;
+      _stackTrace = stackTrace;
+      _tag = tag;
+      _time = DateTime.Now;
+
+      if (_userId == 0) _userId = GetCurrentUserId();
+      //If _stackTrace = Nothing Then _stackTrace = Environment.StackTrace
+      if (_sublocation == null) _sublocation = GetCurrentSubLocation();
+    }
+
+    public override string ToString()
+    {
+      return string.Format("{{ sublocation = {0}, userId = {1}, type = {2}, summary = {3}, details = {4}, stackTrace = {5}, tag = {6} }}", _sublocation, _userId, _type, _summary, _details, _stackTrace, _tag);
+    }
+
+    public string sublocation
+    {
+      get { return _sublocation; }
+      set { _sublocation = value; }
+    }
+    public int userId
+    {
+      get { return _userId; }
+      set { _userId = value; }
+    }
+    public EventType type
+    {
+      get { return _type; }
+      set { _type = value; }
+    }
+    public string summary
+    {
+      get { return _summary; }
+      set { _summary = value; }
+    }
+    public string details
+    {
+      get { return _details; }
+      set { _details = value; }
+    }
+    public string stackTrace
+    {
+      get { return _stackTrace; }
+      set { _stackTrace = value; }
+    }
+    public string tag
+    {
+      get { return _tag; }
+      set { _tag = value; }
+    }
+    public DateTime time
+    {
+      get { return _time; }
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Foo.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Foo.cs
new file mode 100644 (file)
index 0000000..657037b
--- /dev/null
@@ -0,0 +1,40 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System.Collections.Generic;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class Foo
+  {
+    public Foo()
+    {
+      Bars = new List<Bar>();
+    }
+
+    [JsonConverter(typeof(ListOfIds<Bar>))]
+    public List<Bar> Bars { get; set; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/GenericImpl.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/GenericImpl.cs
new file mode 100644 (file)
index 0000000..e4b82c8
--- /dev/null
@@ -0,0 +1,32 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class GenericImpl : AbstractGenericBase<int>
+  {
+    public override int Id { get; set; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/GenericListAndDictionaryInterfaceProperties.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/GenericListAndDictionaryInterfaceProperties.cs
new file mode 100644 (file)
index 0000000..87fefc4
--- /dev/null
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class GenericListAndDictionaryInterfaceProperties
+  {
+    public IEnumerable<int> IEnumerableProperty { get; set; }
+    public IList<int> IListProperty { get; set; }
+    public IDictionary<string, int> IDictionaryProperty { get; set; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/GetOnlyPropertyClass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/GetOnlyPropertyClass.cs
new file mode 100644 (file)
index 0000000..4243aa1
--- /dev/null
@@ -0,0 +1,37 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class GetOnlyPropertyClass
+  {
+    public string Field = "Field";
+
+    public string GetOnlyProperty
+    {
+      get { return "GetOnlyProperty"; }
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/GoogleMapGeocoderStructure.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/GoogleMapGeocoderStructure.cs
new file mode 100644 (file)
index 0000000..ceee06f
--- /dev/null
@@ -0,0 +1,95 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System.Collections.Generic;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class GoogleMapGeocoderStructure
+  {
+    public string Name;
+    public Status Status;
+    public List<Placemark> Placemark;
+  }
+
+  public class Status
+  {
+    public string Request;
+    public string Code;
+  }
+
+  public class Placemark
+  {
+    public string Address;
+    public AddressDetails AddressDetails;
+    public Point Point;
+  }
+
+  public class AddressDetails
+  {
+    public int Accuracy;
+    public Country Country;
+  }
+
+  public class Country
+  {
+    public string CountryNameCode;
+    public AdministrativeArea AdministrativeArea;
+  }
+
+  public class AdministrativeArea
+  {
+    public string AdministrativeAreaName;
+    public SubAdministrativeArea SubAdministrativeArea;
+  }
+
+  public class SubAdministrativeArea
+  {
+    public string SubAdministrativeAreaName;
+    public Locality Locality;
+  }
+
+  public class Locality
+  {
+    public string LocalityName;
+    public Thoroughfare Thoroughfare;
+    public PostalCode PostalCode;
+  }
+
+  public class Thoroughfare
+  {
+    public string ThoroughfareName;
+  }
+
+  public class PostalCode
+  {
+    public string PostalCodeNumber;
+  }
+
+  public class Point
+  {
+    public List<decimal> Coordinates;
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/HolderClass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/HolderClass.cs
new file mode 100644 (file)
index 0000000..4ddffb2
--- /dev/null
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class HolderClass
+  {
+    public HolderClass() { }
+
+    [Newtonsoft.Json.JsonProperty(TypeNameHandling = Newtonsoft.Json.TypeNameHandling.All)]
+    public ContentBaseClass TestMember { get; set; }
+
+    [Newtonsoft.Json.JsonProperty(TypeNameHandling = Newtonsoft.Json.TypeNameHandling.All)]
+    public Dictionary<int, IList<ContentBaseClass>> AnotherTestMember { get; set; }
+
+    public ContentBaseClass AThirdTestMember { get; set; }
+
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/IncompatibleJsonAttributeClass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/IncompatibleJsonAttributeClass.cs
new file mode 100644 (file)
index 0000000..d1f961e
--- /dev/null
@@ -0,0 +1,34 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using Newtonsoft.Json.Converters;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  [JsonConverter(typeof(IsoDateTimeConverter))]
+  public class IncompatibleJsonAttributeClass
+  {
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/InterfacePropertyTestClass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/InterfacePropertyTestClass.cs
new file mode 100644 (file)
index 0000000..9a3eb56
--- /dev/null
@@ -0,0 +1,51 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class Co : ICo
+  {
+    public string Name { get; set; }
+  }
+
+  public interface ICo
+  {
+    string Name { get; set; }
+  }
+
+  public interface IInterfacePropertyTestClass
+  {
+    ICo co { get; set; }
+  }
+
+  public class InterfacePropertyTestClass : IInterfacePropertyTestClass
+  {
+    public ICo co { get; set; }
+
+    public InterfacePropertyTestClass()
+    {
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Invoice.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Invoice.cs
new file mode 100644 (file)
index 0000000..bdce565
--- /dev/null
@@ -0,0 +1,47 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.ComponentModel;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class Invoice
+  {
+    public string Company { get; set; }
+    public decimal Amount { get; set; }
+
+    // false is default value of bool
+    public bool Paid { get; set; }
+    // null is default value of nullable
+    public DateTime? PaidDate { get; set; }
+
+    // customize default values
+    [DefaultValue(30)]
+    public int FollowUpDays { get; set; }
+    [DefaultValue("")]
+    public string FollowUpEmailAddress { get; set; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/JaggedArray.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/JaggedArray.cs
new file mode 100644 (file)
index 0000000..63cac1c
--- /dev/null
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class JaggedArray
+  {
+    public string Before { get; set; }
+    public int[][] Coordinates { get; set; }
+    public string After { get; set; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/JsonIgnoreAttributeOnClassTestClass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/JsonIgnoreAttributeOnClassTestClass.cs
new file mode 100644 (file)
index 0000000..27ff136
--- /dev/null
@@ -0,0 +1,52 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  [JsonObject(MemberSerialization.OptIn)]
+  public class JsonIgnoreAttributeOnClassTestClass
+  {
+    private int _property = 21;
+    private int _ignoredProperty = 12;
+
+    [JsonProperty("TheField")]
+    public int Field;
+
+    [JsonProperty]
+    public int Property
+    {
+      get { return _property; }
+    }
+
+    public int IgnoredField;
+
+    [JsonProperty]
+    [JsonIgnore] // JsonIgnore should take priority
+      public int IgnoredProperty
+    {
+      get { return _ignoredProperty; }
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/JsonIgnoreAttributeTestClass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/JsonIgnoreAttributeTestClass.cs
new file mode 100644 (file)
index 0000000..cb1fbde
--- /dev/null
@@ -0,0 +1,51 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class JsonIgnoreAttributeTestClass
+  {
+    private int _property = 21;
+    private int _ignoredProperty = 12;
+
+    public int Field;
+    public int Property
+    {
+      get { return _property; }
+    }
+
+    [JsonIgnore]
+    public int IgnoredField;
+
+    [JsonIgnore]
+    public int IgnoredProperty
+    {
+      get { return _ignoredProperty; }
+    }
+
+    [JsonIgnore]
+    public Product IgnoredObject = new Product();
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/JsonPropertyClass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/JsonPropertyClass.cs
new file mode 100644 (file)
index 0000000..1714f01
--- /dev/null
@@ -0,0 +1,47 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class JsonPropertyClass
+  {
+    [JsonProperty("pie")]
+    public string Pie = "Yum";
+
+    [JsonIgnore]
+    public string pie = "No pie for you!";
+
+    public string pie1 = "PieChart!";
+
+    private int _sweetCakesCount;
+
+    [JsonProperty("sweet_cakes_count")]
+    public int SweetCakesCount
+    {
+      get { return _sweetCakesCount; }
+      set { _sweetCakesCount = value; }
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/JsonPropertyWithHandlingValues.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/JsonPropertyWithHandlingValues.cs
new file mode 100644 (file)
index 0000000..6feb12d
--- /dev/null
@@ -0,0 +1,55 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System.ComponentModel;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class JsonPropertyWithHandlingValues
+  {
+    [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
+    [DefaultValue("Default!")]
+    public string DefaultValueHandlingIgnoreProperty { get; set; }
+
+    [JsonProperty(DefaultValueHandling = DefaultValueHandling.Include)]
+    [DefaultValue("Default!")]
+    public string DefaultValueHandlingIncludeProperty { get; set; }
+
+    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
+    public string NullValueHandlingIgnoreProperty { get; set; }
+
+    [JsonProperty(NullValueHandling = NullValueHandling.Include)]
+    public string NullValueHandlingIncludeProperty { get; set; }
+
+    [JsonProperty(ReferenceLoopHandling = ReferenceLoopHandling.Error)]
+    public JsonPropertyWithHandlingValues ReferenceLoopHandlingErrorProperty { get; set; }
+
+    [JsonProperty(ReferenceLoopHandling = ReferenceLoopHandling.Ignore)]
+    public JsonPropertyWithHandlingValues ReferenceLoopHandlingIgnoreProperty { get; set; }
+
+    [JsonProperty(ReferenceLoopHandling = ReferenceLoopHandling.Serialize)]
+    public JsonPropertyWithHandlingValues ReferenceLoopHandlingSerializeProperty { get; set; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ListErrorObject.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ListErrorObject.cs
new file mode 100644 (file)
index 0000000..800e682
--- /dev/null
@@ -0,0 +1,58 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class ListErrorObject
+  {
+    public string Member { get; set; }
+
+    private string _throwError;
+    public string ThrowError
+    {
+      get
+      {
+        if (_throwError != null)
+          return _throwError;
+
+        throw new Exception("ListErrorObject.ThrowError get error!");
+      }
+      set
+      {
+        if (value != null && value.StartsWith("Handle"))
+        {
+          _throwError = value;
+          return;
+        }
+
+        throw new Exception("ListErrorObject.ThrowError set error!");
+      }
+    }
+
+    public string Member2 { get; set; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ListErrorObjectCollection.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ListErrorObjectCollection.cs
new file mode 100644 (file)
index 0000000..2b37501
--- /dev/null
@@ -0,0 +1,40 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System.Collections.ObjectModel;
+using System.Runtime.Serialization;
+using Newtonsoft.Json.Serialization;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class ListErrorObjectCollection : Collection<ListErrorObject>
+  {
+    [OnError]
+    internal void OnErrorMethod(StreamingContext context, ErrorContext errorContext)
+    {
+      errorContext.Handled = true;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ListOfIds.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ListOfIds.cs
new file mode 100644 (file)
index 0000000..b7d68a3
--- /dev/null
@@ -0,0 +1,70 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class ListOfIds<T> : JsonConverter where T : Bar, new()
+  {
+    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+    {
+      IList<T> list = (IList<T>)value;
+
+      writer.WriteStartArray();
+      foreach (T item in list)
+      {
+        writer.WriteValue(item.Id);
+      }
+      writer.WriteEndArray();
+    }
+
+    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+    {
+      IList<T> list = new List<T>();
+
+      reader.Read();
+      while (reader.TokenType != JsonToken.EndArray)
+      {
+        long id = (long)reader.Value;
+
+        list.Add(new T
+                   {
+                     Id = Convert.ToInt32(id)
+                   });
+
+        reader.Read();
+      }
+
+      return list;
+    }
+
+    public override bool CanConvert(Type objectType)
+    {
+      return typeof(IList<T>).IsAssignableFrom(objectType);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ListTestClass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ListTestClass.cs
new file mode 100644 (file)
index 0000000..74ea35d
--- /dev/null
@@ -0,0 +1,45 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System.Collections.Generic;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  [JsonObject(MemberSerialization.OptIn)]
+  public class ListTestClass
+  {
+    [JsonProperty]
+    public string id { get; set; }
+    [JsonProperty]
+    public List<ListItem> items { get; set; }
+  }
+
+  [JsonObject(MemberSerialization.OptIn)]
+  public class ListItem
+  {
+    [JsonProperty]
+    public string id { get; set; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/LogEntry.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/LogEntry.cs
new file mode 100644 (file)
index 0000000..0dbd63f
--- /dev/null
@@ -0,0 +1,35 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class LogEntry
+  {
+    public string Details { get; set; }
+    public DateTime LogDate { get; set; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/MemberConverterClass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/MemberConverterClass.cs
new file mode 100644 (file)
index 0000000..89ab7a6
--- /dev/null
@@ -0,0 +1,37 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using Newtonsoft.Json.Converters;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class MemberConverterClass
+  {
+    public DateTime DefaultConverter { get; set; }
+    [JsonConverter(typeof(IsoDateTimeConverter))]
+    public DateTime MemberConverter { get; set; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/MemberConverterPrecedenceClassConverter.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/MemberConverterPrecedenceClassConverter.cs
new file mode 100644 (file)
index 0000000..afe3498
--- /dev/null
@@ -0,0 +1,35 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class MemberConverterPrecedenceClassConverter : ConverterPrecedenceClassConverter
+  {
+    public override string ConverterType
+    {
+      get { return "Member"; }
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/MethodExecutorObject.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/MethodExecutorObject.cs
new file mode 100644 (file)
index 0000000..7586d05
--- /dev/null
@@ -0,0 +1,34 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class MethodExecutorObject
+  {
+    public string serverClassName;
+    public object[] serverMethodParams;
+    public string clientGetResultFunction;
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Movie.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Movie.cs
new file mode 100644 (file)
index 0000000..3d568a9
--- /dev/null
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class Movie
+  {
+    public string Name { get; set; }
+    public string Description { get; set; }
+    public string Classification { get; set; }
+    public string Studio { get; set; }
+    public DateTime? ReleaseDate { get; set; }
+    public List<string> ReleaseCountries { get; set; }
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/MyClass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/MyClass.cs
new file mode 100644 (file)
index 0000000..d44da3d
--- /dev/null
@@ -0,0 +1,34 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class MyClass
+  {
+    public int PreProperty { get; set; }
+    //public DateTime DateProperty { get; set; }
+    public int PostProperty { get; set; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Name.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Name.cs
new file mode 100644 (file)
index 0000000..5e61336
--- /dev/null
@@ -0,0 +1,41 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System.Collections.Generic;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class Name
+  {
+    public string personsName;
+
+    public List<PhoneNumber> pNumbers = new List<PhoneNumber>();
+
+    public Name(string personsName)
+    {
+      this.personsName = personsName;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/NonRequest.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/NonRequest.cs
new file mode 100644 (file)
index 0000000..8f90268
--- /dev/null
@@ -0,0 +1,37 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class NonRequest
+  {
+    public Guid Sid { get; set; }
+    public Guid Uid { get; set; }
+    public IList<string> FidOrder { get; set; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/NullableDateTimeTestClass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/NullableDateTimeTestClass.cs
new file mode 100644 (file)
index 0000000..2ede479
--- /dev/null
@@ -0,0 +1,42 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+#if !PocketPC && !NET20
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class NullableDateTimeTestClass
+  {
+    public string PreField { get; set; }
+    public DateTime? DateTimeField { get; set; }
+    public DateTimeOffset? DateTimeOffsetField { get; set; }
+    public string PostField { get; set; }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ObjectArrayPropertyTest.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ObjectArrayPropertyTest.cs
new file mode 100644 (file)
index 0000000..1bea547
--- /dev/null
@@ -0,0 +1,34 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class ObjectArrayPropertyTest
+  {
+    public string Action { get; set; }
+    public string Method { get; set; }
+    public object[] Data { get; set; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Person.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Person.cs
new file mode 100644 (file)
index 0000000..7e93090
--- /dev/null
@@ -0,0 +1,54 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.ComponentModel;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  [JsonObject(Id = "Person", Title = "Title!", Description = "JsonObjectAttribute description!", MemberSerialization = MemberSerialization.OptIn)]
+#if !PocketPC
+  [Description("DescriptionAttribute description!")]
+#endif
+  public class Person
+  {
+    // "John Smith"
+    [JsonProperty]
+    public string Name { get; set; }
+
+    // "2000-12-15T22:11:03"
+    [JsonProperty]
+    //[JsonConverter(typeof(IsoDateTimeConverter))]
+    public DateTime BirthDate { get; set; }
+
+    // new Date(976918263055)
+    [JsonProperty]
+    //[JsonConverter(typeof(JavaScriptDateTimeConverter))]
+    public DateTime LastModified { get; set; }
+
+    // not serialized
+    public string Department { get; set; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/PersonError.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/PersonError.cs
new file mode 100644 (file)
index 0000000..6542198
--- /dev/null
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.Serialization;
+using System.Text;
+using Newtonsoft.Json.Serialization;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class PersonError
+  {
+    private List<string> _roles;
+
+    public string Name { get; set; }
+    public int Age { get; set; }
+    public List<string> Roles
+    {
+      get
+      {
+        if (_roles == null)
+          throw new Exception("Roles not loaded!");
+
+        return _roles;
+      }
+      set { _roles = value; }
+    }
+    public string Title { get; set; }
+
+    [OnError]
+    internal void HandleError(StreamingContext context, ErrorContext errorContext)
+    {
+      errorContext.Handled = true;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/PersonPropertyClass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/PersonPropertyClass.cs
new file mode 100644 (file)
index 0000000..f7ab01c
--- /dev/null
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class PersonPropertyClass
+  {
+    public Person Person { get; set; }
+
+    public PersonPropertyClass()
+    {
+      Person = new WagePerson();
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/PersonRaw.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/PersonRaw.cs
new file mode 100644 (file)
index 0000000..82f67ee
--- /dev/null
@@ -0,0 +1,65 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using Newtonsoft.Json.Linq;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class PersonRaw
+  {
+    private Guid _internalId;
+    private string _firstName;
+    private string _lastName;
+    private JRaw _rawContent;
+
+    [JsonIgnore]
+    public Guid InternalId
+    {
+      get { return _internalId; }
+      set { _internalId = value; }
+    }
+
+    [JsonProperty("first_name")]
+    public string FirstName
+    {
+      get { return _firstName; }
+      set { _firstName = value; }
+    }
+
+    public JRaw RawContent
+    {
+      get { return _rawContent; }
+      set { _rawContent = value; }
+    }
+
+    [JsonProperty("last_name")]
+    public string LastName
+    {
+      get { return _lastName; }
+      set { _lastName = value; }
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/PhoneNumber.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/PhoneNumber.cs
new file mode 100644 (file)
index 0000000..411c6a2
--- /dev/null
@@ -0,0 +1,37 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class PhoneNumber
+  {
+    public string phoneNumber;
+
+    public PhoneNumber(string phoneNumber)
+    {
+      this.phoneNumber = phoneNumber;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/PrivateConstructorTestClass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/PrivateConstructorTestClass.cs
new file mode 100644 (file)
index 0000000..5344c60
--- /dev/null
@@ -0,0 +1,37 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class PrivateConstructorTestClass
+  {
+    public string Name { get; set; }
+    public int Age { get; set; }
+
+    private PrivateConstructorTestClass()
+    {
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/PrivateConstructorWithPublicParametizedConstructorTestClass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/PrivateConstructorWithPublicParametizedConstructorTestClass.cs
new file mode 100644 (file)
index 0000000..7077d2b
--- /dev/null
@@ -0,0 +1,45 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class PrivateConstructorWithPublicParametizedConstructorTestClass
+  {
+    public string Name { get; set; }
+    public int Age { get; set; }
+
+    private PrivateConstructorWithPublicParametizedConstructorTestClass()
+    {
+      Age = 1;
+    }
+
+    public PrivateConstructorWithPublicParametizedConstructorTestClass(string dummy)
+    {
+      throw new Exception("Should never get here.");
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/PrivateMembersClass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/PrivateMembersClass.cs
new file mode 100644 (file)
index 0000000..01932ed
--- /dev/null
@@ -0,0 +1,55 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class PrivateMembersClass
+  {
+    public PrivateMembersClass(string privateString, string internalString)
+    {
+      _privateString = privateString;
+      _internalString = internalString;
+    }
+
+    public PrivateMembersClass()
+    {
+      i = default(int);
+    }
+
+    private string _privateString;
+    private readonly int i;
+    internal string _internalString;
+
+    public int UseValue()
+    {
+      return i;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Product.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Product.cs
new file mode 100644 (file)
index 0000000..f0ba4e1
--- /dev/null
@@ -0,0 +1,54 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class Product
+  {
+    public string Name;
+    public DateTime ExpiryDate = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+    public decimal Price;
+    public string[] Sizes;
+
+    public override bool Equals(object obj)
+    {
+      if (obj is Product)
+      {
+        Product p = (Product)obj;
+
+        return (p.Name == Name && p.ExpiryDate == ExpiryDate && p.Price == Price);
+      }
+
+      return base.Equals(obj);
+    }
+
+    public override int GetHashCode()
+    {
+      return (Name ?? string.Empty).GetHashCode();
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ProductCollection.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ProductCollection.cs
new file mode 100644 (file)
index 0000000..9e22492
--- /dev/null
@@ -0,0 +1,33 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System.Collections.Generic;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class ProductCollection : List<Product>
+  {
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ProductShort.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/ProductShort.cs
new file mode 100644 (file)
index 0000000..902f1da
--- /dev/null
@@ -0,0 +1,37 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class ProductShort
+  {
+    public string Name;
+    public DateTime ExpiryDate;
+    //public decimal Price;
+    public string[] Sizes;
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/PropertyCase.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/PropertyCase.cs
new file mode 100644 (file)
index 0000000..e98e070
--- /dev/null
@@ -0,0 +1,35 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class PropertyCase
+  {
+    public string firstName { get; set; }
+    public string FirstName { get; set; }
+    public string LastName { get; set; }
+    public string lastName { get; set; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/RequestOnly.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/RequestOnly.cs
new file mode 100644 (file)
index 0000000..0b47bce
--- /dev/null
@@ -0,0 +1,32 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class RequestOnly
+  {
+    public string Request { get; set; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/RequiredMembersClass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/RequiredMembersClass.cs
new file mode 100644 (file)
index 0000000..8731e69
--- /dev/null
@@ -0,0 +1,47 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class RequiredMembersClass
+  {
+    [JsonProperty(Required = Required.Always)]
+    public string FirstName { get; set; }
+
+    [JsonProperty]
+    public string MiddleName { get; set; }
+
+    [JsonProperty(Required = Required.AllowNull)]
+    public string LastName { get; set; }
+
+    [JsonProperty(Required = Required.Default)]
+    public DateTime BirthDate { get; set; }
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/RoleTransfer.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/RoleTransfer.cs
new file mode 100644 (file)
index 0000000..c6fe92f
--- /dev/null
@@ -0,0 +1,46 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public enum RoleTransferOperation
+  {
+    First,
+    Second
+  }
+
+  public enum RoleTransferDirection
+  {
+    First,
+    Second
+  }
+
+  public class RoleTransfer
+  {
+    public RoleTransferOperation Operation { get; set; }   //This is enum type
+    public string RoleName { get; set; }
+    public RoleTransferDirection Direction { get; set; }   //This is enum type
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/SearchResult.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/SearchResult.cs
new file mode 100644 (file)
index 0000000..d326ef3
--- /dev/null
@@ -0,0 +1,34 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class SearchResult
+  {
+    public string Title { get; set; }
+    public string Content { get; set; }
+    public string Url { get; set; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/SerializationEventTestDictionary.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/SerializationEventTestDictionary.cs
new file mode 100644 (file)
index 0000000..e613704
--- /dev/null
@@ -0,0 +1,82 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+#if !PocketPC
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class SerializationEventTestDictionary : Dictionary<decimal, string>
+  {
+    // This member is serialized and deserialized with no change.
+    public int Member1 { get; private set; }
+
+    // The value of this field is set and reset during and 
+    // after serialization.
+    public string Member2 { get; private set; }
+
+    // This field is not serialized. The OnDeserializedAttribute 
+    // is used to set the member value after serialization.
+    public string Member3 { get; private set; }
+
+    // This field is set to null, but populated after deserialization.
+    public string Member4 { get; private set; }
+
+    public SerializationEventTestDictionary()
+    {
+      Member1 = 11;
+      Member2 = "Hello World!";
+      Member3 = "This is a nonserialized value";
+      Member4 = null;
+    }
+
+    [OnSerializing]
+    internal void OnSerializingMethod(StreamingContext context)
+    {
+      Member2 = "This value went into the data file during serialization.";
+      Add(decimal.MaxValue, "Inserted on serializing");
+    }
+
+    [OnSerialized]
+    internal void OnSerializedMethod(StreamingContext context)
+    {
+      Member2 = "This value was reset after serialization.";
+    }
+
+    [OnDeserializing]
+    internal void OnDeserializingMethod(StreamingContext context)
+    {
+      Member3 = "This value was set during deserialization";
+    }
+
+    [OnDeserialized]
+    internal void OnDeserializedMethod(StreamingContext context)
+    {
+      Member4 = "This value was set after deserialization.";
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/SerializationEventTestList.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/SerializationEventTestList.cs
new file mode 100644 (file)
index 0000000..2eb84fb
--- /dev/null
@@ -0,0 +1,83 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+#if !PocketPC
+using System.Collections.ObjectModel;
+using System.Runtime.Serialization;
+using Newtonsoft.Json.Tests.Serialization;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class SerializationEventTestList : Collection<decimal>
+  {
+    // This member is serialized and deserialized with no change.
+    public int Member1 { get; private set; }
+
+    // The value of this field is set and reset during and 
+    // after serialization.
+    public string Member2 { get; private set; }
+
+    // This field is not serialized. The OnDeserializedAttribute 
+    // is used to set the member value after serialization.
+    public string Member3 { get; private set; }
+
+    // This field is set to null, but populated after deserialization.
+    public string Member4 { get; private set; }
+
+    public SerializationEventTestList()
+    {
+      Member1 = 11;
+      Member2 = "Hello World!";
+      Member3 = "This is a nonserialized value";
+      Member4 = null;
+    }
+
+    [OnSerializing]
+    internal void OnSerializingMethod(StreamingContext context)
+    {
+      Member2 = "This value went into the data file during serialization.";
+      Insert(0, -1);
+    }
+
+    [OnSerialized]
+    internal void OnSerializedMethod(StreamingContext context)
+    {
+      Member2 = "This value was reset after serialization.";
+    }
+
+    [OnDeserializing]
+    internal void OnDeserializingMethod(StreamingContext context)
+    {
+      Member3 = "This value was set during deserialization";
+    }
+
+    [OnDeserialized]
+    internal void OnDeserializedMethod(StreamingContext context)
+    {
+      Member4 = "This value was set after deserialization.";
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/SerializationEventTestObject.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/SerializationEventTestObject.cs
new file mode 100644 (file)
index 0000000..a6cd39c
--- /dev/null
@@ -0,0 +1,103 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+#if !PocketPC
+using System;
+using System.Linq;
+using System.Runtime.Serialization;
+using System.Text;
+using Newtonsoft.Json.Serialization;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class SerializationEventTestObject
+  {
+    // This member is serialized and deserialized with no change.
+    public int Member1 { get; set; }
+
+    // The value of this field is set and reset during and 
+    // after serialization.
+    public string Member2 { get; set; }
+
+    // This field is not serialized. The OnDeserializedAttribute 
+    // is used to set the member value after serialization.
+    [JsonIgnore]
+    public string Member3 { get; set; }
+
+    // This field is set to null, but populated after deserialization.
+    public string Member4 { get; set; }
+
+    // This field is set to null, but populated after error.
+    [JsonIgnore]
+    public string Member5 { get; set; }
+
+    // Getting or setting this field will throw an error.
+    public string Member6
+    {
+      get { throw new Exception("Member5 get error!"); }
+      set { throw new Exception("Member5 set error!"); }
+    }
+
+    public SerializationEventTestObject()
+    {
+      Member1 = 11;
+      Member2 = "Hello World!";
+      Member3 = "This is a nonserialized value";
+      Member4 = null;
+    }
+
+    [OnSerializing]
+    internal void OnSerializingMethod(StreamingContext context)
+    {
+      Member2 = "This value went into the data file during serialization.";
+    }
+
+    [OnSerialized]
+    internal void OnSerializedMethod(StreamingContext context)
+    {
+      Member2 = "This value was reset after serialization.";
+    }
+
+    [OnDeserializing]
+    internal void OnDeserializingMethod(StreamingContext context)
+    {
+      Member3 = "This value was set during deserialization";
+    }
+
+    [OnDeserialized]
+    internal void OnDeserializedMethod(StreamingContext context)
+    {
+      Member4 = "This value was set after deserialization.";
+    }
+
+    [OnError]
+    internal void OnErrorMethod(StreamingContext context, ErrorContext errorContext)
+    {
+      Member5 = "Error message for member " + errorContext.Member + " = " + errorContext.Error.Message;
+      errorContext.Handled = true;
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/SerializationEventTestObjectWithConstructor.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/SerializationEventTestObjectWithConstructor.cs
new file mode 100644 (file)
index 0000000..2aa159d
--- /dev/null
@@ -0,0 +1,85 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+#if !PocketPC
+using System;
+using System.Runtime.Serialization;
+using Newtonsoft.Json.Serialization;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class SerializationEventTestObjectWithConstructor
+  {
+    // This member is serialized and deserialized with no change.
+    public int Member1 { get; private set; }
+
+    // The value of this field is set and reset during and 
+    // after serialization.
+    public string Member2 { get; private set; }
+
+    // This field is not serialized. The OnDeserializedAttribute 
+    // is used to set the member value after serialization.
+    [JsonIgnore]
+    public string Member3 { get; private set; }
+
+    // This field is set to null, but populated after deserialization.
+    public string Member4 { get; private set; }
+
+    public SerializationEventTestObjectWithConstructor(int member1,
+                                                       string member2,
+                                                       string member4)
+    {
+      Member1 = member1;
+      Member2 = member2;
+      Member3 = "This is a nonserialized value";
+      Member4 = member4;
+    }
+
+    [OnSerializing]
+    internal void OnSerializingMethod(StreamingContext context)
+    {
+      Member2 = "This value went into the data file during serialization.";
+    }
+
+    [OnSerialized]
+    internal void OnSerializedMethod(StreamingContext context)
+    {
+      Member2 = "This value was reset after serialization.";
+    }
+
+    [OnDeserializing]
+    internal void OnDeserializingMethod(StreamingContext context)
+    {
+      Member3 = "This value was set during deserialization";
+    }
+
+    [OnDeserialized]
+    internal void OnDeserializedMethod(StreamingContext context)
+    {
+      Member4 = "This value was set after deserialization.";
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/SetOnlyPropertyClass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/SetOnlyPropertyClass.cs
new file mode 100644 (file)
index 0000000..da57e65
--- /dev/null
@@ -0,0 +1,37 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class SetOnlyPropertyClass
+  {
+    public string Field = "Field";
+
+    public string SetOnlyProperty
+    {
+      set { }
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/SetOnlyPropertyClass2.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/SetOnlyPropertyClass2.cs
new file mode 100644 (file)
index 0000000..6b6d0be
--- /dev/null
@@ -0,0 +1,40 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class SetOnlyPropertyClass2
+  {
+    private object _value;
+    public object SetOnlyProperty
+    {
+      set { _value = value; }
+    }
+    public object GetValue()
+    {
+      return _value;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Shortie.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Shortie.cs
new file mode 100644 (file)
index 0000000..e08db45
--- /dev/null
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Xml.Serialization;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class Shortie
+  {
+    public string Original { get; set; }
+    public string Shortened { get; set; }
+    public string Short { get; set; }
+    public ShortieException Error { get; set; }
+  }
+
+  public class ShortieException
+  {
+    public int Code { get; set; }
+    public string ErrorMessage { get; set; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Store.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/Store.cs
new file mode 100644 (file)
index 0000000..7a6f0aa
--- /dev/null
@@ -0,0 +1,64 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class Store
+  {
+    public StoreColor Color = StoreColor.Yellow;
+    public DateTime Establised = new DateTime(2010, 1, 22, 1, 1, 1, DateTimeKind.Utc);
+    public double Width = 1.1;
+    public int Employees = 999;
+    public int[] RoomsPerFloor = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+    public bool Open = false;
+    public char Symbol = '@';
+    [JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace)]
+    public List<string> Mottos = new List<string>();
+    public decimal Cost = 100980.1M;
+    public string Escape = "\r\n\t\f\b?{\\r\\n\"\'";
+    [JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace)]
+    public List<Product> product = new List<Product>();
+
+    public Store()
+    {
+      Mottos.Add("Hello World");
+      Mottos.Add("öäüÖÄÜ\\'{new Date(12345);}[222]_µ@²³~");
+      Mottos.Add(null);
+      Mottos.Add(" ");
+
+      Product rocket = new Product();
+      rocket.Name = "Rocket";
+      rocket.ExpiryDate = new DateTime(2000, 2, 2, 23, 1, 30, DateTimeKind.Utc);
+      Product alien = new Product();
+      alien.Name = "Alien";
+
+      product.Add(rocket);
+      product.Add(alien);
+    }
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/StoreColor.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/StoreColor.cs
new file mode 100644 (file)
index 0000000..bc384b1
--- /dev/null
@@ -0,0 +1,39 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  [Flags]
+  public enum StoreColor
+  {
+    Black = 1,
+    Red = 2,
+    Yellow = 4,
+    White = 8,
+    DarkGoldenrod = 16
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/StructTest.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/StructTest.cs
new file mode 100644 (file)
index 0000000..45d492f
--- /dev/null
@@ -0,0 +1,35 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public struct StructTest
+  {
+    public string StringProperty { get; set; }
+    public string StringField;
+    public int IntProperty { get; set; }
+    public int IntField;
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/SubKlass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/SubKlass.cs
new file mode 100644 (file)
index 0000000..9294a8e
--- /dev/null
@@ -0,0 +1,33 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class SubKlass : SuperKlass
+  {
+    public string SubProp { get; set; }
+    public SubKlass(string subprop) { SubProp = subprop; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/SuperKlass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/SuperKlass.cs
new file mode 100644 (file)
index 0000000..2c581ac
--- /dev/null
@@ -0,0 +1,33 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class SuperKlass
+  {
+    public string SuperProp { get; set; }
+    public SuperKlass() { SuperProp = "default superprop"; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/TypeClass.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/TypeClass.cs
new file mode 100644 (file)
index 0000000..21333a9
--- /dev/null
@@ -0,0 +1,34 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class TypeClass
+  {
+    public Type TypeProperty { get; set; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/TypedSubHashtable.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/TypedSubHashtable.cs
new file mode 100644 (file)
index 0000000..636d417
--- /dev/null
@@ -0,0 +1,37 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System.Collections;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+#if !SILVERLIGHT
+  public class TypedSubHashtable
+  {
+    public string Name;
+    public Hashtable Hash;
+  }
+#endif
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/UserNullable.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/UserNullable.cs
new file mode 100644 (file)
index 0000000..8fb8cf6
--- /dev/null
@@ -0,0 +1,40 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class UserNullable
+  {
+    public Guid Id;
+    public string FName;
+    public string LName;
+    public int RoleId;
+    public int? NullableRoleId;
+    public int? NullRoleId;
+    public bool? Active;
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/VersionKeyedCollection.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/VersionKeyedCollection.cs
new file mode 100644 (file)
index 0000000..17d62af
--- /dev/null
@@ -0,0 +1,73 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Runtime.Serialization;
+using Newtonsoft.Json.Serialization;
+using Newtonsoft.Json.Tests.TestObjects;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class VersionKeyedCollection : KeyedCollection<string, Person>, IEnumerable<Person>
+  {
+    public List<string> Messages { get; set; }
+
+    public VersionKeyedCollection()
+    {
+      Messages = new List<string>();
+    }
+
+    protected override string GetKeyForItem(Person item)
+    {
+      return item.Name;
+    }
+
+    [OnError]
+    internal void OnErrorMethod(StreamingContext context, ErrorContext errorContext)
+    {
+      Messages.Add("Error message for member " + errorContext.Member + " = " + errorContext.Error.Message);
+      errorContext.Handled = true;
+    }
+
+    IEnumerator<Person> IEnumerable<Person>.GetEnumerator()
+    {
+      for (int i = 0; i < Count; i++)
+      {
+        if (i % 2 == 0)
+          throw new Exception("Index even: " + i);
+
+        yield return this[i];
+      }
+    }
+
+    IEnumerator IEnumerable.GetEnumerator()
+    {
+      return ((IEnumerable<Person>) this).GetEnumerator();
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/WagePerson.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/TestObjects/WagePerson.cs
new file mode 100644 (file)
index 0000000..b99f00d
--- /dev/null
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Tests.TestObjects
+{
+  public class WagePerson : Person
+  {
+    [JsonProperty]
+    public decimal HourlyWage { get; set; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Utilities/DynamicReflectionDelegateFactoryTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Utilities/DynamicReflectionDelegateFactoryTests.cs
new file mode 100644 (file)
index 0000000..bdb6d1c
--- /dev/null
@@ -0,0 +1,112 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+#if !PocketPC && !SILVERLIGHT
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using NUnit.Framework;
+using Newtonsoft.Json.Utilities;
+using Newtonsoft.Json.Tests.TestObjects;
+using Newtonsoft.Json.Tests.Serialization;
+
+namespace Newtonsoft.Json.Tests.Utilities
+{
+  public class DynamicReflectionDelegateFactoryTests : TestFixtureBase
+  {
+    [Test]
+    [ExpectedException(typeof(InvalidCastException), ExpectedMessage = "Unable to cast object of type 'Newtonsoft.Json.Tests.TestObjects.Person' to type 'Newtonsoft.Json.Tests.TestObjects.Movie'.")]
+    public void CreateGetWithBadObjectTarget()
+    {
+      Person p = new Person();
+      p.Name = "Hi";
+
+      Func<object, object> setter = DynamicReflectionDelegateFactory.Instance.CreateGet<object>(typeof(Movie).GetProperty("Name"));
+
+      setter(p);
+    }
+
+    [Test]
+    [ExpectedException(typeof(InvalidCastException), ExpectedMessage = "Unable to cast object of type 'Newtonsoft.Json.Tests.TestObjects.Person' to type 'Newtonsoft.Json.Tests.TestObjects.Movie'.")]
+    public void CreateSetWithBadObjectTarget()
+    {
+      Person p = new Person();
+      Movie m = new Movie();
+
+      Action<object, object> setter = DynamicReflectionDelegateFactory.Instance.CreateSet<object>(typeof(Movie).GetProperty("Name"));
+
+      setter(m, "Hi");
+
+      Assert.AreEqual(m.Name, "Hi");
+
+      setter(p, "Hi");
+    }
+
+    [Test]
+    [ExpectedException(typeof(InvalidCastException), ExpectedMessage = "Specified cast is not valid.")]
+    public void CreateSetWithBadTarget()
+    {
+      object structTest = new StructTest();
+
+      Action<object, object> setter = DynamicReflectionDelegateFactory.Instance.CreateSet<object>(typeof(StructTest).GetProperty("StringProperty"));
+
+      setter(structTest, "Hi");
+
+      Assert.AreEqual("Hi", ((StructTest)structTest).StringProperty);
+
+      setter(new TimeSpan(), "Hi");
+    }
+
+    [Test]
+    [ExpectedException(typeof(InvalidCastException), ExpectedMessage = "Unable to cast object of type 'System.Version' to type 'System.String'.")]
+    public void CreateSetWithBadObjectValue()
+    {
+      Movie m = new Movie();
+
+      Action<object, object> setter = DynamicReflectionDelegateFactory.Instance.CreateSet<object>(typeof(Movie).GetProperty("Name"));
+
+      setter(m, new Version());
+    }
+
+    [Test]
+    public void CreateStaticMethodCall()
+    {
+      MethodInfo castMethodInfo = typeof(JsonSerializerTest.DictionaryKey).GetMethod("op_Implicit", new[] { typeof(string) });
+
+      Assert.IsNotNull(castMethodInfo);
+
+      MethodCall<object, object> call = DynamicReflectionDelegateFactory.Instance.CreateMethodCall<object>(castMethodInfo);
+
+      object result = call(null, "First!");
+      Assert.IsNotNull(result);
+
+      JsonSerializerTest.DictionaryKey key = (JsonSerializerTest.DictionaryKey) result;
+      Assert.AreEqual("First!", key.Value);
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Utilities/ReflectionUtilsTests.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/Utilities/ReflectionUtilsTests.cs
new file mode 100644 (file)
index 0000000..9124e15
--- /dev/null
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.Serialization.Formatters;
+using System.Text;
+using NUnit.Framework;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Tests.Utilities
+{
+  public class ReflectionUtilsTests : TestFixtureBase
+  {
+    [Test]
+    public void GetTypeNameSimpleForGenericTypes()
+    {
+      string typeName;
+
+      typeName = ReflectionUtils.GetTypeName(typeof(IList<Type>), FormatterAssemblyStyle.Simple);
+      Assert.AreEqual("System.Collections.Generic.IList`1[[System.Type, mscorlib]], mscorlib", typeName);
+
+      typeName = ReflectionUtils.GetTypeName(typeof(IDictionary<IList<Type>, IList<Type>>), FormatterAssemblyStyle.Simple);
+      Assert.AreEqual("System.Collections.Generic.IDictionary`2[[System.Collections.Generic.IList`1[[System.Type, mscorlib]], mscorlib],[System.Collections.Generic.IList`1[[System.Type, mscorlib]], mscorlib]], mscorlib", typeName);
+
+      typeName = ReflectionUtils.GetTypeName(typeof(IList<>), FormatterAssemblyStyle.Simple);
+      Assert.AreEqual("System.Collections.Generic.IList`1, mscorlib", typeName);
+
+      typeName = ReflectionUtils.GetTypeName(typeof(IDictionary<,>), FormatterAssemblyStyle.Simple);
+      Assert.AreEqual("System.Collections.Generic.IDictionary`2, mscorlib", typeName);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/bunny_pancake.jpg b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/bunny_pancake.jpg
new file mode 100644 (file)
index 0000000..59e882c
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.Tests/bunny_pancake.jpg differ
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.WindowsPhone.sln b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.WindowsPhone.sln
new file mode 100644 (file)
index 0000000..e4cdfae
--- /dev/null
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Lib", "Lib", "{F69285DD-24FB-4A60-AE8B-4C2744285D0F}"
+       ProjectSection(SolutionItems) = preProject
+               Lib\NUnit\Silverlight\nunit.framework.dll = Lib\NUnit\Silverlight\nunit.framework.dll
+       EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Newtonsoft.Json.WindowsPhone", "Newtonsoft.Json\Newtonsoft.Json.WindowsPhone.csproj", "{7A7F70AB-5C07-47ED-BDD2-ECC14DBACA5E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Newtonsoft.Json.Tests.WindowsPhone", "Newtonsoft.Json.Tests\Newtonsoft.Json.Tests.WindowsPhone.csproj", "{5ED71C8C-D0A6-487C-9A8C-BB855ECEAF75}"
+EndProject
+Global
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Debug|Any CPU = Debug|Any CPU
+               Release|Any CPU = Release|Any CPU
+       EndGlobalSection
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {7A7F70AB-5C07-47ED-BDD2-ECC14DBACA5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {7A7F70AB-5C07-47ED-BDD2-ECC14DBACA5E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {7A7F70AB-5C07-47ED-BDD2-ECC14DBACA5E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {7A7F70AB-5C07-47ED-BDD2-ECC14DBACA5E}.Release|Any CPU.Build.0 = Release|Any CPU
+               {5ED71C8C-D0A6-487C-9A8C-BB855ECEAF75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {5ED71C8C-D0A6-487C-9A8C-BB855ECEAF75}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {5ED71C8C-D0A6-487C-9A8C-BB855ECEAF75}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {5ED71C8C-D0A6-487C-9A8C-BB855ECEAF75}.Release|Any CPU.Build.0 = Release|Any CPU
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+EndGlobal
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.sln b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json.sln
new file mode 100644 (file)
index 0000000..f94c4c3
--- /dev/null
@@ -0,0 +1,32 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Lib", "Lib", "{620042D9-2753-48F5-BEDE-3905248781D2}"
+       ProjectSection(SolutionItems) = preProject
+               Lib\NUnit\DotNet\nunit.framework.dll = Lib\NUnit\DotNet\nunit.framework.dll
+               Lib\NUnit\DotNet\nunit.framework.xml = Lib\NUnit\DotNet\nunit.framework.xml
+       EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Newtonsoft.Json", "Newtonsoft.Json\Newtonsoft.Json.csproj", "{A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Newtonsoft.Json.Tests", "Newtonsoft.Json.Tests\Newtonsoft.Json.Tests.csproj", "{3E6E2335-B079-4B5B-A65A-9D586914BCBB}"
+EndProject
+Global
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Debug|Any CPU = Debug|Any CPU
+               Release|Any CPU = Release|Any CPU
+       EndGlobalSection
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Release|Any CPU.Build.0 = Release|Any CPU
+               {3E6E2335-B079-4B5B-A65A-9D586914BCBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {3E6E2335-B079-4B5B-A65A-9D586914BCBB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {3E6E2335-B079-4B5B-A65A-9D586914BCBB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {3E6E2335-B079-4B5B-A65A-9D586914BCBB}.Release|Any CPU.Build.0 = Release|Any CPU
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+EndGlobal
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Bson/BsonBinaryType.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Bson/BsonBinaryType.cs
new file mode 100644 (file)
index 0000000..0826446
--- /dev/null
@@ -0,0 +1,40 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json.Bson
+{
+  internal enum BsonBinaryType : byte
+  {
+    Binary = 0x00,
+    Function = 0x01,
+    [Obsolete("This type has been deprecated in the BSON specification. Use Binary instead.")]
+    Data = 0x02,
+    Uuid = 0x03,
+    Md5 = 0x05,
+    UserDefined = 0x80
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Bson/BsonBinaryWriter.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Bson/BsonBinaryWriter.cs
new file mode 100644 (file)
index 0000000..f74e0e5
--- /dev/null
@@ -0,0 +1,302 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Bson
+{
+  internal class BsonBinaryWriter
+  {
+    private static readonly Encoding Encoding = Encoding.UTF8;
+
+    private readonly BinaryWriter _writer;
+
+    private byte[] _largeByteBuffer;
+    private int _maxChars;
+
+    public DateTimeKind DateTimeKindHandling { get; set; }
+
+    public BsonBinaryWriter(Stream stream)
+    {
+      DateTimeKindHandling = DateTimeKind.Utc;
+      _writer = new BinaryWriter(stream);
+    }
+
+    public void Flush()
+    {
+      _writer.Flush();
+    }
+
+    public void Close()
+    {
+      _writer.Close();
+    }
+
+    public void WriteToken(BsonToken t)
+    {
+      CalculateSize(t);
+      WriteTokenInternal(t);
+    }
+
+    private void WriteTokenInternal(BsonToken t)
+    {
+      switch (t.Type)
+      {
+        case BsonType.Object:
+          {
+            BsonObject value = (BsonObject) t;
+            _writer.Write(value.CalculatedSize);
+            foreach (BsonProperty property in value)
+            {
+              _writer.Write((sbyte)property.Value.Type);
+              WriteString((string)property.Name.Value, property.Name.ByteCount, null);
+              WriteTokenInternal(property.Value);
+            }
+            _writer.Write((byte)0);
+          }
+          break;
+        case BsonType.Array:
+          {
+            BsonArray value = (BsonArray) t;
+            _writer.Write(value.CalculatedSize);
+            int index = 0;
+            foreach (BsonToken c in value)
+            {
+              _writer.Write((sbyte)c.Type);
+              WriteString(index.ToString(CultureInfo.InvariantCulture), MathUtils.IntLength(index), null);
+              WriteTokenInternal(c);
+              index++;
+            }
+            _writer.Write((byte)0);
+          }
+          break;
+        case BsonType.Integer:
+          {
+            BsonValue value = (BsonValue) t;
+            _writer.Write(Convert.ToInt32(value.Value, CultureInfo.InvariantCulture));
+          }
+          break;
+        case BsonType.Long:
+          {
+            BsonValue value = (BsonValue)t;
+            _writer.Write(Convert.ToInt64(value.Value, CultureInfo.InvariantCulture));
+          }
+          break;
+        case BsonType.Number:
+          {
+            BsonValue value = (BsonValue)t;
+            _writer.Write(Convert.ToDouble(value.Value, CultureInfo.InvariantCulture));
+          }
+          break;
+        case BsonType.String:
+          {
+            BsonString value = (BsonString)t;
+            WriteString((string)value.Value, value.ByteCount, value.CalculatedSize - 4);
+          }
+          break;
+        case BsonType.Boolean:
+          {
+            BsonValue value = (BsonValue)t;
+            _writer.Write((bool)value.Value);
+          }
+          break;
+        case BsonType.Null:
+        case BsonType.Undefined:
+          break;
+        case BsonType.Date:
+          {
+            BsonValue value = (BsonValue)t;
+
+            long ticks = 0;
+
+            if (value.Value is DateTime)
+            {
+              DateTime dateTime = (DateTime) value.Value;
+              if (DateTimeKindHandling == DateTimeKind.Utc)
+                dateTime = dateTime.ToUniversalTime();
+              else if (DateTimeKindHandling == DateTimeKind.Local)
+                dateTime = dateTime.ToLocalTime();
+
+              ticks = JsonConvert.ConvertDateTimeToJavaScriptTicks(dateTime, false);
+            }
+#if !PocketPC && !NET20
+            else
+            {
+              DateTimeOffset dateTimeOffset = (DateTimeOffset) value.Value;
+              ticks = JsonConvert.ConvertDateTimeToJavaScriptTicks(dateTimeOffset.UtcDateTime, dateTimeOffset.Offset);
+            }
+#endif
+
+            _writer.Write(ticks);
+          }
+          break;
+        case BsonType.Binary:
+          {
+            BsonValue value = (BsonValue)t;
+
+            byte[] data = (byte[])value.Value;
+            _writer.Write(data.Length);
+            _writer.Write((byte)BsonBinaryType.Binary);
+            _writer.Write(data);
+          }
+          break;
+        case BsonType.Oid:
+          {
+            BsonValue value = (BsonValue)t;
+
+            byte[] data = (byte[])value.Value;
+            _writer.Write(data);
+          }
+          break;
+        case BsonType.Regex:
+          {
+            BsonRegex value = (BsonRegex) t;
+
+            WriteString((string)value.Pattern.Value, value.Pattern.ByteCount, null);
+            WriteString((string)value.Options.Value, value.Options.ByteCount, null);
+          }
+          break;
+        default:
+          throw new ArgumentOutOfRangeException("t", "Unexpected token when writing BSON: {0}".FormatWith(CultureInfo.InvariantCulture, t.Type));
+      }
+    }
+
+    private void WriteString(string s, int byteCount, int? calculatedlengthPrefix)
+    {
+      if (calculatedlengthPrefix != null)
+        _writer.Write(calculatedlengthPrefix.Value);
+
+      if (s != null)
+      {
+        if (_largeByteBuffer == null)
+        {
+          _largeByteBuffer = new byte[256];
+          _maxChars = 256/Encoding.GetMaxByteCount(1);
+        }
+        if (byteCount <= 256)
+        {
+          Encoding.GetBytes(s, 0, s.Length, _largeByteBuffer, 0);
+          _writer.Write(_largeByteBuffer, 0, byteCount);
+        }
+        else
+        {
+          int charCount;
+          int totalCharsWritten = 0;
+          for (int i = s.Length; i > 0; i -= charCount)
+          {
+            charCount = (i > _maxChars) ? _maxChars : i;
+            int count = Encoding.GetBytes(s, totalCharsWritten, charCount, _largeByteBuffer, 0);
+            _writer.Write(_largeByteBuffer, 0, count);
+            totalCharsWritten += charCount;
+          }
+        }
+      }
+
+      _writer.Write((byte)0);
+    }
+
+    private int CalculateSize(int stringByteCount)
+    {
+      return stringByteCount + 1;
+    }
+
+    private int CalculateSizeWithLength(int stringByteCount, bool includeSize)
+    {
+      int baseSize = (includeSize)
+        ? 5 // size bytes + terminator
+        : 1; // terminator
+
+      return baseSize + stringByteCount;
+    }
+
+    private int CalculateSize(BsonToken t)
+    {
+      switch (t.Type)
+      {
+        case BsonType.Object:
+          {
+            BsonObject value = (BsonObject) t;
+
+            int bases = 4;
+            foreach (BsonProperty p in value)
+            {
+              int size = 1;
+              size += CalculateSize(p.Name);
+              size += CalculateSize(p.Value);
+
+              bases += size;
+            }
+            bases += 1;
+            value.CalculatedSize = bases;
+            return bases;
+          }
+        case BsonType.Array:
+          {
+            BsonArray value = (BsonArray)t;
+
+            int size = 4;
+            int index = 0;
+            foreach (BsonToken c in value)
+            {
+              size += 1;
+              size += CalculateSize(MathUtils.IntLength(index));
+              size += CalculateSize(c);
+              index++;
+            }
+            size += 1;
+            value.CalculatedSize = size;
+
+            return value.CalculatedSize;
+          }
+        case BsonType.Integer:
+          return 4;
+        case BsonType.Long:
+          return 8;
+        case BsonType.Number:
+          return 8;
+        case BsonType.String:
+          {
+            BsonString value = (BsonString)t;
+            string s = (string) value.Value;
+            value.ByteCount = (s != null) ? Encoding.GetByteCount(s) : 0;
+            value.CalculatedSize = CalculateSizeWithLength(value.ByteCount, value.IncludeLength);
+
+            return value.CalculatedSize;
+          }
+        case BsonType.Boolean:
+          return 1;
+        case BsonType.Null:
+        case BsonType.Undefined:
+          return 0;
+        case BsonType.Date:
+          return 8;
+        case BsonType.Binary:
+          {
+            BsonValue value = (BsonValue) t;
+
+            byte[] data = (byte[])value.Value;
+            value.CalculatedSize = 4 + 1 + data.Length;
+
+            return value.CalculatedSize;
+          }
+        case BsonType.Oid:
+          return 12;
+        case BsonType.Regex:
+          {
+            BsonRegex value = (BsonRegex) t;
+            int size = 0;
+            size += CalculateSize(value.Pattern);
+            size += CalculateSize(value.Options);
+            value.CalculatedSize = size;
+
+            return value.CalculatedSize;
+          }
+        default:
+          throw new ArgumentOutOfRangeException("t", "Unexpected token when writing BSON: {0}".FormatWith(CultureInfo.InvariantCulture, t.Type));
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Bson/BsonObjectId.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Bson/BsonObjectId.cs
new file mode 100644 (file)
index 0000000..e8333c5
--- /dev/null
@@ -0,0 +1,58 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Bson
+{
+  /// <summary>
+  /// Represents a BSON Oid (object id).
+  /// </summary>
+  public class BsonObjectId
+  {
+    /// <summary>
+    /// Gets or sets the value of the Oid.
+    /// </summary>
+    /// <value>The value of the Oid.</value>
+    public byte[] Value { get; private set; }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="BsonObjectId"/> class.
+    /// </summary>
+    /// <param name="value">The Oid value.</param>
+    public BsonObjectId(byte[] value)
+    {
+      ValidationUtils.ArgumentNotNull(value, "value");
+      if (value.Length != 12)
+        throw new Exception("An ObjectId must be 12 bytes");
+
+      Value = value;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Bson/BsonReader.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Bson/BsonReader.cs
new file mode 100644 (file)
index 0000000..cf5eb06
--- /dev/null
@@ -0,0 +1,795 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Text;
+using System.IO;
+using Newtonsoft.Json.Utilities;
+using Newtonsoft.Json.Linq;
+
+namespace Newtonsoft.Json.Bson
+{
+  /// <summary>
+  /// Represents a reader that provides fast, non-cached, forward-only access to serialized Json data.
+  /// </summary>
+  public class BsonReader : JsonReader
+  {
+    private const int MaxCharBytesSize = 128;
+    private static readonly byte[] _seqRange1 = new byte[] { 0, 127 }; // range of 1-byte sequence
+    private static readonly byte[] _seqRange2 = new byte[] { 194, 223 }; // range of 2-byte sequence
+    private static readonly byte[] _seqRange3 = new byte[] { 224, 239 }; // range of 3-byte sequence
+    private static readonly byte[] _seqRange4 = new byte[] { 240, 244 }; // range of 4-byte sequence
+
+    private readonly BinaryReader _reader;
+    private readonly List<ContainerContext> _stack;
+
+    private byte[] _byteBuffer;
+    private char[] _charBuffer;
+
+    private BsonType _currentElementType;
+    private BsonReaderState _bsonReaderState;
+    private ContainerContext _currentContext;
+
+    private bool _readRootValueAsArray;
+    private bool _jsonNet35BinaryCompatibility;
+    private DateTimeKind _dateTimeKindHandling;
+
+    private enum BsonReaderState
+    {
+      Normal,
+      ReferenceStart,
+      ReferenceRef,
+      ReferenceId,
+      CodeWScopeStart,
+      CodeWScopeCode,
+      CodeWScopeScope,
+      CodeWScopeScopeObject,
+      CodeWScopeScopeEnd
+    }
+
+    private class ContainerContext
+    {
+      public readonly BsonType Type;
+      public int Length;
+      public int Position;
+
+      public ContainerContext(BsonType type)
+      {
+        Type = type;
+      }
+    }
+
+    /// <summary>
+    /// Gets or sets a value indicating whether binary data reading should compatible with incorrect Json.NET 3.5 written binary.
+    /// </summary>
+    /// <value>
+    ///        <c>true</c> if binary data reading will be compatible with incorrect Json.NET 3.5 written binary; otherwise, <c>false</c>.
+    /// </value>
+    public bool JsonNet35BinaryCompatibility
+    {
+      get { return _jsonNet35BinaryCompatibility; }
+      set { _jsonNet35BinaryCompatibility = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets a value indicating whether the root object will be read as a JSON array.
+    /// </summary>
+    /// <value>
+    ///        <c>true</c> if the root object will be read as a JSON array; otherwise, <c>false</c>.
+    /// </value>
+    public bool ReadRootValueAsArray
+    {
+      get { return _readRootValueAsArray; }
+      set { _readRootValueAsArray = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets the <see cref="DateTimeKind" /> used when reading <see cref="DateTime"/> values from BSON.
+    /// </summary>
+    /// <value>The <see cref="DateTimeKind" /> used when reading <see cref="DateTime"/> values from BSON.</value>
+    public DateTimeKind DateTimeKindHandling
+    {
+      get { return _dateTimeKindHandling; }
+      set { _dateTimeKindHandling = value; }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="BsonReader"/> class.
+    /// </summary>
+    /// <param name="stream">The stream.</param>
+    public BsonReader(Stream stream)
+      : this(stream, false, DateTimeKind.Local)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="BsonReader"/> class.
+    /// </summary>
+    /// <param name="stream">The stream.</param>
+    /// <param name="readRootValueAsArray">if set to <c>true</c> the root object will be read as a JSON array.</param>
+    /// <param name="dateTimeKindHandling">The <see cref="DateTimeKind" /> used when reading <see cref="DateTime"/> values from BSON.</param>
+    public BsonReader(Stream stream, bool readRootValueAsArray, DateTimeKind dateTimeKindHandling)
+    {
+      ValidationUtils.ArgumentNotNull(stream, "stream");
+      _reader = new BinaryReader(stream);
+      _stack = new List<ContainerContext>();
+      _readRootValueAsArray = readRootValueAsArray;
+      _dateTimeKindHandling = dateTimeKindHandling;
+    }
+
+    private string ReadElement()
+    {
+      _currentElementType = ReadType();
+      string elementName = ReadString();
+      return elementName;
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="T:Byte[]"/>.
+    /// </summary>
+    /// <returns>
+    /// A <see cref="T:Byte[]"/> or a null reference if the next JSON token is null.
+    /// </returns>
+    public override byte[] ReadAsBytes()
+    {
+      Read();
+
+      if (TokenType == JsonToken.Null)
+        return null;
+      if (TokenType == JsonToken.Bytes)
+        return (byte[])Value;
+
+      throw new JsonReaderException("Error reading bytes. Expected bytes but got {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="Nullable{Decimal}"/>.
+    /// </summary>
+    /// <returns>A <see cref="Nullable{Decimal}"/>.</returns>
+    public override decimal? ReadAsDecimal()
+    {
+      Read();
+
+      if (TokenType == JsonToken.Null)
+        return null;
+      if (TokenType == JsonToken.Integer || TokenType == JsonToken.Float)
+      {
+        SetToken(JsonToken.Float, Convert.ToDecimal(Value, CultureInfo.InvariantCulture));
+        return (decimal)Value;
+      }
+
+      throw new JsonReaderException("Error reading decimal. Expected a number but got {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
+    }
+
+#if !NET20
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="Nullable{DateTimeOffset}"/>.
+    /// </summary>
+    /// <returns>
+    /// A <see cref="Nullable{DateTimeOffset}"/>.
+    /// </returns>
+    public override DateTimeOffset? ReadAsDateTimeOffset()
+    {
+      Read();
+
+      if (TokenType == JsonToken.Null)
+        return null;
+      if (TokenType == JsonToken.Date)
+      {
+        SetToken(JsonToken.Date, new DateTimeOffset((DateTime)Value));
+        return (DateTimeOffset)Value;
+      }
+      
+      throw new JsonReaderException("Error reading date. Expected bytes but got {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
+    }
+#endif
+
+    /// <summary>
+    /// Reads the next JSON token from the stream.
+    /// </summary>
+    /// <returns>
+    /// true if the next token was read successfully; false if there are no more tokens to read.
+    /// </returns>
+    public override bool Read()
+    {
+      try
+      {
+        switch (_bsonReaderState)
+        {
+          case BsonReaderState.Normal:
+            return ReadNormal();
+          case BsonReaderState.ReferenceStart:
+          case BsonReaderState.ReferenceRef:
+          case BsonReaderState.ReferenceId:
+            return ReadReference();
+          case BsonReaderState.CodeWScopeStart:
+          case BsonReaderState.CodeWScopeCode:
+          case BsonReaderState.CodeWScopeScope:
+          case BsonReaderState.CodeWScopeScopeObject:
+          case BsonReaderState.CodeWScopeScopeEnd:
+            return ReadCodeWScope();
+          default:
+            throw new JsonReaderException("Unexpected state: {0}".FormatWith(CultureInfo.InvariantCulture, _bsonReaderState));
+        }
+      }
+      catch (EndOfStreamException)
+      {
+        return false;
+      }
+    }
+
+    /// <summary>
+    /// Changes the <see cref="JsonReader.State"/> to Closed.
+    /// </summary>
+    public override void Close()
+    {
+      base.Close();
+
+      if (CloseInput && _reader != null)
+        _reader.Close();
+    }
+
+    private bool ReadCodeWScope()
+    {
+      switch (_bsonReaderState)
+      {
+        case BsonReaderState.CodeWScopeStart:
+          SetToken(JsonToken.PropertyName, "$code");
+          _bsonReaderState = BsonReaderState.CodeWScopeCode;
+          return true;
+        case BsonReaderState.CodeWScopeCode:
+          // total CodeWScope size - not used
+          ReadInt32();
+
+          SetToken(JsonToken.String, ReadLengthString());
+          _bsonReaderState = BsonReaderState.CodeWScopeScope;
+          return true;
+        case BsonReaderState.CodeWScopeScope:
+          if (CurrentState == State.PostValue)
+          {
+            SetToken(JsonToken.PropertyName, "$scope");
+            return true;
+          }
+          else
+          {
+            SetToken(JsonToken.StartObject);
+            _bsonReaderState = BsonReaderState.CodeWScopeScopeObject;
+
+            ContainerContext newContext = new ContainerContext(BsonType.Object);
+            PushContext(newContext);
+            newContext.Length = ReadInt32();
+
+            return true;
+          }
+        case BsonReaderState.CodeWScopeScopeObject:
+          bool result = ReadNormal();
+          if (result && TokenType == JsonToken.EndObject)
+            _bsonReaderState = BsonReaderState.CodeWScopeScopeEnd;
+
+          return result;
+        case BsonReaderState.CodeWScopeScopeEnd:
+          SetToken(JsonToken.EndObject);
+          _bsonReaderState = BsonReaderState.Normal;
+          return true;
+        default:
+          throw new ArgumentOutOfRangeException();
+      }
+    }
+
+    private bool ReadReference()
+    {
+      switch (CurrentState)
+      {
+        case State.ObjectStart:
+          {
+            SetToken(JsonToken.PropertyName, "$ref");
+            _bsonReaderState = BsonReaderState.ReferenceRef;
+            return true;
+          }
+        case State.Property:
+          {
+            if (_bsonReaderState == BsonReaderState.ReferenceRef)
+            {
+              SetToken(JsonToken.String, ReadLengthString());
+              return true;
+            }
+            else if (_bsonReaderState == BsonReaderState.ReferenceId)
+            {
+              SetToken(JsonToken.Bytes, ReadBytes(12));
+              return true;
+            }
+            else
+            {
+              throw new JsonReaderException("Unexpected state when reading BSON reference: " + _bsonReaderState);
+            }
+          }
+        case State.PostValue:
+          {
+            if (_bsonReaderState == BsonReaderState.ReferenceRef)
+            {
+              SetToken(JsonToken.PropertyName, "$id");
+              _bsonReaderState = BsonReaderState.ReferenceId;
+              return true;
+            }
+            else if (_bsonReaderState == BsonReaderState.ReferenceId)
+            {
+              SetToken(JsonToken.EndObject);
+              _bsonReaderState = BsonReaderState.Normal;
+              return true;
+            }
+            else
+            {
+              throw new JsonReaderException("Unexpected state when reading BSON reference: " + _bsonReaderState);
+            }
+          }
+        default:
+          throw new JsonReaderException("Unexpected state when reading BSON reference: " + CurrentState);
+      }
+    }
+
+    private bool ReadNormal()
+    {
+      switch (CurrentState)
+      {
+        case State.Start:
+          {
+            JsonToken token = (!_readRootValueAsArray) ? JsonToken.StartObject : JsonToken.StartArray;
+            BsonType type = (!_readRootValueAsArray) ? BsonType.Object : BsonType.Array;
+
+            SetToken(token);
+            ContainerContext newContext = new ContainerContext(type);
+            PushContext(newContext);
+            newContext.Length = ReadInt32();
+            return true;
+          }
+        case State.Complete:
+        case State.Closed:
+          return false;
+        case State.Property:
+          {
+            ReadType(_currentElementType);
+            return true;
+          }
+        case State.ObjectStart:
+        case State.ArrayStart:
+        case State.PostValue:
+          ContainerContext context = _currentContext;
+          if (context == null)
+            return false;
+
+          int lengthMinusEnd = context.Length - 1;
+
+          if (context.Position < lengthMinusEnd)
+          {
+            if (context.Type == BsonType.Array)
+            {
+              ReadElement();
+              ReadType(_currentElementType);
+              return true;
+            }
+            else
+            {
+              SetToken(JsonToken.PropertyName, ReadElement());
+              return true;
+            }
+          }
+          else if (context.Position == lengthMinusEnd)
+          {
+            if (ReadByte() != 0)
+              throw new JsonReaderException("Unexpected end of object byte value.");
+
+            PopContext();
+            if (_currentContext != null)
+              MovePosition(context.Length);
+
+            JsonToken endToken = (context.Type == BsonType.Object) ? JsonToken.EndObject : JsonToken.EndArray;
+            SetToken(endToken);
+            return true;
+          }
+          else
+          {
+            throw new JsonReaderException("Read past end of current container context.");
+          }
+        case State.ConstructorStart:
+          break;
+        case State.Constructor:
+          break;
+        case State.Error:
+          break;
+        case State.Finished:
+          break;
+        default:
+          throw new ArgumentOutOfRangeException();
+      }
+
+      return false;
+    }
+
+    private void PopContext()
+    {
+      _stack.RemoveAt(_stack.Count - 1);
+      if (_stack.Count == 0)
+        _currentContext = null;
+      else
+        _currentContext = _stack[_stack.Count - 1];
+    }
+
+    private void PushContext(ContainerContext newContext)
+    {
+      _stack.Add(newContext);
+      _currentContext = newContext;
+    }
+
+    private byte ReadByte()
+    {
+      MovePosition(1);
+      return _reader.ReadByte();
+    }
+
+    private void ReadType(BsonType type)
+    {
+      switch (type)
+      {
+        case BsonType.Number:
+          SetToken(JsonToken.Float, ReadDouble());
+          break;
+        case BsonType.String:
+        case BsonType.Symbol:
+          SetToken(JsonToken.String, ReadLengthString());
+          break;
+        case BsonType.Object:
+          {
+            SetToken(JsonToken.StartObject);
+
+            ContainerContext newContext = new ContainerContext(BsonType.Object);
+            PushContext(newContext);
+            newContext.Length = ReadInt32();
+            break;
+          }
+        case BsonType.Array:
+          {
+            SetToken(JsonToken.StartArray);
+
+            ContainerContext newContext = new ContainerContext(BsonType.Array);
+            PushContext(newContext);
+            newContext.Length = ReadInt32();
+            break;
+          }
+        case BsonType.Binary:
+          SetToken(JsonToken.Bytes, ReadBinary());
+          break;
+        case BsonType.Undefined:
+          SetToken(JsonToken.Undefined);
+          break;
+        case BsonType.Oid:
+          byte[] oid = ReadBytes(12);
+          SetToken(JsonToken.Bytes, oid);
+          break;
+        case BsonType.Boolean:
+          bool b = Convert.ToBoolean(ReadByte());
+          SetToken(JsonToken.Boolean, b);
+          break;
+        case BsonType.Date:
+          long ticks = ReadInt64();
+          DateTime utcDateTime = JsonConvert.ConvertJavaScriptTicksToDateTime(ticks);
+
+          DateTime dateTime;
+          switch (DateTimeKindHandling)
+          {
+            case DateTimeKind.Unspecified:
+              dateTime = DateTime.SpecifyKind(utcDateTime.ToLocalTime(), DateTimeKind.Unspecified);
+              break;
+            case DateTimeKind.Local:
+              dateTime = utcDateTime.ToLocalTime();
+              break;
+            default:
+              dateTime = utcDateTime;
+              break;
+          }
+
+          SetToken(JsonToken.Date, dateTime);
+          break;
+        case BsonType.Null:
+          SetToken(JsonToken.Null);
+          break;
+        case BsonType.Regex:
+          string expression = ReadString();
+          string modifiers = ReadString();
+
+          string regex = @"/" + expression + @"/" + modifiers;
+          SetToken(JsonToken.String, regex);
+          break;
+        case BsonType.Reference:
+          SetToken(JsonToken.StartObject);
+          _bsonReaderState = BsonReaderState.ReferenceStart;
+          break;
+        case BsonType.Code:
+          SetToken(JsonToken.String, ReadLengthString());
+          break;
+        case BsonType.CodeWScope:
+          SetToken(JsonToken.StartObject);
+          _bsonReaderState = BsonReaderState.CodeWScopeStart;
+          break;
+        case BsonType.Integer:
+          SetToken(JsonToken.Integer, (long)ReadInt32());
+          break;
+        case BsonType.TimeStamp:
+        case BsonType.Long:
+          SetToken(JsonToken.Integer, ReadInt64());
+          break;
+        default:
+          throw new ArgumentOutOfRangeException("type", "Unexpected BsonType value: " + type);
+      }
+    }
+
+    private byte[] ReadBinary()
+    {
+      int dataLength = ReadInt32();
+
+      BsonBinaryType binaryType = (BsonBinaryType)ReadByte();
+
+#pragma warning disable 612,618
+      // the old binary type has the data length repeated in the data for some reason
+      if (binaryType == BsonBinaryType.Data && !_jsonNet35BinaryCompatibility)
+      {
+        dataLength = ReadInt32();
+      }
+#pragma warning restore 612,618
+
+      return ReadBytes(dataLength);
+    }
+
+    private string ReadString()
+    {
+      EnsureBuffers();
+
+      StringBuilder builder = null;
+
+      int totalBytesRead = 0;
+      // used in case of left over multibyte characters in the buffer
+      int offset = 0;
+      do
+      {
+        int count = offset;
+        byte b;
+        while (count < MaxCharBytesSize && (b = _reader.ReadByte()) > 0)
+        {
+          _byteBuffer[count++] = b;
+        }
+        int byteCount = count - offset;
+        totalBytesRead += byteCount;
+
+        if (count < MaxCharBytesSize && builder == null)
+        {
+          // pref optimization to avoid reading into a string builder
+          // if string is smaller than the buffer then return it directly
+          int length = Encoding.UTF8.GetChars(_byteBuffer, 0, byteCount, _charBuffer, 0);
+
+          MovePosition(totalBytesRead + 1);
+          return new string(_charBuffer, 0, length);
+        }
+        else
+        {
+          // calculate the index of the end of the last full character in the buffer
+          int lastFullCharStop = GetLastFullCharStop(count - 1);
+
+          int charCount = Encoding.UTF8.GetChars(_byteBuffer, 0, lastFullCharStop + 1, _charBuffer, 0);
+
+          if (builder == null)
+            builder = new StringBuilder(MaxCharBytesSize * 2);
+
+          builder.Append(_charBuffer, 0, charCount);
+
+          if (lastFullCharStop < byteCount - 1)
+          {
+            offset = byteCount - lastFullCharStop - 1;
+            // copy left over multi byte characters to beginning of buffer for next iteration
+            Array.Copy(_byteBuffer, lastFullCharStop + 1, _byteBuffer, 0, offset);
+          }
+          else
+          {
+            // reached end of string
+            if (count < MaxCharBytesSize)
+            {
+              MovePosition(totalBytesRead + 1);
+              return builder.ToString();
+            }
+
+            offset = 0;
+          }
+        }
+      }
+      while (true);
+    }
+
+    private string ReadLengthString()
+    {
+      int length = ReadInt32();
+
+      MovePosition(length);
+
+      string s = GetString(length - 1);
+      _reader.ReadByte();
+
+      return s;
+    }
+
+    private string GetString(int length)
+    {
+      if (length == 0)
+        return string.Empty;
+
+      EnsureBuffers();
+
+      StringBuilder builder = null;
+
+      int totalBytesRead = 0;
+
+      // used in case of left over multibyte characters in the buffer
+      int offset = 0;
+      do
+      {
+        int count = ((length - totalBytesRead) > MaxCharBytesSize - offset)
+          ? MaxCharBytesSize - offset
+          : length - totalBytesRead;
+
+        int byteCount = _reader.BaseStream.Read(_byteBuffer, offset, count);
+
+        if (byteCount == 0)
+          throw new EndOfStreamException("Unable to read beyond the end of the stream.");
+
+        totalBytesRead += byteCount;
+
+        // Above, byteCount is how many bytes we read this time.
+        // Below, byteCount is how many bytes are in the _byteBuffer.
+        byteCount += offset;
+
+        if (byteCount == length)
+        {
+          // pref optimization to avoid reading into a string builder
+          // first iteration and all bytes read then return string directly
+          int charCount = Encoding.UTF8.GetChars(_byteBuffer, 0, byteCount, _charBuffer, 0);
+          return new string(_charBuffer, 0, charCount);
+        }
+        else
+        {
+          int lastFullCharStop = GetLastFullCharStop(byteCount - 1);
+
+          if (builder == null)
+            builder = new StringBuilder(length);
+
+          int charCount = Encoding.UTF8.GetChars(_byteBuffer, 0, lastFullCharStop + 1, _charBuffer, 0);
+          builder.Append(_charBuffer, 0, charCount);
+
+          if (lastFullCharStop < byteCount - 1)
+          {
+            offset = byteCount - lastFullCharStop - 1;
+            // copy left over multi byte characters to beginning of buffer for next iteration
+            Array.Copy(_byteBuffer, lastFullCharStop + 1, _byteBuffer, 0, offset);
+          }
+          else
+          {
+            offset = 0;
+          }
+        }
+      }
+      while (totalBytesRead < length);
+
+      return builder.ToString();
+    }
+
+    private int GetLastFullCharStop(int start)
+    {
+      int lookbackPos = start;
+      int bis = 0;
+      while (lookbackPos >= 0)
+      {
+        bis = BytesInSequence(_byteBuffer[lookbackPos]);
+        if (bis == 0)
+        {
+          lookbackPos--;
+          continue;
+        }
+        else if (bis == 1)
+        {
+          break;
+        }
+        else
+        {
+          lookbackPos--;
+          break;
+        }
+      }
+      if (bis == start - lookbackPos)
+      {
+        //Full character.
+        return start;
+      }
+      else
+      {
+        return lookbackPos;
+      }
+    }
+
+    private int BytesInSequence(byte b)
+    {
+      if (b <= _seqRange1[1]) return 1;
+      if (b >= _seqRange2[0] && b <= _seqRange2[1]) return 2;
+      if (b >= _seqRange3[0] && b <= _seqRange3[1]) return 3;
+      if (b >= _seqRange4[0] && b <= _seqRange4[1]) return 4;
+      return 0;
+    }
+
+    private void EnsureBuffers()
+    {
+      if (_byteBuffer == null)
+      {
+        _byteBuffer = new byte[MaxCharBytesSize];
+      }
+      if (_charBuffer == null)
+      {
+        int charBufferSize = Encoding.UTF8.GetMaxCharCount(MaxCharBytesSize);
+        _charBuffer = new char[charBufferSize];
+      }
+    }
+
+    private double ReadDouble()
+    {
+      MovePosition(8);
+      return _reader.ReadDouble();
+    }
+
+    private int ReadInt32()
+    {
+      MovePosition(4);
+      return _reader.ReadInt32();
+    }
+
+    private long ReadInt64()
+    {
+      MovePosition(8);
+      return _reader.ReadInt64();
+    }
+
+    private BsonType ReadType()
+    {
+      MovePosition(1);
+      return (BsonType)_reader.ReadSByte();
+    }
+
+    private void MovePosition(int count)
+    {
+      _currentContext.Position += count;
+    }
+
+    private byte[] ReadBytes(int count)
+    {
+      MovePosition(count);
+      return _reader.ReadBytes(count);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Bson/BsonToken.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Bson/BsonToken.cs
new file mode 100644 (file)
index 0000000..789d3cd
--- /dev/null
@@ -0,0 +1,121 @@
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Newtonsoft.Json.Bson
+{
+  internal abstract class BsonToken
+  {
+    public abstract BsonType Type { get; }
+    public BsonToken Parent { get; set; }
+    public int CalculatedSize { get; set; }
+  }
+
+  internal class BsonObject : BsonToken, IEnumerable<BsonProperty>
+  {
+    private readonly List<BsonProperty> _children = new List<BsonProperty>();
+
+    public void Add(string name, BsonToken token)
+    {
+      _children.Add(new BsonProperty { Name = new BsonString(name, false), Value = token });
+      token.Parent = this;
+    }
+
+    public override BsonType Type
+    {
+      get { return BsonType.Object; }
+    }
+
+    public IEnumerator<BsonProperty> GetEnumerator()
+    {
+      return _children.GetEnumerator();
+    }
+
+    IEnumerator IEnumerable.GetEnumerator()
+    {
+      return GetEnumerator();
+    }
+  }
+
+  internal class BsonArray : BsonToken, IEnumerable<BsonToken>
+  {
+    private readonly List<BsonToken> _children = new List<BsonToken>();
+
+    public void Add(BsonToken token)
+    {
+      _children.Add(token);
+      token.Parent = this;
+    }
+
+    public override BsonType Type
+    {
+      get { return BsonType.Array; }
+    }
+
+    public IEnumerator<BsonToken> GetEnumerator()
+    {
+      return _children.GetEnumerator();
+    }
+
+    IEnumerator IEnumerable.GetEnumerator()
+    {
+      return GetEnumerator();
+    }
+  }
+
+  internal class BsonValue : BsonToken
+  {
+    private object _value;
+    private BsonType _type;
+
+    public BsonValue(object value, BsonType type)
+    {
+      _value = value;
+      _type = type;
+    }
+
+    public object Value
+    {
+      get { return _value; }
+    }
+
+    public override BsonType Type
+    {
+      get { return _type; }
+    }
+  }
+
+  internal class BsonString : BsonValue
+  {
+    public int ByteCount { get; set; }
+    public bool IncludeLength { get; set; }
+
+    public BsonString(object value, bool includeLength)
+      : base(value, BsonType.String)
+    {
+      IncludeLength = includeLength;
+    }
+  }
+
+  internal class BsonRegex : BsonToken
+  {
+    public BsonString Pattern { get; set; }
+    public BsonString Options { get; set; }
+
+    public BsonRegex(string pattern, string options)
+    {
+      Pattern = new BsonString(pattern, false);
+      Options = new BsonString(options, false);
+    }
+
+    public override BsonType Type
+    {
+      get { return BsonType.Regex; }
+    }
+  }
+
+  internal class BsonProperty
+  {
+    public BsonString Name { get; set; }
+    public BsonToken Value { get; set; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Bson/BsonType.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Bson/BsonType.cs
new file mode 100644 (file)
index 0000000..f4e1214
--- /dev/null
@@ -0,0 +1,51 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Bson
+{
+  internal enum BsonType : sbyte 
+  {
+    Number = 1,
+    String = 2,
+    Object = 3,
+    Array = 4,
+    Binary = 5,
+    Undefined = 6,
+    Oid = 7,
+    Boolean = 8,
+    Date = 9,
+    Null = 10,
+    Regex = 11,
+    Reference = 12,
+    Code = 13,
+    Symbol = 14,
+    CodeWScope = 15,
+    Integer = 16,
+    TimeStamp = 17,
+    Long = 18,
+    MinKey = -1,
+    MaxKey = 127
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Bson/BsonWriter.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Bson/BsonWriter.cs
new file mode 100644 (file)
index 0000000..fe34289
--- /dev/null
@@ -0,0 +1,442 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using Newtonsoft.Json.Utilities;
+using Newtonsoft.Json.Linq;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Bson
+{
+  /// <summary>
+  /// Represents a writer that provides a fast, non-cached, forward-only way of generating Json data.
+  /// </summary>
+  public class BsonWriter : JsonWriter
+  {
+    private readonly BsonBinaryWriter _writer;
+
+    private BsonToken _root;
+    private BsonToken _parent;
+    private string _propertyName;
+
+    /// <summary>
+    /// Gets or sets the <see cref="DateTimeKind" /> used when writing <see cref="DateTime"/> values to BSON.
+    /// When set to <see cref="DateTimeKind.Unspecified" /> no conversion will occur.
+    /// </summary>
+    /// <value>The <see cref="DateTimeKind" /> used when writing <see cref="DateTime"/> values to BSON.</value>
+    public DateTimeKind DateTimeKindHandling
+    {
+      get { return _writer.DateTimeKindHandling; }
+      set { _writer.DateTimeKindHandling = value; }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="BsonWriter"/> class.
+    /// </summary>
+    /// <param name="stream">The stream.</param>
+    public BsonWriter(Stream stream)
+    {
+      ValidationUtils.ArgumentNotNull(stream, "stream");
+      _writer = new BsonBinaryWriter(stream);
+    }
+
+    /// <summary>
+    /// Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream.
+    /// </summary>
+    public override void Flush()
+    {
+      _writer.Flush();
+    }
+
+    /// <summary>
+    /// Writes the end.
+    /// </summary>
+    /// <param name="token">The token.</param>
+    protected override void WriteEnd(JsonToken token)
+    {
+      base.WriteEnd(token);
+      RemoveParent();
+
+      if (Top == 0)
+      {
+        _writer.WriteToken(_root);
+      }
+    }
+
+    /// <summary>
+    /// Writes out a comment <code>/*...*/</code> containing the specified text.
+    /// </summary>
+    /// <param name="text">Text to place inside the comment.</param>
+    public override void WriteComment(string text)
+    {
+      throw new JsonWriterException("Cannot write JSON comment as BSON.");
+    }
+
+    /// <summary>
+    /// Writes the start of a constructor with the given name.
+    /// </summary>
+    /// <param name="name">The name of the constructor.</param>
+    public override void WriteStartConstructor(string name)
+    {
+      throw new JsonWriterException("Cannot write JSON constructor as BSON.");
+    }
+
+    /// <summary>
+    /// Writes raw JSON.
+    /// </summary>
+    /// <param name="json">The raw JSON to write.</param>
+    public override void WriteRaw(string json)
+    {
+      throw new JsonWriterException("Cannot write raw JSON as BSON.");
+    }
+
+    /// <summary>
+    /// Writes raw JSON where a value is expected and updates the writer's state.
+    /// </summary>
+    /// <param name="json">The raw JSON to write.</param>
+    public override void WriteRawValue(string json)
+    {
+      throw new JsonWriterException("Cannot write raw JSON as BSON.");
+    }
+
+    /// <summary>
+    /// Writes the beginning of a Json array.
+    /// </summary>
+    public override void WriteStartArray()
+    {
+      base.WriteStartArray();
+
+      AddParent(new BsonArray());
+    }
+
+    /// <summary>
+    /// Writes the beginning of a Json object.
+    /// </summary>
+    public override void WriteStartObject()
+    {
+      base.WriteStartObject();
+
+      AddParent(new BsonObject());
+    }
+
+    /// <summary>
+    /// Writes the property name of a name/value pair on a Json object.
+    /// </summary>
+    /// <param name="name">The name of the property.</param>
+    public override void WritePropertyName(string name)
+    {
+      base.WritePropertyName(name);
+
+      _propertyName = name;
+    }
+
+    /// <summary>
+    /// Closes this stream and the underlying stream.
+    /// </summary>
+    public override void Close()
+    {
+      base.Close();
+
+      if (CloseOutput && _writer != null)
+        _writer.Close();
+    }
+
+    private void AddParent(BsonToken container)
+    {
+      AddToken(container);
+      _parent = container;
+    }
+
+    private void RemoveParent()
+    {
+      _parent = _parent.Parent;
+    }
+
+    private void AddValue(object value, BsonType type)
+    {
+      AddToken(new BsonValue(value, type));
+    }
+
+    internal void AddToken(BsonToken token)
+    {
+      if (_parent != null)
+      {
+        if (_parent is BsonObject)
+        {
+          ((BsonObject)_parent).Add(_propertyName, token);
+          _propertyName = null;
+        }
+        else
+        {
+          ((BsonArray)_parent).Add(token);
+        }
+      }
+      else
+      {
+        _parent = token;
+        _root = token;
+      }
+    }
+
+    #region WriteValue methods
+    /// <summary>
+    /// Writes a null value.
+    /// </summary>
+    public override void WriteNull()
+    {
+      base.WriteNull();
+      AddValue(null, BsonType.Null);
+    }
+
+    /// <summary>
+    /// Writes an undefined value.
+    /// </summary>
+    public override void WriteUndefined()
+    {
+      base.WriteUndefined();
+      AddValue(null, BsonType.Undefined);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="String"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="String"/> value to write.</param>
+    public override void WriteValue(string value)
+    {
+      base.WriteValue(value);
+      if (value == null)
+        AddValue(null, BsonType.Null);
+      else
+        AddToken(new BsonString(value, true));
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Int32"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Int32"/> value to write.</param>
+    public override void WriteValue(int value)
+    {
+      base.WriteValue(value);
+      AddValue(value, BsonType.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="UInt32"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="UInt32"/> value to write.</param>
+    [CLSCompliant(false)]
+    public override void WriteValue(uint value)
+    {
+      if (value > int.MaxValue)
+        throw new JsonWriterException("Value is too large to fit in a signed 32 bit integer. BSON does not support unsigned values.");
+
+      base.WriteValue(value);
+      AddValue(value, BsonType.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Int64"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Int64"/> value to write.</param>
+    public override void WriteValue(long value)
+    {
+      base.WriteValue(value);
+      AddValue(value, BsonType.Long);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="UInt64"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="UInt64"/> value to write.</param>
+    [CLSCompliant(false)]
+    public override void WriteValue(ulong value)
+    {
+      if (value > long.MaxValue)
+        throw new JsonWriterException("Value is too large to fit in a signed 64 bit integer. BSON does not support unsigned values.");
+
+      base.WriteValue(value);
+      AddValue(value, BsonType.Long);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Single"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Single"/> value to write.</param>
+    public override void WriteValue(float value)
+    {
+      base.WriteValue(value);
+      AddValue(value, BsonType.Number);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Double"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Double"/> value to write.</param>
+    public override void WriteValue(double value)
+    {
+      base.WriteValue(value);
+      AddValue(value, BsonType.Number);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Boolean"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Boolean"/> value to write.</param>
+    public override void WriteValue(bool value)
+    {
+      base.WriteValue(value);
+      AddValue(value, BsonType.Boolean);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Int16"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Int16"/> value to write.</param>
+    public override void WriteValue(short value)
+    {
+      base.WriteValue(value);
+      AddValue(value, BsonType.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="UInt16"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="UInt16"/> value to write.</param>
+    [CLSCompliant(false)]
+    public override void WriteValue(ushort value)
+    {
+      base.WriteValue(value);
+      AddValue(value, BsonType.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Char"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Char"/> value to write.</param>
+    public override void WriteValue(char value)
+    {
+      base.WriteValue(value);
+      AddToken(new BsonString(value.ToString(), true));
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Byte"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Byte"/> value to write.</param>
+    public override void WriteValue(byte value)
+    {
+      base.WriteValue(value);
+      AddValue(value, BsonType.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="SByte"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="SByte"/> value to write.</param>
+    [CLSCompliant(false)]
+    public override void WriteValue(sbyte value)
+    {
+      base.WriteValue(value);
+      AddValue(value, BsonType.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Decimal"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Decimal"/> value to write.</param>
+    public override void WriteValue(decimal value)
+    {
+      base.WriteValue(value);
+      AddValue(value, BsonType.Number);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="DateTime"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="DateTime"/> value to write.</param>
+    public override void WriteValue(DateTime value)
+    {
+      base.WriteValue(value);
+      AddValue(value, BsonType.Date);
+    }
+
+#if !PocketPC && !NET20
+    /// <summary>
+    /// Writes a <see cref="DateTimeOffset"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="DateTimeOffset"/> value to write.</param>
+    public override void WriteValue(DateTimeOffset value)
+    {
+      base.WriteValue(value);
+      AddValue(value, BsonType.Date);
+    }
+#endif
+
+    /// <summary>
+    /// Writes a <see cref="T:Byte[]"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="T:Byte[]"/> value to write.</param>
+    public override void WriteValue(byte[] value)
+    {
+      base.WriteValue(value);
+      AddValue(value, BsonType.Binary);
+    }
+    #endregion
+
+    /// <summary>
+    /// Writes a <see cref="T:Byte[]"/> value that represents a BSON object id.
+    /// </summary>
+    /// <param name="value"></param>
+    public void WriteObjectId(byte[] value)
+    {
+      ValidationUtils.ArgumentNotNull(value, "value");
+
+      if (value.Length != 12)
+        throw new Exception("An object id must be 12 bytes");
+
+      // hack to update the writer state
+      AutoComplete(JsonToken.Undefined);
+      AddValue(value, BsonType.Oid);
+    }
+
+    /// <summary>
+    /// Writes a BSON regex.
+    /// </summary>
+    /// <param name="pattern">The regex pattern.</param>
+    /// <param name="options">The regex options.</param>
+    public void WriteRegex(string pattern, string options)
+    {
+      ValidationUtils.ArgumentNotNull(pattern, "pattern");
+
+      // hack to update the writer state
+      AutoComplete(JsonToken.Undefined);
+      AddToken(new BsonRegex(pattern, options));
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/ConstructorHandling.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/ConstructorHandling.cs
new file mode 100644 (file)
index 0000000..f8cb5de
--- /dev/null
@@ -0,0 +1,47 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Specifies how constructors are used when initializing objects during deserialization by the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public enum ConstructorHandling
+  {
+    /// <summary>
+    /// First attempt to use the public default constructor then fall back to single paramatized constructor.
+    /// </summary>
+    Default = 0,
+    /// <summary>
+    /// Allow Json.NET to use a non-public default constructor.
+    /// </summary>
+    AllowNonPublicDefaultConstructor = 1
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/BinaryConverter.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/BinaryConverter.cs
new file mode 100644 (file)
index 0000000..7bf8c6a
--- /dev/null
@@ -0,0 +1,147 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+#if !SILVERLIGHT
+using System.Data.SqlTypes;
+#endif
+using System.Globalization;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Converters
+{
+#if !SILVERLIGHT && !PocketPC && !NET20
+  internal interface IBinary
+  {
+    byte[] ToArray();
+  }
+#endif
+
+  /// <summary>
+  /// Converts a binary value to and from a base 64 string value.
+  /// </summary>
+  public class BinaryConverter : JsonConverter
+  {
+#if !SILVERLIGHT && !PocketPC && !NET20
+    private const string BinaryTypeName = "System.Data.Linq.Binary";
+#endif
+
+    /// <summary>
+    /// Writes the JSON representation of the object.
+    /// </summary>
+    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
+    /// <param name="value">The value.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+    {
+      if (value == null)
+      {
+        writer.WriteNull();
+        return;
+      }
+
+      byte[] data = GetByteArray(value);
+
+      writer.WriteValue(data);
+    }
+
+    private byte[] GetByteArray(object value)
+    {
+#if !SILVERLIGHT && !PocketPC && !NET20
+      if (value.GetType().AssignableToTypeName(BinaryTypeName))
+      {
+        IBinary binary = DynamicWrapper.CreateWrapper<IBinary>(value);
+        return binary.ToArray();
+      }
+#endif
+#if !SILVERLIGHT
+      if (value is SqlBinary)
+        return ((SqlBinary) value).Value;
+#endif
+      throw new Exception("Unexpected value type when writing binary: {0}".FormatWith(CultureInfo.InvariantCulture, value.GetType()));
+    }
+
+    /// <summary>
+    /// Reads the JSON representation of the object.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
+    /// <param name="objectType">Type of the object.</param>
+    /// <param name="existingValue">The existing value of object being read.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    /// <returns>The object value.</returns>
+    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+    {
+      Type t = (ReflectionUtils.IsNullableType(objectType))
+        ? Nullable.GetUnderlyingType(objectType)
+        : objectType;
+
+      if (reader.TokenType == JsonToken.Null)
+      {
+        if (!ReflectionUtils.IsNullable(objectType))
+          throw new Exception("Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType));
+
+        return null;
+      }
+
+      if (reader.TokenType != JsonToken.String)
+        throw new Exception("Unexpected token parsing binary. Expected String, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
+
+      // current token is already at base64 string
+      // unable to call ReadAsBytes so do it the old fashion way
+      string encodedData = reader.Value.ToString();
+      byte[] data = Convert.FromBase64String(encodedData);
+
+#if !SILVERLIGHT && !PocketPC && !NET20
+      if (t.AssignableToTypeName(BinaryTypeName))
+        return Activator.CreateInstance(t, data);
+#endif
+#if !SILVERLIGHT
+      if (t == typeof(SqlBinary))
+        return new SqlBinary(data);
+#endif
+      throw new Exception("Unexpected object type when writing binary: {0}".FormatWith(CultureInfo.InvariantCulture, objectType));
+    }
+
+    /// <summary>
+    /// Determines whether this instance can convert the specified object type.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns>
+    ///        <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
+    /// </returns>
+    public override bool CanConvert(Type objectType)
+    {
+#if !SILVERLIGHT && !PocketPC && !NET20
+      if (objectType.AssignableToTypeName(BinaryTypeName))
+        return true;
+#endif
+#if !SILVERLIGHT
+      if (objectType == typeof(SqlBinary) || objectType == typeof(SqlBinary?))
+        return true;
+#endif
+      return false;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/BsonObjectIdConverter.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/BsonObjectIdConverter.cs
new file mode 100644 (file)
index 0000000..e70a378
--- /dev/null
@@ -0,0 +1,67 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Bson;
+using System.Globalization;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Converters
+{
+  /// <summary>
+  /// Converts a <see cref="BsonObjectId"/> to and from JSON and BSON.
+  /// </summary>
+  public class BsonObjectIdConverter : JsonConverter
+  {
+    /// <summary>
+    /// Writes the JSON representation of the object.
+    /// </summary>
+    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
+    /// <param name="value">The value.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+    {
+      BsonObjectId objectId = (BsonObjectId) value;
+
+      BsonWriter bsonWriter = writer as BsonWriter;
+      if (bsonWriter != null)
+      {
+        bsonWriter.WriteObjectId(objectId.Value);
+      }
+      else
+      {
+        writer.WriteValue(objectId.Value);
+      }
+    }
+
+    /// <summary>
+    /// Reads the JSON representation of the object.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
+    /// <param name="objectType">Type of the object.</param>
+    /// <param name="existingValue">The existing value of object being read.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    /// <returns>The object value.</returns>
+    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+    {
+      if (reader.TokenType != JsonToken.Bytes)
+        throw new JsonSerializationException("Expected Bytes but got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
+
+      byte[] value = (byte[])reader.Value;
+
+      return new BsonObjectId(value);
+    }
+
+    /// <summary>
+    /// Determines whether this instance can convert the specified object type.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns>
+    ///        <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
+    /// </returns>
+    public override bool CanConvert(Type objectType)
+    {
+      return (objectType == typeof (BsonObjectId));
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/CustomCreationConverter.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/CustomCreationConverter.cs
new file mode 100644 (file)
index 0000000..368d71b
--- /dev/null
@@ -0,0 +1,98 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json.Converters
+{
+  /// <summary>
+  /// Create a custom object
+  /// </summary>
+  /// <typeparam name="T"></typeparam>
+  public abstract class CustomCreationConverter<T> : JsonConverter
+  {
+    /// <summary>
+    /// Writes the JSON representation of the object.
+    /// </summary>
+    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
+    /// <param name="value">The value.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+    {
+      throw new NotSupportedException("CustomCreationConverter should only be used while deserializing.");
+    }
+
+    /// <summary>
+    /// Reads the JSON representation of the object.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
+    /// <param name="objectType">Type of the object.</param>
+    /// <param name="existingValue">The existing value of object being read.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    /// <returns>The object value.</returns>
+    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+    {
+      if (reader.TokenType == JsonToken.Null)
+        return null;
+
+      T value = Create(objectType);
+      if (value == null)
+        throw new JsonSerializationException("No object created.");
+
+      serializer.Populate(reader, value);
+      return value;
+    }
+
+    /// <summary>
+    /// Creates an object which will then be populated by the serializer.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns></returns>
+    public abstract T Create(Type objectType);
+
+    /// <summary>
+    /// Determines whether this instance can convert the specified object type.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns>
+    ///        <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
+    /// </returns>
+    public override bool CanConvert(Type objectType)
+    {
+      return typeof (T).IsAssignableFrom(objectType);
+    }
+
+    /// <summary>
+    /// Gets a value indicating whether this <see cref="JsonConverter"/> can write JSON.
+    /// </summary>
+    /// <value>
+    ///        <c>true</c> if this <see cref="JsonConverter"/> can write JSON; otherwise, <c>false</c>.
+    /// </value>
+    public override bool CanWrite
+    {
+      get { return false; }
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/DataSetConverter.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/DataSetConverter.cs
new file mode 100644 (file)
index 0000000..df88ff9
--- /dev/null
@@ -0,0 +1,101 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+#if !SILVERLIGHT
+using System;
+using System.Data;
+
+namespace Newtonsoft.Json.Converters
+{
+  /// <summary>
+  /// Converts a <see cref="DataSet"/> to and from JSON.
+  /// </summary>
+  public class DataSetConverter : JsonConverter
+  {
+    /// <summary>
+    /// Writes the JSON representation of the object.
+    /// </summary>
+    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
+    /// <param name="value">The value.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+    {
+      DataSet dataSet = (DataSet)value;
+
+      DataTableConverter converter = new DataTableConverter();
+
+      writer.WriteStartObject();
+
+      foreach (DataTable table in dataSet.Tables)
+      {
+        writer.WritePropertyName(table.TableName);
+        
+        converter.WriteJson(writer, table, serializer);
+      }
+
+      writer.WriteEndObject();
+    }
+
+    /// <summary>
+    /// Reads the JSON representation of the object.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
+    /// <param name="objectType">Type of the object.</param>
+    /// <param name="existingValue">The existing value of object being read.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    /// <returns>The object value.</returns>
+    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+    {
+      DataSet ds = new DataSet();
+
+      DataTableConverter converter = new DataTableConverter();
+
+      reader.Read();
+
+      while (reader.TokenType == JsonToken.PropertyName)
+      {
+        DataTable dt = (DataTable)converter.ReadJson(reader, typeof (DataTable), null, serializer);
+        ds.Tables.Add(dt);
+
+        reader.Read();
+      }
+
+      return ds;
+    }
+
+    /// <summary>
+    /// Determines whether this instance can convert the specified value type.
+    /// </summary>
+    /// <param name="valueType">Type of the value.</param>
+    /// <returns>
+    ///        <c>true</c> if this instance can convert the specified value type; otherwise, <c>false</c>.
+    /// </returns>
+    public override bool CanConvert(Type valueType)
+    {
+      return (valueType == typeof(DataSet));
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/DataTableConverter.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/DataTableConverter.cs
new file mode 100644 (file)
index 0000000..9845582
--- /dev/null
@@ -0,0 +1,151 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+#if !SILVERLIGHT
+using System;
+using System.Data;
+
+namespace Newtonsoft.Json.Converters
+{
+  /// <summary>
+  /// Converts a <see cref="DataTable"/> to and from JSON.
+  /// </summary>
+  public class DataTableConverter : JsonConverter
+  {
+    /// <summary>
+    /// Writes the JSON representation of the object.
+    /// </summary>
+    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
+    /// <param name="value">The value.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+    {
+      DataTable table = (DataTable)value;
+
+      writer.WriteStartArray();
+
+      foreach (DataRow row in table.Rows)
+      {
+        writer.WriteStartObject();
+        foreach (DataColumn column in row.Table.Columns)
+        {
+          writer.WritePropertyName(column.ColumnName);
+          serializer.Serialize(writer, row[column]);
+        }
+        writer.WriteEndObject();
+      }
+
+      writer.WriteEndArray();
+    }
+
+    /// <summary>
+    /// Reads the JSON representation of the object.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
+    /// <param name="objectType">Type of the object.</param>
+    /// <param name="existingValue">The existing value of object being read.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    /// <returns>The object value.</returns>
+    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+    {
+      DataTable dt;
+
+      if (reader.TokenType == JsonToken.PropertyName)
+      {
+        dt = new DataTable((string)reader.Value);
+        reader.Read();
+      }
+      else
+      {
+        dt = new DataTable();
+      }
+
+      reader.Read();
+
+      while (reader.TokenType == JsonToken.StartObject)
+      {
+        DataRow dr = dt.NewRow();
+        reader.Read();
+
+        while (reader.TokenType == JsonToken.PropertyName)
+        {
+          string columnName = (string) reader.Value;
+
+          reader.Read();
+
+          if (!dt.Columns.Contains(columnName))
+          {
+            Type columnType = GetColumnDataType(reader.TokenType);
+            dt.Columns.Add(new DataColumn(columnName, columnType));
+          }
+
+          dr[columnName] = reader.Value;
+          reader.Read();
+        }
+
+        dr.EndEdit();
+        dt.Rows.Add(dr);
+
+        reader.Read();
+      }
+
+      return dt;
+    }
+
+    private static Type GetColumnDataType(JsonToken tokenType)
+    {
+      switch (tokenType)
+      {
+        case JsonToken.Integer:
+          return typeof (long);
+        case JsonToken.Float:
+          return typeof (double);
+        case JsonToken.String:
+        case JsonToken.Null:
+        case JsonToken.Undefined:
+          return typeof (string);
+        case JsonToken.Boolean:
+          return typeof (bool);
+        case JsonToken.Date:
+          return typeof (DateTime);
+        default:
+          throw new ArgumentOutOfRangeException();
+      }
+    }
+
+    /// <summary>
+    /// Determines whether this instance can convert the specified value type.
+    /// </summary>
+    /// <param name="valueType">Type of the value.</param>
+    /// <returns>
+    ///        <c>true</c> if this instance can convert the specified value type; otherwise, <c>false</c>.
+    /// </returns>
+    public override bool CanConvert(Type valueType)
+    {
+      return (valueType == typeof(DataTable));
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/DateTimeConverterBase.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/DateTimeConverterBase.cs
new file mode 100644 (file)
index 0000000..914e755
--- /dev/null
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Converters
+{
+  /// <summary>
+  /// Provides a base class for converting a <see cref="DateTime"/> to and from JSON.
+  /// </summary>
+  public abstract class DateTimeConverterBase : JsonConverter
+  {
+    /// <summary>
+    /// Determines whether this instance can convert the specified object type.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns>
+    ///        <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
+    /// </returns>
+    public override bool CanConvert(Type objectType)
+    {
+      if (objectType == typeof(DateTime) || objectType == typeof(DateTime?))
+        return true;
+#if !PocketPC && !NET20
+      if (objectType == typeof(DateTimeOffset) || objectType == typeof(DateTimeOffset?))
+        return true;
+#endif
+
+      return false;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/EntityKeyMemberConverter.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/EntityKeyMemberConverter.cs
new file mode 100644 (file)
index 0000000..fba98f8
--- /dev/null
@@ -0,0 +1,140 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+#if !PocketPC && !SILVERLIGHT && !NET20
+using System;
+using Newtonsoft.Json.Serialization;
+using System.Globalization;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Converters
+{
+  internal interface IEntityKeyMember
+  {
+    string Key { get; set; }
+    object Value { get; set; }
+  }
+
+  /// <summary>
+  /// Converts an Entity Framework EntityKey to and from JSON.
+  /// </summary>
+  public class EntityKeyMemberConverter : JsonConverter
+  {
+    private const string EntityKeyMemberFullTypeName = "System.Data.EntityKeyMember";
+
+    /// <summary>
+    /// Writes the JSON representation of the object.
+    /// </summary>
+    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
+    /// <param name="value">The value.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+    {
+      IEntityKeyMember entityKeyMember = DynamicWrapper.CreateWrapper<IEntityKeyMember>(value);
+      Type keyType = (entityKeyMember.Value != null) ? entityKeyMember.Value.GetType() : null;
+
+      writer.WriteStartObject();
+      writer.WritePropertyName("Key");
+      writer.WriteValue(entityKeyMember.Key);
+      writer.WritePropertyName("Type");
+      writer.WriteValue((keyType != null) ? keyType.FullName : null);
+
+      writer.WritePropertyName("Value");
+
+      if (keyType != null)
+      {
+        string valueJson;
+        if (JsonSerializerInternalWriter.TryConvertToString(entityKeyMember.Value, keyType, out valueJson))
+          writer.WriteValue(valueJson);
+        else
+          writer.WriteValue(entityKeyMember.Value);
+      }
+      else
+      {
+        writer.WriteNull();
+      }
+
+      writer.WriteEndObject();
+    }
+
+    private static void ReadAndAssertProperty(JsonReader reader, string propertyName)
+    {
+      ReadAndAssert(reader);
+
+      if (reader.TokenType != JsonToken.PropertyName || reader.Value.ToString() != propertyName)
+        throw new JsonSerializationException("Expected JSON property '{0}'.".FormatWith(CultureInfo.InvariantCulture, propertyName));
+    }
+
+    private static void ReadAndAssert(JsonReader reader)
+    {
+      if (!reader.Read())
+        throw new JsonSerializationException("Unexpected end.");
+    }
+
+    /// <summary>
+    /// Reads the JSON representation of the object.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
+    /// <param name="objectType">Type of the object.</param>
+    /// <param name="existingValue">The existing value of object being read.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    /// <returns>The object value.</returns>
+    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+    {
+      IEntityKeyMember entityKeyMember = DynamicWrapper.CreateWrapper<IEntityKeyMember>(Activator.CreateInstance(objectType));
+
+      ReadAndAssertProperty(reader, "Key");
+      ReadAndAssert(reader);
+      entityKeyMember.Key = reader.Value.ToString();
+
+      ReadAndAssertProperty(reader, "Type");
+      ReadAndAssert(reader);
+      string type = reader.Value.ToString();
+
+      Type t = Type.GetType(type);
+
+      ReadAndAssertProperty(reader, "Value");
+      ReadAndAssert(reader);
+      entityKeyMember.Value = serializer.Deserialize(reader, t);
+
+      ReadAndAssert(reader);
+
+      return DynamicWrapper.GetUnderlyingObject(entityKeyMember);
+    }
+
+    /// <summary>
+    /// Determines whether this instance can convert the specified object type.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns>
+    ///        <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
+    /// </returns>
+    public override bool CanConvert(Type objectType)
+    {
+      return (objectType.AssignableToTypeName(EntityKeyMemberFullTypeName));
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/ExpandoObjectConverter.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/ExpandoObjectConverter.cs
new file mode 100644 (file)
index 0000000..5158beb
--- /dev/null
@@ -0,0 +1,140 @@
+#if !(NET35 || NET20 || WINDOWS_PHONE)
+
+using System;
+using System.Collections.Generic;
+using System.Dynamic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Converters
+{
+  /// <summary>
+  /// Converts an ExpandoObject to and from JSON.
+  /// </summary>
+  public class ExpandoObjectConverter : JsonConverter
+  {
+    /// <summary>
+    /// Writes the JSON representation of the object.
+    /// </summary>
+    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
+    /// <param name="value">The value.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+    {
+      // can write is set to false
+    }
+
+    /// <summary>
+    /// Reads the JSON representation of the object.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
+    /// <param name="objectType">Type of the object.</param>
+    /// <param name="existingValue">The existing value of object being read.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    /// <returns>The object value.</returns>
+    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+    {
+      return ReadValue(reader);
+    }
+
+    private object ReadValue(JsonReader reader)
+    {
+      while (reader.TokenType == JsonToken.Comment)
+      {
+        if (!reader.Read())
+          throw new Exception("Unexpected end.");
+      }
+
+      switch (reader.TokenType)
+      {
+        case JsonToken.StartObject:
+          return ReadObject(reader);
+        case JsonToken.StartArray:
+          return ReadList(reader);
+        default:
+          if (JsonReader.IsPrimitiveToken(reader.TokenType))
+            return reader.Value;
+
+          throw new Exception("Unexpected token when converting ExpandoObject: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
+      }
+    }
+
+    private object ReadList(JsonReader reader)
+    {
+      IList<object> list = new List<object>();
+
+      while (reader.Read())
+      {
+        switch (reader.TokenType)
+        {
+          case JsonToken.Comment:
+            break;
+          default:
+            object v = ReadValue(reader);
+
+            list.Add(v);
+            break;
+          case JsonToken.EndArray:
+            return list;
+        }
+      }
+
+      throw new Exception("Unexpected end.");
+    }
+
+    private object ReadObject(JsonReader reader)
+    {
+      IDictionary<string, object> expandoObject = new ExpandoObject();
+
+      while (reader.Read())
+      {
+        switch (reader.TokenType)
+        {
+          case JsonToken.PropertyName:
+            string propertyName = reader.Value.ToString();
+
+            if (!reader.Read())
+              throw new Exception("Unexpected end.");
+
+            object v = ReadValue(reader);
+
+            expandoObject[propertyName] = v;
+            break;
+          case JsonToken.Comment:
+            break;
+          case JsonToken.EndObject:
+            return expandoObject;
+        }
+      }
+
+      throw new Exception("Unexpected end.");
+    }
+
+    /// <summary>
+    /// Determines whether this instance can convert the specified object type.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns>
+    ///        <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
+    /// </returns>
+    public override bool CanConvert(Type objectType)
+    {
+      return (objectType == typeof (ExpandoObject));
+    }
+
+    /// <summary>
+    /// Gets a value indicating whether this <see cref="JsonConverter"/> can write JSON.
+    /// </summary>
+    /// <value>
+    ///        <c>true</c> if this <see cref="JsonConverter"/> can write JSON; otherwise, <c>false</c>.
+    /// </value>
+    public override bool CanWrite
+    {
+      get { return false; }
+    }
+  }
+}
+
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/IsoDateTimeConverter.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/IsoDateTimeConverter.cs
new file mode 100644 (file)
index 0000000..4007626
--- /dev/null
@@ -0,0 +1,134 @@
+using System;
+using System.Globalization;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Converters
+{
+  /// <summary>
+  /// Converts a <see cref="DateTime"/> to and from the ISO 8601 date format (e.g. 2008-04-12T12:53Z).
+  /// </summary>
+  public class IsoDateTimeConverter : DateTimeConverterBase
+  {
+    private const string DefaultDateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";
+
+    private DateTimeStyles _dateTimeStyles = DateTimeStyles.RoundtripKind;
+    private string _dateTimeFormat;
+    private CultureInfo _culture;
+
+    /// <summary>
+    /// Gets or sets the date time styles used when converting a date to and from JSON.
+    /// </summary>
+    /// <value>The date time styles used when converting a date to and from JSON.</value>
+    public DateTimeStyles DateTimeStyles
+    {
+      get { return _dateTimeStyles; }
+      set { _dateTimeStyles = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets the date time format used when converting a date to and from JSON.
+    /// </summary>
+    /// <value>The date time format used when converting a date to and from JSON.</value>
+    public string DateTimeFormat
+    {
+      get { return _dateTimeFormat ?? string.Empty; }
+      set { _dateTimeFormat = StringUtils.NullEmptyString(value); }
+    }
+
+    /// <summary>
+    /// Gets or sets the culture used when converting a date to and from JSON.
+    /// </summary>
+    /// <value>The culture used when converting a date to and from JSON.</value>
+    public CultureInfo Culture
+    {
+      get { return _culture ?? CultureInfo.CurrentCulture; }
+      set { _culture = value; }
+    }
+
+    /// <summary>
+    /// Writes the JSON representation of the object.
+    /// </summary>
+    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
+    /// <param name="value">The value.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+    {
+      string text;
+
+      if (value is DateTime)
+      {
+        DateTime dateTime = (DateTime)value;
+
+        if ((_dateTimeStyles & DateTimeStyles.AdjustToUniversal) == DateTimeStyles.AdjustToUniversal
+          || (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal)
+          dateTime = dateTime.ToUniversalTime();
+
+        text = dateTime.ToString(_dateTimeFormat ?? DefaultDateTimeFormat, Culture);
+      }
+#if !PocketPC && !NET20
+      else if (value is DateTimeOffset)
+      {
+        DateTimeOffset dateTimeOffset = (DateTimeOffset)value;
+        if ((_dateTimeStyles & DateTimeStyles.AdjustToUniversal) == DateTimeStyles.AdjustToUniversal
+          || (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal)
+          dateTimeOffset = dateTimeOffset.ToUniversalTime();
+
+        text = dateTimeOffset.ToString(_dateTimeFormat ?? DefaultDateTimeFormat, Culture);
+      }
+#endif
+      else
+      {
+        throw new Exception("Unexpected value when converting date. Expected DateTime or DateTimeOffset, got {0}.".FormatWith(CultureInfo.InvariantCulture, ReflectionUtils.GetObjectType(value)));
+      }
+
+      writer.WriteValue(text);
+    }
+
+    /// <summary>
+    /// Reads the JSON representation of the object.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
+    /// <param name="objectType">Type of the object.</param>
+    /// <param name="existingValue">The existing value of object being read.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    /// <returns>The object value.</returns>
+    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+    {
+      bool nullable = ReflectionUtils.IsNullableType(objectType);
+      Type t = (nullable)
+        ? Nullable.GetUnderlyingType(objectType)
+        : objectType;
+
+      if (reader.TokenType == JsonToken.Null)
+      {
+        if (!ReflectionUtils.IsNullableType(objectType))
+          throw new Exception("Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType));
+        return null;
+      }
+
+      if (reader.TokenType != JsonToken.String)
+        throw new Exception("Unexpected token parsing date. Expected String, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
+
+      string dateText = reader.Value.ToString();
+
+      if (string.IsNullOrEmpty(dateText) && nullable)
+        return null;
+
+#if !PocketPC && !NET20
+      if (t == typeof(DateTimeOffset))
+      {
+        if (!string.IsNullOrEmpty(_dateTimeFormat))
+          return DateTimeOffset.ParseExact(dateText, _dateTimeFormat, Culture, _dateTimeStyles);
+        else
+          return DateTimeOffset.Parse(dateText, Culture, _dateTimeStyles);
+      }
+#endif
+
+      if (!string.IsNullOrEmpty(_dateTimeFormat))
+        return DateTime.ParseExact(dateText, _dateTimeFormat, Culture, _dateTimeStyles);
+      else
+        return DateTime.Parse(dateText, Culture, _dateTimeStyles);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/JavaScriptDateTimeConverter.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/JavaScriptDateTimeConverter.cs
new file mode 100644 (file)
index 0000000..c59bfe8
--- /dev/null
@@ -0,0 +1,93 @@
+using System;
+using System.Globalization;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Converters
+{
+  /// <summary>
+  /// Converts a <see cref="DateTime"/> to and from a JavaScript date constructor (e.g. new Date(52231943)).
+  /// </summary>
+  public class JavaScriptDateTimeConverter : DateTimeConverterBase
+  {
+    /// <summary>
+    /// Writes the JSON representation of the object.
+    /// </summary>
+    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
+    /// <param name="value">The value.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+    {
+      long ticks;
+
+      if (value is DateTime)
+      {
+        DateTime dateTime = (DateTime)value;
+        DateTime utcDateTime = dateTime.ToUniversalTime();
+        ticks = JsonConvert.ConvertDateTimeToJavaScriptTicks(utcDateTime);
+      }
+#if !PocketPC && !NET20
+      else if (value is DateTimeOffset)
+      {
+        DateTimeOffset dateTimeOffset = (DateTimeOffset)value;
+        DateTimeOffset utcDateTimeOffset = dateTimeOffset.ToUniversalTime();
+        ticks = JsonConvert.ConvertDateTimeToJavaScriptTicks(utcDateTimeOffset.UtcDateTime);
+      }
+#endif
+      else
+      {
+        throw new Exception("Expected date object value.");
+      }
+
+      writer.WriteStartConstructor("Date");
+      writer.WriteValue(ticks);
+      writer.WriteEndConstructor();
+    }
+
+    /// <summary>
+    /// Reads the JSON representation of the object.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
+    /// <param name="objectType">Type of the object.</param>
+    /// <param name="existingValue">The existing property value of the JSON that is being converted.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    /// <returns>The object value.</returns>
+    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+    {
+      Type t = (ReflectionUtils.IsNullableType(objectType))
+        ? Nullable.GetUnderlyingType(objectType)
+        : objectType;
+
+      if (reader.TokenType == JsonToken.Null)
+      {
+        if (!ReflectionUtils.IsNullableType(objectType))
+          throw new Exception("Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType));
+
+        return null;
+      }
+
+      if (reader.TokenType != JsonToken.StartConstructor || string.Compare(reader.Value.ToString(), "Date", StringComparison.Ordinal) != 0)
+        throw new Exception("Unexpected token or value when parsing date. Token: {0}, Value: {1}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType, reader.Value));
+
+      reader.Read();
+
+      if (reader.TokenType != JsonToken.Integer)
+        throw new Exception("Unexpected token parsing date. Expected Integer, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
+
+      long ticks = (long)reader.Value;
+
+      DateTime d = JsonConvert.ConvertJavaScriptTicksToDateTime(ticks);
+
+      reader.Read();
+
+      if (reader.TokenType != JsonToken.EndConstructor)
+        throw new Exception("Unexpected token parsing date. Expected EndConstructor, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
+
+#if !PocketPC && !NET20
+      if (t == typeof(DateTimeOffset))
+        return new DateTimeOffset(d);
+#endif
+
+      return d;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/JsonDateTimeSerializationMode.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/JsonDateTimeSerializationMode.cs
new file mode 100644 (file)
index 0000000..b698f6e
--- /dev/null
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Converters
+{
+  /// <summary>
+  /// Specifies whether a DateTime object represents a local time, a Coordinated Universal Time (UTC), or is not specified as either local time or UTC.
+  /// </summary>
+  public enum JsonDateTimeSerializationMode
+  {
+    /// <summary>
+    /// The time represented is local time.
+    /// </summary>
+    Local,
+    /// <summary>
+    /// The time represented is UTC.
+    /// </summary>
+    Utc,
+    /// <summary>
+    /// The time represented is not specified as either local time or Coordinated Universal Time (UTC).
+    /// </summary>
+    Unspecified,
+    /// <summary>
+    /// Preserves the DateTimeKind field of a date when a DateTime object is converted to a string and the string is then converted back to a DateTime object.
+    /// </summary>
+    RoundtripKind
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/KeyValuePairConverter.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/KeyValuePairConverter.cs
new file mode 100644 (file)
index 0000000..e5adbc4
--- /dev/null
@@ -0,0 +1,75 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Utilities;
+using System.Reflection;
+
+namespace Newtonsoft.Json.Converters
+{
+  /// <summary>
+  /// Converts a <see cref="KeyValuePair{TKey,TValue}"/> to and from JSON.
+  /// </summary>
+  public class KeyValuePairConverter : JsonConverter
+  {
+    /// <summary>
+    /// Writes the JSON representation of the object.
+    /// </summary>
+    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
+    /// <param name="value">The value.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+    {
+      Type t = value.GetType();
+      PropertyInfo keyProperty = t.GetProperty("Key");
+      PropertyInfo valueProperty = t.GetProperty("Value");
+
+      writer.WriteStartObject();
+      writer.WritePropertyName("Key");
+      serializer.Serialize(writer, ReflectionUtils.GetMemberValue(keyProperty, value));
+      writer.WritePropertyName("Value");
+      serializer.Serialize(writer, ReflectionUtils.GetMemberValue(valueProperty, value));
+      writer.WriteEndObject();
+    }
+
+    /// <summary>
+    /// Reads the JSON representation of the object.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
+    /// <param name="objectType">Type of the object.</param>
+    /// <param name="existingValue">The existing value of object being read.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    /// <returns>The object value.</returns>
+    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+    {
+      IList<Type> genericArguments = objectType.GetGenericArguments();
+      Type keyType = genericArguments[0];
+      Type valueType = genericArguments[1];
+
+      reader.Read();
+      reader.Read();
+      object key = serializer.Deserialize(reader, keyType);
+      reader.Read();
+      reader.Read();
+      object value = serializer.Deserialize(reader, valueType);
+      reader.Read();
+
+      return ReflectionUtils.CreateInstance(objectType, key, value);
+    }
+
+    /// <summary>
+    /// Determines whether this instance can convert the specified object type.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns>
+    ///        <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
+    /// </returns>
+    public override bool CanConvert(Type objectType)
+    {
+      if (objectType.IsValueType && objectType.IsGenericType)
+        return (objectType.GetGenericTypeDefinition() == typeof (KeyValuePair<,>));
+
+      return false;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/RegexConverter.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/RegexConverter.cs
new file mode 100644 (file)
index 0000000..7735cba
--- /dev/null
@@ -0,0 +1,152 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using Newtonsoft.Json.Bson;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Converters
+{
+  /// <summary>
+  /// Converts a <see cref="Regex"/> to and from JSON and BSON.
+  /// </summary>
+  public class RegexConverter : JsonConverter
+  {
+    /// <summary>
+    /// Writes the JSON representation of the object.
+    /// </summary>
+    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
+    /// <param name="value">The value.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+    {
+      Regex regex = (Regex) value;
+
+      BsonWriter bsonWriter = writer as BsonWriter;
+      if (bsonWriter != null)
+        WriteBson(bsonWriter, regex);
+      else
+        WriteJson(writer, regex);
+    }
+
+    private bool HasFlag(RegexOptions options, RegexOptions flag)
+    {
+      return ((options & flag) == flag);
+    }
+
+    private void WriteBson(BsonWriter writer, Regex regex)
+    {
+      // Regular expression - The first cstring is the regex pattern, the second
+      // is the regex options string. Options are identified by characters, which 
+      // must be stored in alphabetical order. Valid options are 'i' for case 
+      // insensitive matching, 'm' for multiline matching, 'x' for verbose mode, 
+      // 'l' to make \w, \W, etc. locale dependent, 's' for dotall mode 
+      // ('.' matches everything), and 'u' to make \w, \W, etc. match unicode.
+
+      string options = null;
+
+      if (HasFlag(regex.Options, RegexOptions.IgnoreCase))
+        options += "i";
+
+      if (HasFlag(regex.Options, RegexOptions.Multiline))
+        options += "m";
+
+      if (HasFlag(regex.Options, RegexOptions.Singleline))
+        options += "s";
+
+      options += "u";
+
+      if (HasFlag(regex.Options, RegexOptions.ExplicitCapture))
+        options += "x";
+
+      writer.WriteRegex(regex.ToString(), options);
+    }
+
+    private void WriteJson(JsonWriter writer, Regex regex)
+    {
+      writer.WriteStartObject();
+      writer.WritePropertyName("Pattern");
+      writer.WriteValue(regex.ToString());
+      writer.WritePropertyName("Options");
+      writer.WriteValue(regex.Options);
+      writer.WriteEndObject();
+    }
+
+    /// <summary>
+    /// Reads the JSON representation of the object.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
+    /// <param name="objectType">Type of the object.</param>
+    /// <param name="existingValue">The existing value of object being read.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    /// <returns>The object value.</returns>
+    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+    {
+      BsonReader bsonReader = reader as BsonReader;
+
+      if (bsonReader != null)
+        return ReadBson(bsonReader);
+      else
+        return ReadJson(reader);
+    }
+
+    private object ReadBson(BsonReader reader)
+    {
+      string regexText = (string)reader.Value;
+      int patternOptionDelimiterIndex = regexText.LastIndexOf(@"/");
+
+      string patternText = regexText.Substring(1, patternOptionDelimiterIndex - 1);
+      string optionsText = regexText.Substring(patternOptionDelimiterIndex + 1);
+
+      RegexOptions options = RegexOptions.None;
+      foreach (char c in optionsText)
+      {
+        switch (c)
+        {
+          case 'i':
+            options |= RegexOptions.IgnoreCase;
+            break;
+          case 'm':
+            options |= RegexOptions.Multiline;
+            break;
+          case 's':
+            options |= RegexOptions.Singleline;
+            break;
+          case 'x':
+            options |= RegexOptions.ExplicitCapture;
+            break;
+        }
+      }
+
+      return new Regex(patternText, options);
+    }
+
+    private Regex ReadJson(JsonReader reader)
+    {
+      reader.Read();
+      reader.Read();
+      string pattern = (string) reader.Value;
+
+      reader.Read();
+      reader.Read();
+      int options = Convert.ToInt32(reader.Value, CultureInfo.InvariantCulture);
+
+      reader.Read();
+
+      return new Regex(pattern, (RegexOptions)options);
+    }
+
+    /// <summary>
+    /// Determines whether this instance can convert the specified object type.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns>
+    ///        <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
+    /// </returns>
+    public override bool CanConvert(Type objectType)
+    {
+      return (objectType == typeof (Regex));
+    }
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/StringEnumConverter.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/StringEnumConverter.cs
new file mode 100644 (file)
index 0000000..1c9e50e
--- /dev/null
@@ -0,0 +1,194 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.Serialization;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Converters
+{
+  /// <summary>
+  /// Converts an <see cref="Enum"/> to and from its name string value.
+  /// </summary>
+  /// <summary>
+  /// Converts an <see cref="Enum"/> to and from its name string value.
+  /// </summary>
+  public class StringEnumConverter : JsonConverter
+  {
+    private readonly Dictionary<Type, BidirectionalDictionary<string, string>> _enumMemberNamesPerType = new Dictionary<Type, BidirectionalDictionary<string, string>>();
+
+    /// <summary>
+    /// Gets or sets a value indicating whether the written enum text should be camel case.
+    /// </summary>
+    /// <value><c>true</c> if the written enum text will be camel case; otherwise, <c>false</c>.</value>
+    public bool CamelCaseText { get; set; }
+    
+    /// <summary>
+    /// Writes the JSON representation of the object.
+    /// </summary>
+    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
+    /// <param name="value">The value.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+    {
+      if (value == null)
+      {
+        writer.WriteNull();
+        return;
+      }
+
+      Enum e = (Enum)value;
+
+      string enumName = e.ToString("G");
+
+      if (char.IsNumber(enumName[0]) || enumName[0] == '-')
+      {
+        writer.WriteValue(value);
+      }
+      else
+      {
+        BidirectionalDictionary<string, string> map = GetEnumNameMap(e.GetType());
+
+        string resolvedEnumName;
+        map.TryGetByFirst(enumName, out resolvedEnumName);
+        resolvedEnumName = resolvedEnumName ?? enumName;
+
+        if (CamelCaseText)
+          resolvedEnumName = StringUtils.ToCamelCase(resolvedEnumName);
+
+        writer.WriteValue(resolvedEnumName);
+      }
+    }
+
+    /// <summary>
+    /// Reads the JSON representation of the object.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
+    /// <param name="objectType">Type of the object.</param>
+    /// <param name="existingValue">The existing value of object being read.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    /// <returns>The object value.</returns>
+    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+    {
+      Type t = (ReflectionUtils.IsNullableType(objectType))
+      ? Nullable.GetUnderlyingType(objectType)
+      : objectType;
+
+      if (reader.TokenType == JsonToken.Null)
+      {
+        if (!ReflectionUtils.IsNullableType(objectType))
+          throw new Exception("Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType));
+
+        return null;
+      }
+
+      if (reader.TokenType == JsonToken.String)
+      {
+        var map = GetEnumNameMap(t);
+        string resolvedEnumName;
+        map.TryGetBySecond(reader.Value.ToString(), out resolvedEnumName);
+        resolvedEnumName = resolvedEnumName ?? reader.Value.ToString();
+
+        return Enum.Parse(t, resolvedEnumName, true);
+      }
+
+      if (reader.TokenType == JsonToken.Integer)
+        return ConvertUtils.ConvertOrCast(reader.Value, CultureInfo.InvariantCulture, t);
+
+      throw new Exception("Unexpected token when parsing enum. Expected String or Integer, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
+    }
+
+    /// <summary>
+    /// A cached representation of the Enum string representation to respect per Enum field name.
+    /// </summary>
+    /// <param name="t">The type of the Enum.</param>
+    /// <returns>A map of enum field name to either the field name, or the configured enum member name (<see cref="EnumMemberAttribute"/>).</returns>
+    private BidirectionalDictionary<string, string> GetEnumNameMap(Type t)
+    {
+      BidirectionalDictionary<string, string> map;
+
+      if (!_enumMemberNamesPerType.TryGetValue(t, out map))
+      {
+        lock (_enumMemberNamesPerType)
+        {
+          if (_enumMemberNamesPerType.TryGetValue(t, out map))
+            return map;
+
+          map = new BidirectionalDictionary<string, string>(
+            StringComparer.OrdinalIgnoreCase,
+            StringComparer.OrdinalIgnoreCase);
+
+          foreach (FieldInfo f in t.GetFields())
+          {
+            string n1 = f.Name;
+            string n2;
+            
+#if !NET20
+            n2 = f.GetCustomAttributes(typeof (EnumMemberAttribute), true)
+                          .Cast<EnumMemberAttribute>()
+                          .Select(a => a.Value)
+                          .SingleOrDefault() ?? f.Name;
+#else
+            n2 = f.Name;
+#endif
+
+            string s;
+            if (map.TryGetBySecond(n2, out s))
+            {
+              throw new Exception("Enum name '{0}' already exists on enum '{1}'."
+                .FormatWith(CultureInfo.InvariantCulture, n2, t.Name));
+            }
+
+            map.Add(n1, n2);
+          }
+
+          _enumMemberNamesPerType[t] = map;
+        }
+      }
+
+      return map;
+    }
+
+    /// <summary>
+    /// Determines whether this instance can convert the specified object type.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns>
+    /// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
+    /// </returns>
+    public override bool CanConvert(Type objectType)
+    {
+      Type t = (ReflectionUtils.IsNullableType(objectType))
+      ? Nullable.GetUnderlyingType(objectType)
+      : objectType;
+
+      return t.IsEnum;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs
new file mode 100644 (file)
index 0000000..b864db3
--- /dev/null
@@ -0,0 +1,1520 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+#if !SILVERLIGHT || WINDOWS_PHONE
+using System;
+using System.Collections.Generic;
+using System.Xml;
+#if !NET20
+using System.Xml.Linq;
+#endif
+using Newtonsoft.Json.Utilities;
+using System.Linq;
+
+namespace Newtonsoft.Json.Converters
+{
+  #region XmlNodeWrappers
+#if !SILVERLIGHT
+  internal class XmlDocumentWrapper : XmlNodeWrapper, IXmlDocument
+  {
+    private XmlDocument _document;
+
+    public XmlDocumentWrapper(XmlDocument document)
+      : base(document)
+    {
+      _document = document;
+    }
+
+    public IXmlNode CreateComment(string data)
+    {
+      return new XmlNodeWrapper(_document.CreateComment(data));
+    }
+
+    public IXmlNode CreateTextNode(string text)
+    {
+      return new XmlNodeWrapper(_document.CreateTextNode(text));
+    }
+
+    public IXmlNode CreateCDataSection(string data)
+    {
+      return new XmlNodeWrapper(_document.CreateCDataSection(data));
+    }
+
+    public IXmlNode CreateWhitespace(string text)
+    {
+      return new XmlNodeWrapper(_document.CreateWhitespace(text));
+    }
+
+    public IXmlNode CreateSignificantWhitespace(string text)
+    {
+      return new XmlNodeWrapper(_document.CreateSignificantWhitespace(text));
+    }
+
+    public IXmlNode CreateXmlDeclaration(string version, string encoding, string standalone)
+    {
+      return new XmlNodeWrapper(_document.CreateXmlDeclaration(version, encoding, standalone));
+    }
+
+    public IXmlNode CreateProcessingInstruction(string target, string data)
+    {
+      return new XmlNodeWrapper(_document.CreateProcessingInstruction(target, data));
+    }
+
+    public IXmlElement CreateElement(string elementName)
+    {
+      return new XmlElementWrapper(_document.CreateElement(elementName));
+    }
+
+    public IXmlElement CreateElement(string qualifiedName, string namespaceURI)
+    {
+      return new XmlElementWrapper(_document.CreateElement(qualifiedName, namespaceURI));
+    }
+
+    public IXmlNode CreateAttribute(string name, string value)
+    {
+      XmlNodeWrapper attribute = new XmlNodeWrapper(_document.CreateAttribute(name));
+      attribute.Value = value;
+
+      return attribute;
+    }
+
+    public IXmlNode CreateAttribute(string qualifiedName, string namespaceURI, string value)
+    {
+      XmlNodeWrapper attribute = new XmlNodeWrapper(_document.CreateAttribute(qualifiedName, namespaceURI));
+      attribute.Value = value;
+
+      return attribute;
+    }
+
+    public IXmlElement DocumentElement
+    {
+      get
+      {
+        if (_document.DocumentElement == null)
+          return null;
+
+        return new XmlElementWrapper(_document.DocumentElement);
+      }
+    }
+  }
+
+  internal class XmlElementWrapper : XmlNodeWrapper, IXmlElement
+  {
+    private XmlElement _element;
+
+    public XmlElementWrapper(XmlElement element)
+      : base(element)
+    {
+      _element = element;
+    }
+
+    public void SetAttributeNode(IXmlNode attribute)
+    {
+      XmlNodeWrapper xmlAttributeWrapper = (XmlNodeWrapper)attribute;
+
+      _element.SetAttributeNode((XmlAttribute) xmlAttributeWrapper.WrappedNode);
+    }
+
+    public string GetPrefixOfNamespace(string namespaceURI)
+    {
+      return _element.GetPrefixOfNamespace(namespaceURI);
+    }
+  }
+
+  internal class XmlDeclarationWrapper : XmlNodeWrapper, IXmlDeclaration
+  {
+    private XmlDeclaration _declaration;
+
+    public XmlDeclarationWrapper(XmlDeclaration declaration)
+      : base(declaration)
+    {
+      _declaration = declaration;
+    }
+
+    public string Version
+    {
+      get { return _declaration.Version; }
+    }
+
+    public string Encoding
+    {
+      get { return _declaration.Encoding; }
+      set { _declaration.Encoding = value; }
+    }
+
+    public string Standalone
+    {
+      get { return _declaration.Standalone; }
+      set { _declaration.Standalone = value; }
+    }
+  }
+
+  internal class XmlNodeWrapper : IXmlNode
+  {
+    private readonly XmlNode _node;
+
+    public XmlNodeWrapper(XmlNode node)
+    {
+      _node = node;
+    }
+
+    public object WrappedNode
+    {
+      get { return _node; }
+    }
+
+    public XmlNodeType NodeType
+    {
+      get { return _node.NodeType; }
+    }
+
+    public string Name
+    {
+      get { return _node.Name; }
+    }
+
+    public string LocalName
+    {
+      get { return _node.LocalName; }
+    }
+
+    public IList<IXmlNode> ChildNodes
+    {
+      get { return _node.ChildNodes.Cast<XmlNode>().Select(n => WrapNode(n)).ToList(); }
+    }
+
+    private IXmlNode WrapNode(XmlNode node)
+    {
+      switch (node.NodeType)
+      {
+        case XmlNodeType.Element:
+          return new XmlElementWrapper((XmlElement) node);
+        case XmlNodeType.XmlDeclaration:
+          return new XmlDeclarationWrapper((XmlDeclaration) node);
+        default:
+          return new XmlNodeWrapper(node);
+      }
+    }
+
+    public IList<IXmlNode> Attributes
+    {
+      get
+      {
+        if (_node.Attributes == null)
+          return null;
+
+        return _node.Attributes.Cast<XmlAttribute>().Select(a => WrapNode(a)).ToList();
+      }
+    }
+
+    public IXmlNode ParentNode
+    {
+      get
+      {
+        XmlNode node = (_node is XmlAttribute)
+                         ? ((XmlAttribute) _node).OwnerElement
+                         : _node.ParentNode;
+        
+        if (node == null)
+          return null;
+
+        return WrapNode(node);
+      }
+    }
+
+    public string Value
+    {
+      get { return _node.Value; }
+      set { _node.Value = value; }
+    }
+
+    public IXmlNode AppendChild(IXmlNode newChild)
+    {
+      XmlNodeWrapper xmlNodeWrapper = (XmlNodeWrapper) newChild;
+      _node.AppendChild(xmlNodeWrapper._node);
+
+      return newChild;
+    }
+
+    public string Prefix
+    {
+      get { return _node.Prefix; }
+    }
+
+    public string NamespaceURI
+    {
+      get { return _node.NamespaceURI; }
+    }
+  }
+#endif
+  #endregion
+
+  #region Interfaces
+  internal interface IXmlDocument : IXmlNode
+  {
+    IXmlNode CreateComment(string text);
+    IXmlNode CreateTextNode(string text);
+    IXmlNode CreateCDataSection(string data);
+    IXmlNode CreateWhitespace(string text);
+    IXmlNode CreateSignificantWhitespace(string text);
+    IXmlNode CreateXmlDeclaration(string version, string encoding, string standalone);
+    IXmlNode CreateProcessingInstruction(string target, string data);
+    IXmlElement CreateElement(string elementName);
+    IXmlElement CreateElement(string qualifiedName, string namespaceURI);
+    IXmlNode CreateAttribute(string name, string value);
+    IXmlNode CreateAttribute(string qualifiedName, string namespaceURI, string value);
+
+    IXmlElement DocumentElement { get; }
+  }
+
+  internal interface IXmlDeclaration : IXmlNode
+  {
+    string Version { get; }
+    string Encoding { get; set; }
+    string Standalone { get; set; }
+  }
+
+  internal interface IXmlElement : IXmlNode
+  {
+    void SetAttributeNode(IXmlNode attribute);
+    string GetPrefixOfNamespace(string namespaceURI);
+  }
+
+  internal interface IXmlNode
+  {
+    XmlNodeType NodeType { get; }
+    string LocalName { get; }
+    IList<IXmlNode> ChildNodes { get; }
+    IList<IXmlNode> Attributes { get; }
+    IXmlNode ParentNode { get; }
+    string Value { get; set; }
+    IXmlNode AppendChild(IXmlNode newChild);
+    string NamespaceURI { get; }
+    object WrappedNode { get; }
+  }
+  #endregion
+
+  #region XNodeWrappers
+#if !NET20
+  internal class XDeclarationWrapper : XObjectWrapper, IXmlDeclaration
+  {
+    internal readonly XDeclaration _declaration;
+
+    public XDeclarationWrapper(XDeclaration declaration)
+      : base(null)
+    {
+      _declaration = declaration;
+    }
+
+    public override XmlNodeType NodeType
+    {
+      get { return XmlNodeType.XmlDeclaration; }
+    }
+
+    public string Version
+    {
+      get { return _declaration.Version; }
+    }
+
+    public string Encoding
+    {
+      get { return _declaration.Encoding; }
+      set { _declaration.Encoding = value; }
+    }
+
+    public string Standalone
+    {
+      get { return _declaration.Standalone; }
+      set { _declaration.Standalone = value; }
+    }
+  }
+
+  internal class XDocumentWrapper : XContainerWrapper, IXmlDocument
+  {
+    private XDocument Document
+    {
+      get { return (XDocument)WrappedNode; }
+    }
+
+    public XDocumentWrapper(XDocument document)
+      : base(document)
+    {
+    }
+
+    public override IList<IXmlNode> ChildNodes
+    {
+      get
+      {
+        IList<IXmlNode> childNodes = base.ChildNodes;
+
+        if (Document.Declaration != null)
+          childNodes.Insert(0, new XDeclarationWrapper(Document.Declaration));
+
+        return childNodes;
+      }
+    }
+
+    public IXmlNode CreateComment(string text)
+    {
+      return new XObjectWrapper(new XComment(text));
+    }
+
+    public IXmlNode CreateTextNode(string text)
+    {
+      return new XObjectWrapper(new XText(text));
+    }
+
+    public IXmlNode CreateCDataSection(string data)
+    {
+      return new XObjectWrapper(new XCData(data));
+    }
+
+    public IXmlNode CreateWhitespace(string text)
+    {
+      return new XObjectWrapper(new XText(text));
+    }
+
+    public IXmlNode CreateSignificantWhitespace(string text)
+    {
+      return new XObjectWrapper(new XText(text));
+    }
+
+    public IXmlNode CreateXmlDeclaration(string version, string encoding, string standalone)
+    {
+      return new XDeclarationWrapper(new XDeclaration(version, encoding, standalone));
+    }
+
+    public IXmlNode CreateProcessingInstruction(string target, string data)
+    {
+      return new XProcessingInstructionWrapper(new XProcessingInstruction(target, data));
+    }
+
+    public IXmlElement CreateElement(string elementName)
+    {
+      return new XElementWrapper(new XElement(elementName));
+    }
+
+    public IXmlElement CreateElement(string qualifiedName, string namespaceURI)
+    {
+      string localName = MiscellaneousUtils.GetLocalName(qualifiedName);
+      return new XElementWrapper(new XElement(XName.Get(localName, namespaceURI)));
+    }
+
+    public IXmlNode CreateAttribute(string name, string value)
+    {
+      return new XAttributeWrapper(new XAttribute(name, value));
+    }
+
+    public IXmlNode CreateAttribute(string qualifiedName, string namespaceURI, string value)
+    {
+      string localName = MiscellaneousUtils.GetLocalName(qualifiedName);
+      return new XAttributeWrapper(new XAttribute(XName.Get(localName, namespaceURI), value));
+    }
+
+    public IXmlElement DocumentElement
+    {
+      get
+      {
+        if (Document.Root == null)
+          return null;
+
+        return new XElementWrapper(Document.Root);
+      }
+    }
+
+    public override IXmlNode AppendChild(IXmlNode newChild)
+    {
+      XDeclarationWrapper declarationWrapper = newChild as XDeclarationWrapper;
+      if (declarationWrapper != null)
+      {
+        Document.Declaration = declarationWrapper._declaration;
+        return declarationWrapper;
+      }
+      else
+      {
+        return base.AppendChild(newChild);
+      }
+    }
+  }
+
+  internal class XTextWrapper : XObjectWrapper
+  {
+    private XText Text
+    {
+      get { return (XText)WrappedNode; }
+    }
+
+    public XTextWrapper(XText text)
+      : base(text)
+    {
+    }
+
+    public override string Value
+    {
+      get { return Text.Value; }
+      set { Text.Value = value; }
+    }
+
+    public override IXmlNode ParentNode
+    {
+      get
+      {
+        if (Text.Parent == null)
+          return null;
+        
+        return XContainerWrapper.WrapNode(Text.Parent);
+      }
+    }
+  }
+
+  internal class XCommentWrapper : XObjectWrapper
+  {
+    private XComment Text
+    {
+      get { return (XComment)WrappedNode; }
+    }
+
+    public XCommentWrapper(XComment text)
+      : base(text)
+    {
+    }
+
+    public override string Value
+    {
+      get { return Text.Value; }
+      set { Text.Value = value; }
+    }
+
+    public override IXmlNode ParentNode
+    {
+      get
+      {
+        if (Text.Parent == null)
+          return null;
+
+        return XContainerWrapper.WrapNode(Text.Parent);
+      }
+    }
+  }
+
+  internal class XProcessingInstructionWrapper : XObjectWrapper
+  {
+    private XProcessingInstruction ProcessingInstruction
+    {
+      get { return (XProcessingInstruction)WrappedNode; }
+    }
+
+    public XProcessingInstructionWrapper(XProcessingInstruction processingInstruction)
+      : base(processingInstruction)
+    {
+    }
+
+    public override string LocalName
+    {
+      get { return ProcessingInstruction.Target; }
+    }
+
+    public override string Value
+    {
+      get { return ProcessingInstruction.Data; }
+      set { ProcessingInstruction.Data = value; }
+    }
+  }
+
+  internal class XContainerWrapper : XObjectWrapper
+  {
+    private XContainer Container
+    {
+      get { return (XContainer)WrappedNode; }
+    }
+
+    public XContainerWrapper(XContainer container)
+      : base(container)
+    {
+    }
+
+    public override IList<IXmlNode> ChildNodes
+    {
+      get { return Container.Nodes().Select(n => WrapNode(n)).ToList(); }
+    }
+
+    public override IXmlNode ParentNode
+    {
+      get
+      {
+        if (Container.Parent == null)
+          return null;
+        
+        return WrapNode(Container.Parent);
+      }
+    }
+
+    internal static IXmlNode WrapNode(XObject node)
+    {
+      if (node is XDocument)
+        return new XDocumentWrapper((XDocument)node);
+      else if (node is XElement)
+        return new XElementWrapper((XElement)node);
+      else if (node is XContainer)
+        return new XContainerWrapper((XContainer)node);
+      else if (node is XProcessingInstruction)
+        return new XProcessingInstructionWrapper((XProcessingInstruction)node);
+      else if (node is XText)
+        return new XTextWrapper((XText)node);
+      else if (node is XComment)
+        return new XCommentWrapper((XComment)node);
+      else if (node is XAttribute)
+        return new XAttributeWrapper((XAttribute) node);
+      else
+        return new XObjectWrapper(node);
+    }
+
+    public override IXmlNode AppendChild(IXmlNode newChild)
+    {
+      Container.Add(newChild.WrappedNode);
+      return newChild;
+    }
+  }
+
+  internal class XObjectWrapper : IXmlNode
+  {
+    private readonly XObject _xmlObject;
+
+    public XObjectWrapper(XObject xmlObject)
+    {
+      _xmlObject = xmlObject;
+    }
+
+    public object WrappedNode
+    {
+      get { return _xmlObject; }
+    }
+
+    public virtual XmlNodeType NodeType
+    {
+      get { return _xmlObject.NodeType; }
+    }
+
+    public virtual string LocalName
+    {
+      get { return null; }
+    }
+
+    public virtual IList<IXmlNode> ChildNodes
+    {
+      get { return new List<IXmlNode>(); }
+    }
+
+    public virtual IList<IXmlNode> Attributes
+    {
+      get { return null; }
+    }
+
+    public virtual IXmlNode ParentNode
+    {
+      get { return null; }
+    }
+
+    public virtual string Value
+    {
+      get { return null; }
+      set { throw new InvalidOperationException(); }
+    }
+
+    public virtual IXmlNode AppendChild(IXmlNode newChild)
+    {
+      throw new InvalidOperationException();
+    }
+
+    public virtual string NamespaceURI
+    {
+      get { return null; }
+    }
+  }
+
+  internal class XAttributeWrapper : XObjectWrapper
+  {
+    private XAttribute Attribute
+    {
+      get { return (XAttribute)WrappedNode; }
+    }
+
+    public XAttributeWrapper(XAttribute attribute)
+      : base(attribute)
+    {
+    }
+
+    public override string Value
+    {
+      get { return Attribute.Value; }
+      set { Attribute.Value = value; }
+    }
+
+    public override string LocalName
+    {
+      get { return Attribute.Name.LocalName; }
+    }
+
+    public override string NamespaceURI
+    {
+      get { return Attribute.Name.NamespaceName; }
+    }
+
+    public override IXmlNode ParentNode
+    {
+      get
+      {
+        if (Attribute.Parent == null)
+          return null;
+
+        return XContainerWrapper.WrapNode(Attribute.Parent);
+      }
+    }
+  }
+
+  internal class XElementWrapper : XContainerWrapper, IXmlElement
+  {
+    private XElement Element
+    {
+      get { return (XElement) WrappedNode; }
+    }
+
+    public XElementWrapper(XElement element)
+      : base(element)
+    {
+    }
+
+    public void SetAttributeNode(IXmlNode attribute)
+    {
+      XObjectWrapper wrapper = (XObjectWrapper)attribute;
+      Element.Add(wrapper.WrappedNode);
+    }
+
+    public override IList<IXmlNode> Attributes
+    {
+      get { return Element.Attributes().Select(a => new XAttributeWrapper(a)).Cast<IXmlNode>().ToList(); }
+    }
+
+    public override string Value
+    {
+      get { return Element.Value; }
+      set { Element.Value = value; }
+    }
+
+    public override string LocalName
+    {
+      get { return Element.Name.LocalName; }
+    }
+
+    public override string NamespaceURI
+    {
+      get { return Element.Name.NamespaceName; }
+    }
+
+    public string GetPrefixOfNamespace(string namespaceURI)
+    {
+      return Element.GetPrefixOfNamespace(namespaceURI);
+    }
+  }
+#endif
+  #endregion
+
+  /// <summary>
+  /// Converts XML to and from JSON.
+  /// </summary>
+  public class XmlNodeConverter : JsonConverter
+  {
+    private const string TextName = "#text";
+    private const string CommentName = "#comment";
+    private const string CDataName = "#cdata-section";
+    private const string WhitespaceName = "#whitespace";
+    private const string SignificantWhitespaceName = "#significant-whitespace";
+    private const string DeclarationName = "?xml";
+    private const string JsonNamespaceUri = "http://james.newtonking.com/projects/json";
+
+    /// <summary>
+    /// Gets or sets the name of the root element to insert when deserializing to XML if the JSON structure has produces multiple root elements.
+    /// </summary>
+    /// <value>The name of the deserialize root element.</value>
+    public string DeserializeRootElementName { get; set; }
+
+    /// <summary>
+    /// Gets or sets a flag to indicate whether to write the Json.NET array attribute.
+    /// This attribute helps preserve arrays when converting the written XML back to JSON.
+    /// </summary>
+    /// <value><c>true</c> if the array attibute is written to the XML; otherwise, <c>false</c>.</value>
+    public bool WriteArrayAttribute { get; set; }
+
+    /// <summary>
+    /// Gets or sets a value indicating whether to write the root JSON object.
+    /// </summary>
+    /// <value><c>true</c> if the JSON root object is omitted; otherwise, <c>false</c>.</value>
+    public bool OmitRootObject { get; set; }
+
+    #region Writing
+    /// <summary>
+    /// Writes the JSON representation of the object.
+    /// </summary>
+    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    /// <param name="value">The value.</param>
+    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+    {
+      IXmlNode node = WrapXml(value);
+
+      XmlNamespaceManager manager = new XmlNamespaceManager(new NameTable());
+      PushParentNamespaces(node, manager);
+
+      if (!OmitRootObject)
+        writer.WriteStartObject();
+
+      SerializeNode(writer, node, manager, !OmitRootObject);
+      
+      if (!OmitRootObject)
+        writer.WriteEndObject();
+    }
+
+    private IXmlNode WrapXml(object value)
+    {
+#if !NET20
+      if (value is XObject)
+        return XContainerWrapper.WrapNode((XObject)value);
+#endif
+#if !SILVERLIGHT
+      if (value is XmlNode)
+        return new XmlNodeWrapper((XmlNode)value);
+#endif
+      
+      throw new ArgumentException("Value must be an XML object.", "value");
+    }
+
+    private void PushParentNamespaces(IXmlNode node, XmlNamespaceManager manager)
+    {
+      List<IXmlNode> parentElements = null;
+
+      IXmlNode parent = node;
+      while ((parent = parent.ParentNode) != null)
+      {
+        if (parent.NodeType == XmlNodeType.Element)
+        {
+          if (parentElements == null)
+            parentElements = new List<IXmlNode>();
+
+          parentElements.Add(parent);
+        }
+      }
+
+      if (parentElements != null)
+      {
+        parentElements.Reverse();
+
+        foreach (IXmlNode parentElement in parentElements)
+        {
+          manager.PushScope();
+          foreach (IXmlNode attribute in parentElement.Attributes)
+          {
+            if (attribute.NamespaceURI == "http://www.w3.org/2000/xmlns/" && attribute.LocalName != "xmlns")
+              manager.AddNamespace(attribute.LocalName, attribute.Value);
+          }
+        }
+      }
+    }
+
+    private string ResolveFullName(IXmlNode node, XmlNamespaceManager manager)
+    {
+      string prefix = (node.NamespaceURI == null || (node.LocalName == "xmlns" && node.NamespaceURI == "http://www.w3.org/2000/xmlns/"))
+                        ? null
+                        : manager.LookupPrefix(node.NamespaceURI);
+
+      if (!string.IsNullOrEmpty(prefix))
+        return prefix + ":" + node.LocalName;
+      else
+        return node.LocalName;
+    }
+
+    private string GetPropertyName(IXmlNode node, XmlNamespaceManager manager)
+    {
+      switch (node.NodeType)
+      {
+        case XmlNodeType.Attribute:
+          if (node.NamespaceURI == JsonNamespaceUri)
+            return "$" + node.LocalName;
+          else
+            return "@" + ResolveFullName(node, manager);
+        case XmlNodeType.CDATA:
+          return CDataName;
+        case XmlNodeType.Comment:
+          return CommentName;
+        case XmlNodeType.Element:
+          return ResolveFullName(node, manager);
+        case XmlNodeType.ProcessingInstruction:
+          return "?" + ResolveFullName(node, manager);
+        case XmlNodeType.XmlDeclaration:
+          return DeclarationName;
+        case XmlNodeType.SignificantWhitespace:
+          return SignificantWhitespaceName;
+        case XmlNodeType.Text:
+          return TextName;
+        case XmlNodeType.Whitespace:
+          return WhitespaceName;
+        default:
+          throw new JsonSerializationException("Unexpected XmlNodeType when getting node name: " + node.NodeType);
+      }
+    }
+
+    private bool IsArray(IXmlNode node)
+    {
+      IXmlNode jsonArrayAttribute = (node.Attributes != null)
+                                      ? node.Attributes.SingleOrDefault(a => a.LocalName == "Array" && a.NamespaceURI == JsonNamespaceUri)
+                                      : null;
+      
+      return (jsonArrayAttribute != null && XmlConvert.ToBoolean(jsonArrayAttribute.Value));
+    }
+
+    private void SerializeGroupedNodes(JsonWriter writer, IXmlNode node, XmlNamespaceManager manager, bool writePropertyName)
+    {
+      // group nodes together by name
+      Dictionary<string, List<IXmlNode>> nodesGroupedByName = new Dictionary<string, List<IXmlNode>>();
+
+      for (int i = 0; i < node.ChildNodes.Count; i++)
+      {
+        IXmlNode childNode = node.ChildNodes[i];
+        string nodeName = GetPropertyName(childNode, manager);
+
+        List<IXmlNode> nodes;
+        if (!nodesGroupedByName.TryGetValue(nodeName, out nodes))
+        {
+          nodes = new List<IXmlNode>();
+          nodesGroupedByName.Add(nodeName, nodes);
+        }
+
+        nodes.Add(childNode);
+      }
+
+      // loop through grouped nodes. write single name instances as normal,
+      // write multiple names together in an array
+      foreach (KeyValuePair<string, List<IXmlNode>> nodeNameGroup in nodesGroupedByName)
+      {
+        List<IXmlNode> groupedNodes = nodeNameGroup.Value;
+        bool writeArray;
+
+        if (groupedNodes.Count == 1)
+        {
+          writeArray = IsArray(groupedNodes[0]);
+        }
+        else
+        {
+          writeArray = true;
+        }
+
+        if (!writeArray)
+        {
+          SerializeNode(writer, groupedNodes[0], manager, writePropertyName);
+        }
+        else
+        {
+          string elementNames = nodeNameGroup.Key;
+
+          if (writePropertyName)
+            writer.WritePropertyName(elementNames);
+
+          writer.WriteStartArray();
+
+          for (int i = 0; i < groupedNodes.Count; i++)
+          {
+            SerializeNode(writer, groupedNodes[i], manager, false);
+          }
+
+          writer.WriteEndArray();
+        }
+      }
+    }
+
+    private void SerializeNode(JsonWriter writer, IXmlNode node, XmlNamespaceManager manager, bool writePropertyName)
+    {
+      switch (node.NodeType)
+      {
+        case XmlNodeType.Document:
+        case XmlNodeType.DocumentFragment:
+          SerializeGroupedNodes(writer, node, manager, writePropertyName);
+          break;
+        case XmlNodeType.Element:
+          if (IsArray(node) && node.ChildNodes.All(n => n.LocalName == node.LocalName))
+          {
+            SerializeGroupedNodes(writer, node, manager, false);
+          }
+          else
+          {
+            foreach (IXmlNode attribute in node.Attributes)
+            {
+              if (attribute.NamespaceURI == "http://www.w3.org/2000/xmlns/")
+              {
+                string prefix = (attribute.LocalName != "xmlns")
+                                  ? attribute.LocalName
+                                  : string.Empty;
+
+                manager.AddNamespace(prefix, attribute.Value);
+              }
+            }
+
+            if (writePropertyName)
+              writer.WritePropertyName(GetPropertyName(node, manager));
+
+            if (ValueAttributes(node.Attributes).Count() == 0 && node.ChildNodes.Count == 1
+                && node.ChildNodes[0].NodeType == XmlNodeType.Text)
+            {
+              // write elements with a single text child as a name value pair
+              writer.WriteValue(node.ChildNodes[0].Value);
+            }
+            else if (node.ChildNodes.Count == 0 && CollectionUtils.IsNullOrEmpty(node.Attributes))
+            {
+              // empty element
+              writer.WriteNull();
+            }
+            else
+            {
+              writer.WriteStartObject();
+
+              for (int i = 0; i < node.Attributes.Count; i++)
+              {
+                SerializeNode(writer, node.Attributes[i], manager, true);
+              }
+
+              SerializeGroupedNodes(writer, node, manager, true);
+
+              writer.WriteEndObject();
+            }
+          }
+
+          break;
+        case XmlNodeType.Comment:
+          if (writePropertyName)
+            writer.WriteComment(node.Value);
+          break;
+        case XmlNodeType.Attribute:
+        case XmlNodeType.Text:
+        case XmlNodeType.CDATA:
+        case XmlNodeType.ProcessingInstruction:
+        case XmlNodeType.Whitespace:
+        case XmlNodeType.SignificantWhitespace:
+          if (node.NamespaceURI == "http://www.w3.org/2000/xmlns/" && node.Value == JsonNamespaceUri)
+            return;
+
+          if (node.NamespaceURI == JsonNamespaceUri)
+          {
+            if (node.LocalName == "Array")
+              return;
+          }
+
+          if (writePropertyName)
+            writer.WritePropertyName(GetPropertyName(node, manager));
+          writer.WriteValue(node.Value);
+          break;
+        case XmlNodeType.XmlDeclaration:
+          IXmlDeclaration declaration = (IXmlDeclaration)node;
+          writer.WritePropertyName(GetPropertyName(node, manager));
+          writer.WriteStartObject();
+
+          if (!string.IsNullOrEmpty(declaration.Version))
+          {
+            writer.WritePropertyName("@version");
+            writer.WriteValue(declaration.Version);
+          }
+          if (!string.IsNullOrEmpty(declaration.Encoding))
+          {
+            writer.WritePropertyName("@encoding");
+            writer.WriteValue(declaration.Encoding);
+          }
+          if (!string.IsNullOrEmpty(declaration.Standalone))
+          {
+            writer.WritePropertyName("@standalone");
+            writer.WriteValue(declaration.Standalone);
+          }
+
+          writer.WriteEndObject();
+          break;
+        default:
+          throw new JsonSerializationException("Unexpected XmlNodeType when serializing nodes: " + node.NodeType);
+      }
+    }
+    #endregion
+
+    #region Reading
+    /// <summary>
+    /// Reads the JSON representation of the object.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
+    /// <param name="objectType">Type of the object.</param>
+    /// <param name="existingValue">The existing value of object being read.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    /// <returns>The object value.</returns>
+    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+    {
+      XmlNamespaceManager manager = new XmlNamespaceManager(new NameTable());
+      IXmlDocument document = null;
+      IXmlNode rootNode = null;
+
+#if !NET20
+      if (typeof(XObject).IsAssignableFrom(objectType))
+      {
+        if (objectType != typeof (XDocument) && objectType != typeof (XElement))
+          throw new JsonSerializationException("XmlNodeConverter only supports deserializing XDocument or XElement.");
+
+        XDocument d = new XDocument();
+        document = new XDocumentWrapper(d);
+        rootNode = document;
+      }
+#endif
+#if !SILVERLIGHT
+      if (typeof(XmlNode).IsAssignableFrom(objectType))
+      {
+        if (objectType != typeof (XmlDocument))
+          throw new JsonSerializationException("XmlNodeConverter only supports deserializing XmlDocuments");
+
+        XmlDocument d = new XmlDocument();
+        document = new XmlDocumentWrapper(d);
+        rootNode = document;
+      }
+#endif
+      
+      if (document == null || rootNode == null)
+        throw new JsonSerializationException("Unexpected type when converting XML: " + objectType);
+
+      if (reader.TokenType != JsonToken.StartObject)
+        throw new JsonSerializationException("XmlNodeConverter can only convert JSON that begins with an object.");
+
+      if (!string.IsNullOrEmpty(DeserializeRootElementName))
+      {
+        //rootNode = document.CreateElement(DeserializeRootElementName);
+        //document.AppendChild(rootNode);
+        ReadElement(reader, document, rootNode, DeserializeRootElementName, manager);
+      }
+      else
+      {
+        reader.Read();
+        DeserializeNode(reader, document, manager, rootNode);
+      }
+
+#if !NET20
+      if (objectType == typeof(XElement))
+      {
+        XElement element = (XElement)document.DocumentElement.WrappedNode;
+        element.Remove();
+
+        return element;
+      }
+#endif
+
+      return document.WrappedNode;
+    }
+
+    private void DeserializeValue(JsonReader reader, IXmlDocument document, XmlNamespaceManager manager, string propertyName, IXmlNode currentNode)
+    {
+      switch (propertyName)
+      {
+        case TextName:
+          currentNode.AppendChild(document.CreateTextNode(reader.Value.ToString()));
+          break;
+        case CDataName:
+          currentNode.AppendChild(document.CreateCDataSection(reader.Value.ToString()));
+          break;
+        case WhitespaceName:
+          currentNode.AppendChild(document.CreateWhitespace(reader.Value.ToString()));
+          break;
+        case SignificantWhitespaceName:
+          currentNode.AppendChild(document.CreateSignificantWhitespace(reader.Value.ToString()));
+          break;
+        default:
+          // processing instructions and the xml declaration start with ?
+          if (!string.IsNullOrEmpty(propertyName) && propertyName[0] == '?')
+          {
+            CreateInstruction(reader, document, currentNode, propertyName);
+          }
+          else
+          {
+            if (reader.TokenType == JsonToken.StartArray)
+            {
+              // handle nested arrays
+              ReadArrayElements(reader, document, propertyName, currentNode, manager);
+              return;
+            }
+
+            // have to wait until attributes have been parsed before creating element
+            // attributes may contain namespace info used by the element
+            ReadElement(reader, document, currentNode, propertyName, manager);
+          }
+          break;
+      }
+    }
+
+    private void ReadElement(JsonReader reader, IXmlDocument document, IXmlNode currentNode, string propertyName, XmlNamespaceManager manager)
+    {
+      if (string.IsNullOrEmpty(propertyName))
+        throw new JsonSerializationException("XmlNodeConverter cannot convert JSON with an empty property name to XML.");
+
+      Dictionary<string, string> attributeNameValues = ReadAttributeElements(reader, manager);
+
+      string elementPrefix = MiscellaneousUtils.GetPrefix(propertyName);
+
+      IXmlElement element = CreateElement(propertyName, document, elementPrefix, manager);
+
+      currentNode.AppendChild(element);
+
+      // add attributes to newly created element
+      foreach (KeyValuePair<string, string> nameValue in attributeNameValues)
+      {
+        string attributePrefix = MiscellaneousUtils.GetPrefix(nameValue.Key);
+
+        IXmlNode attribute = (!string.IsNullOrEmpty(attributePrefix))
+                               ? document.CreateAttribute(nameValue.Key, manager.LookupNamespace(attributePrefix), nameValue.Value)
+                               : document.CreateAttribute(nameValue.Key, nameValue.Value);
+
+        element.SetAttributeNode(attribute);
+      }
+
+      if (reader.TokenType == JsonToken.String)
+      {
+        element.AppendChild(document.CreateTextNode(reader.Value.ToString()));
+      }
+      else if (reader.TokenType == JsonToken.Integer)
+      {
+        element.AppendChild(document.CreateTextNode(XmlConvert.ToString((long)reader.Value)));
+      }
+      else if (reader.TokenType == JsonToken.Float)
+      {
+        element.AppendChild(document.CreateTextNode(XmlConvert.ToString((double)reader.Value)));
+      }
+      else if (reader.TokenType == JsonToken.Boolean)
+      {
+        element.AppendChild(document.CreateTextNode(XmlConvert.ToString((bool)reader.Value)));
+      }
+      else if (reader.TokenType == JsonToken.Date)
+      {
+        DateTime d = (DateTime)reader.Value;
+        element.AppendChild(document.CreateTextNode(XmlConvert.ToString(d, DateTimeUtils.ToSerializationMode(d.Kind))));
+      }
+      else if (reader.TokenType == JsonToken.Null)
+      {
+        // empty element. do nothing
+      }
+      else
+      {
+        // finished element will have no children to deserialize
+        if (reader.TokenType != JsonToken.EndObject)
+        {
+          manager.PushScope();
+
+          DeserializeNode(reader, document, manager, element);
+
+          manager.PopScope();
+        }
+      }
+    }
+
+    private void ReadArrayElements(JsonReader reader, IXmlDocument document, string propertyName, IXmlNode currentNode, XmlNamespaceManager manager)
+    {
+      string elementPrefix = MiscellaneousUtils.GetPrefix(propertyName);
+
+      IXmlElement nestedArrayElement = CreateElement(propertyName, document, elementPrefix, manager);
+
+      currentNode.AppendChild(nestedArrayElement);
+
+      int count = 0;
+      while (reader.Read() && reader.TokenType != JsonToken.EndArray)
+      {
+        DeserializeValue(reader, document, manager, propertyName, nestedArrayElement);
+        count++;
+      }
+
+      if (WriteArrayAttribute)
+      {
+        AddJsonArrayAttribute(nestedArrayElement, document);
+      }
+
+      if (count == 1 && WriteArrayAttribute)
+      {
+        IXmlElement arrayElement = nestedArrayElement.ChildNodes.CastValid<IXmlElement>().Single(n => n.LocalName == propertyName);
+        AddJsonArrayAttribute(arrayElement, document);
+      }
+    }
+
+    private void AddJsonArrayAttribute(IXmlElement element, IXmlDocument document)
+    {
+      element.SetAttributeNode(document.CreateAttribute("json:Array", JsonNamespaceUri, "true"));
+
+#if !NET20
+      // linq to xml doesn't automatically include prefixes via the namespace manager
+      if (element is XElementWrapper)
+      {
+        if (element.GetPrefixOfNamespace(JsonNamespaceUri) == null)
+        {
+          element.SetAttributeNode(document.CreateAttribute("xmlns:json", "http://www.w3.org/2000/xmlns/", JsonNamespaceUri));
+        }
+      }
+#endif
+    }
+
+    private Dictionary<string, string> ReadAttributeElements(JsonReader reader, XmlNamespaceManager manager)
+    {
+      Dictionary<string, string> attributeNameValues = new Dictionary<string, string>();
+      bool finishedAttributes = false;
+      bool finishedElement = false;
+
+      // a string token means the element only has a single text child
+      if (reader.TokenType != JsonToken.String
+          && reader.TokenType != JsonToken.Null
+          && reader.TokenType != JsonToken.Boolean
+          && reader.TokenType != JsonToken.Integer
+          && reader.TokenType != JsonToken.Float
+          && reader.TokenType != JsonToken.Date
+          && reader.TokenType != JsonToken.StartConstructor)
+      {
+        // read properties until first non-attribute is encountered
+        while (!finishedAttributes && !finishedElement && reader.Read())
+        {
+          switch (reader.TokenType)
+          {
+            case JsonToken.PropertyName:
+              string attributeName = reader.Value.ToString();
+              string attributeValue;
+
+              if (!string.IsNullOrEmpty(attributeName))
+              {
+                char firstChar = attributeName[0];
+
+                switch (firstChar)
+                {
+                  case '@':
+                    attributeName = attributeName.Substring(1);
+                    reader.Read();
+                    attributeValue = reader.Value.ToString();
+                    attributeNameValues.Add(attributeName, attributeValue);
+
+                    string namespacePrefix;
+                    if (IsNamespaceAttribute(attributeName, out namespacePrefix))
+                    {
+                      manager.AddNamespace(namespacePrefix, attributeValue);
+                    }
+                    break;
+                  case '$':
+                    attributeName = attributeName.Substring(1);
+                    reader.Read();
+                    attributeValue = reader.Value.ToString();
+
+                    // check that JsonNamespaceUri is in scope
+                    // if it isn't then add it to document and namespace manager
+                    string jsonPrefix = manager.LookupPrefix(JsonNamespaceUri);
+                    if (jsonPrefix == null)
+                    {
+                      // ensure that the prefix used is free
+                      int? i = null;
+                      while (manager.LookupNamespace("json" + i) != null)
+                      {
+                        i = i.GetValueOrDefault() + 1;
+                      }
+                      jsonPrefix = "json" + i;
+
+                      attributeNameValues.Add("xmlns:" + jsonPrefix, JsonNamespaceUri);
+                      manager.AddNamespace(jsonPrefix, JsonNamespaceUri);
+                    }
+
+                    attributeNameValues.Add(jsonPrefix + ":" + attributeName, attributeValue);
+                    break;
+                  default:
+                    finishedAttributes = true;
+                    break;
+                }
+              }
+              else
+              {
+                finishedAttributes = true;
+              }
+
+              break;
+            case JsonToken.EndObject:
+              finishedElement = true;
+              break;
+            default:
+              throw new JsonSerializationException("Unexpected JsonToken: " + reader.TokenType);
+          }
+        }
+      }
+
+      return attributeNameValues;
+    }
+
+    private void CreateInstruction(JsonReader reader, IXmlDocument document, IXmlNode currentNode, string propertyName)
+    {
+      if (propertyName == DeclarationName)
+      {
+        string version = null;
+        string encoding = null;
+        string standalone = null;
+        while (reader.Read() && reader.TokenType != JsonToken.EndObject)
+        {
+          switch (reader.Value.ToString())
+          {
+            case "@version":
+              reader.Read();
+              version = reader.Value.ToString();
+              break;
+            case "@encoding":
+              reader.Read();
+              encoding = reader.Value.ToString();
+              break;
+            case "@standalone":
+              reader.Read();
+              standalone = reader.Value.ToString();
+              break;
+            default:
+              throw new JsonSerializationException("Unexpected property name encountered while deserializing XmlDeclaration: " + reader.Value);
+          }
+        }
+
+        IXmlNode declaration = document.CreateXmlDeclaration(version, encoding, standalone);
+        currentNode.AppendChild(declaration);
+      }
+      else
+      {
+        IXmlNode instruction = document.CreateProcessingInstruction(propertyName.Substring(1), reader.Value.ToString());
+        currentNode.AppendChild(instruction);
+      }
+    }
+
+    private IXmlElement CreateElement(string elementName, IXmlDocument document, string elementPrefix, XmlNamespaceManager manager)
+    {
+      return (!string.IsNullOrEmpty(elementPrefix))
+               ? document.CreateElement(elementName, manager.LookupNamespace(elementPrefix))
+               : document.CreateElement(elementName);
+    }
+
+    private void DeserializeNode(JsonReader reader, IXmlDocument document, XmlNamespaceManager manager, IXmlNode currentNode)
+    {
+      do
+      {
+        switch (reader.TokenType)
+        {
+          case JsonToken.PropertyName:
+            if (currentNode.NodeType == XmlNodeType.Document && document.DocumentElement != null)
+              throw new JsonSerializationException("JSON root object has multiple properties. The root object must have a single property in order to create a valid XML document. Consider specifing a DeserializeRootElementName.");
+
+            string propertyName = reader.Value.ToString();
+            reader.Read();
+
+            if (reader.TokenType == JsonToken.StartArray)
+            {
+              int count = 0;
+              while (reader.Read() && reader.TokenType != JsonToken.EndArray)
+              {
+                DeserializeValue(reader, document, manager, propertyName, currentNode);
+                count++;
+              }
+
+              if (count == 1 && WriteArrayAttribute)
+              {
+                IXmlElement arrayElement = currentNode.ChildNodes.CastValid<IXmlElement>().Single(n => n.LocalName == propertyName);
+                AddJsonArrayAttribute(arrayElement, document);
+              }
+            }
+            else
+            {
+              DeserializeValue(reader, document, manager, propertyName, currentNode);
+            }
+            break;
+          case JsonToken.StartConstructor:
+            string constructorName = reader.Value.ToString();
+
+            while (reader.Read() && reader.TokenType != JsonToken.EndConstructor)
+            {
+              DeserializeValue(reader, document, manager, constructorName, currentNode);
+            }
+            break;
+          case JsonToken.Comment:
+            currentNode.AppendChild(document.CreateComment((string)reader.Value));
+            break;
+          case JsonToken.EndObject:
+          case JsonToken.EndArray:
+            return;
+          default:
+            throw new JsonSerializationException("Unexpected JsonToken when deserializing node: " + reader.TokenType);
+        }
+      } while (reader.TokenType == JsonToken.PropertyName || reader.Read());
+      // don't read if current token is a property. token was already read when parsing element attributes
+    }
+
+    /// <summary>
+    /// Checks if the attributeName is a namespace attribute.
+    /// </summary>
+    /// <param name="attributeName">Attribute name to test.</param>
+    /// <param name="prefix">The attribute name prefix if it has one, otherwise an empty string.</param>
+    /// <returns>True if attribute name is for a namespace attribute, otherwise false.</returns>
+    private bool IsNamespaceAttribute(string attributeName, out string prefix)
+    {
+      if (attributeName.StartsWith("xmlns", StringComparison.Ordinal))
+      {
+        if (attributeName.Length == 5)
+        {
+          prefix = string.Empty;
+          return true;
+        }
+        else if (attributeName[5] == ':')
+        {
+          prefix = attributeName.Substring(6, attributeName.Length - 6);
+          return true;
+        }
+      }
+      prefix = null;
+      return false;
+    }
+
+    private IEnumerable<IXmlNode> ValueAttributes(IEnumerable<IXmlNode> c)
+    {
+      return c.Where(a => a.NamespaceURI != JsonNamespaceUri);
+    }
+    #endregion
+
+    /// <summary>
+    /// Determines whether this instance can convert the specified value type.
+    /// </summary>
+    /// <param name="valueType">Type of the value.</param>
+    /// <returns>
+    ///        <c>true</c> if this instance can convert the specified value type; otherwise, <c>false</c>.
+    /// </returns>
+    public override bool CanConvert(Type valueType)
+    {
+#if !NET20
+      if (typeof(XObject).IsAssignableFrom(valueType))
+        return true;
+#endif
+#if !SILVERLIGHT
+      if (typeof(XmlNode).IsAssignableFrom(valueType))
+        return true;
+#endif
+
+      return false;
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/DefaultValueHandling.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/DefaultValueHandling.cs
new file mode 100644 (file)
index 0000000..43bacdb
--- /dev/null
@@ -0,0 +1,47 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Specifies default value handling options for the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public enum DefaultValueHandling
+  {
+    /// <summary>
+    /// Include default values when serializing and deserializing objects.
+    /// </summary>
+    Include = 0,
+    /// <summary>
+    /// Ignore default values when serializing and deserializing objects.
+    /// </summary>
+    Ignore = 1
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Dynamic.snk b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Dynamic.snk
new file mode 100644 (file)
index 0000000..2225208
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Dynamic.snk differ
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/FormatterAssemblyStyle.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/FormatterAssemblyStyle.cs
new file mode 100644 (file)
index 0000000..d0675bb
--- /dev/null
@@ -0,0 +1,19 @@
+#if SILVERLIGHT || PocketPC
+namespace System.Runtime.Serialization.Formatters
+{
+  /// <summary>
+  /// Indicates the method that will be used during deserialization for locating and loading assemblies.
+  /// </summary>
+  public enum FormatterAssemblyStyle
+  {
+    /// <summary>
+    /// In simple mode, the assembly used during deserialization need not match exactly the assembly used during serialization. Specifically, the version numbers need not match as the LoadWithPartialName method is used to load the assembly.
+    /// </summary>
+    Simple,
+    /// <summary>
+    /// In full mode, the assembly used during deserialization must match exactly the assembly used during serialization. The Load method of the Assembly class is used to load the assembly.
+    /// </summary>
+    Full
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/IJsonLineInfo.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/IJsonLineInfo.cs
new file mode 100644 (file)
index 0000000..7077b48
--- /dev/null
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Provides an interface to enable a class to return line and position information.
+  /// </summary>
+  public interface IJsonLineInfo
+  {
+    /// <summary>
+    /// Gets a value indicating whether the class can return line information.
+    /// </summary>
+    /// <returns>
+    ///        <c>true</c> if LineNumber and LinePosition can be provided; otherwise, <c>false</c>.
+    /// </returns>
+    bool HasLineInfo();
+
+    /// <summary>
+    /// Gets the current line number.
+    /// </summary>
+    /// <value>The current line number or 0 if no line information is available (for example, HasLineInfo returns false).</value>
+    int LineNumber { get; }
+    /// <summary>
+    /// Gets the current line position.
+    /// </summary>
+    /// <value>The current line position or 0 if no line information is available (for example, HasLineInfo returns false).</value>
+    int LinePosition { get; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonArrayAttribute.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonArrayAttribute.cs
new file mode 100644 (file)
index 0000000..689293b
--- /dev/null
@@ -0,0 +1,76 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Instructs the <see cref="JsonSerializer"/> how to serialize the collection.
+  /// </summary>
+  [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
+  public sealed class JsonArrayAttribute : JsonContainerAttribute
+  {
+    private bool _allowNullItems;
+
+    /// <summary>
+    /// Gets or sets a value indicating whether null items are allowed in the collection.
+    /// </summary>
+    /// <value><c>true</c> if null items are allowed in the collection; otherwise, <c>false</c>.</value>
+    public bool AllowNullItems
+    {
+      get { return _allowNullItems; }
+      set { _allowNullItems = value; }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonArrayAttribute"/> class.
+    /// </summary>
+    public JsonArrayAttribute()
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonObjectAttribute"/> class with a flag indicating whether the array can contain null items
+    /// </summary>
+    /// <param name="allowNullItems">A flag indicating whether the array can contain null items.</param>
+    public JsonArrayAttribute(bool allowNullItems)
+    {
+      _allowNullItems = allowNullItems;
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonArrayAttribute"/> class with the specified container Id.
+    /// </summary>
+    /// <param name="id">The container Id.</param>
+    public JsonArrayAttribute(string id)
+      : base(id)
+    {
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonConstructorAttribute.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonConstructorAttribute.cs
new file mode 100644 (file)
index 0000000..9f68563
--- /dev/null
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Instructs the <see cref="JsonSerializer"/> not to serialize the public field or public read/write property value.
+  /// </summary>
+  [AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Property, AllowMultiple = false)]
+  public sealed class JsonConstructorAttribute : Attribute
+  {
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonContainerAttribute.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonContainerAttribute.cs
new file mode 100644 (file)
index 0000000..779cb3e
--- /dev/null
@@ -0,0 +1,87 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Instructs the <see cref="JsonSerializer"/> how to serialize the object.
+  /// </summary>
+  [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
+  public abstract class JsonContainerAttribute : Attribute
+  {
+    /// <summary>
+    /// Gets or sets the id.
+    /// </summary>
+    /// <value>The id.</value>
+    public string Id { get; set; }
+    /// <summary>
+    /// Gets or sets the title.
+    /// </summary>
+    /// <value>The title.</value>
+    public string Title { get; set; }
+    /// <summary>
+    /// Gets or sets the description.
+    /// </summary>
+    /// <value>The description.</value>
+    public string Description { get; set; }
+
+    // yuck. can't set nullable properties on an attribute in C#
+    // have to use this approach to get an unset default state
+    internal bool? _isReference;
+
+    /// <summary>
+    /// Gets or sets a value that indicates whether to preserve object reference data.
+    /// </summary>
+    /// <value>
+    ///        <c>true</c> to keep object reference; otherwise, <c>false</c>. The default is <c>false</c>.
+    /// </value>
+    public bool IsReference
+    {
+      get { return _isReference ?? default(bool); }
+      set { _isReference = value; }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonContainerAttribute"/> class.
+    /// </summary>
+    protected JsonContainerAttribute()
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonContainerAttribute"/> class with the specified container Id.
+    /// </summary>
+    /// <param name="id">The container Id.</param>
+    protected JsonContainerAttribute(string id)
+    {
+      Id = id;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonConvert.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonConvert.cs
new file mode 100644 (file)
index 0000000..90d1ec2
--- /dev/null
@@ -0,0 +1,920 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.IO;
+using System.Globalization;
+using Newtonsoft.Json.Utilities;
+using System.Xml;
+using Newtonsoft.Json.Converters;
+using System.Text;
+#if !NET20 && (!SILVERLIGHT || WINDOWS_PHONE)
+using System.Xml.Linq;
+#endif
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Provides methods for converting between common language runtime types and JSON types.
+  /// </summary>
+  public static class JsonConvert
+  {
+    /// <summary>
+    /// Represents JavaScript's boolean value true as a string. This field is read-only.
+    /// </summary>
+    public static readonly string True = "true";
+
+    /// <summary>
+    /// Represents JavaScript's boolean value false as a string. This field is read-only.
+    /// </summary>
+    public static readonly string False = "false";
+
+    /// <summary>
+    /// Represents JavaScript's null as a string. This field is read-only.
+    /// </summary>
+    public static readonly string Null = "null";
+
+    /// <summary>
+    /// Represents JavaScript's undefined as a string. This field is read-only.
+    /// </summary>
+    public static readonly string Undefined = "undefined";
+
+    /// <summary>
+    /// Represents JavaScript's positive infinity as a string. This field is read-only.
+    /// </summary>
+    public static readonly string PositiveInfinity = "Infinity";
+
+    /// <summary>
+    /// Represents JavaScript's negative infinity as a string. This field is read-only.
+    /// </summary>
+    public static readonly string NegativeInfinity = "-Infinity";
+
+    /// <summary>
+    /// Represents JavaScript's NaN as a string. This field is read-only.
+    /// </summary>
+    public static readonly string NaN = "NaN";
+
+    internal static readonly long InitialJavaScriptDateTicks = 621355968000000000;
+
+    /// <summary>
+    /// Converts the <see cref="DateTime"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="DateTime"/>.</returns>
+    public static string ToString(DateTime value)
+    {
+      using (StringWriter writer = StringUtils.CreateStringWriter(64))
+      {
+        WriteDateTimeString(writer, value, GetUtcOffset(value), value.Kind);
+        return writer.ToString();
+      }
+    }
+
+#if !PocketPC && !NET20
+    /// <summary>
+    /// Converts the <see cref="DateTimeOffset"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="DateTimeOffset"/>.</returns>
+    public static string ToString(DateTimeOffset value)
+    {
+      using (StringWriter writer = StringUtils.CreateStringWriter(64))
+      {
+        WriteDateTimeString(writer, value.UtcDateTime, value.Offset, DateTimeKind.Local);
+        return writer.ToString();
+      }
+    }
+#endif
+
+    private static TimeSpan GetUtcOffset(DateTime dateTime)
+    {
+#if SILVERLIGHT
+      return TimeZoneInfo.Local.GetUtcOffset(dateTime);
+#else
+      return TimeZone.CurrentTimeZone.GetUtcOffset(dateTime);
+#endif
+    }
+
+    internal static void WriteDateTimeString(TextWriter writer, DateTime value)
+    {
+      WriteDateTimeString(writer, value, GetUtcOffset(value), value.Kind);
+    }
+
+    internal static void WriteDateTimeString(TextWriter writer, DateTime value, TimeSpan offset, DateTimeKind kind)
+    {
+      long javaScriptTicks = ConvertDateTimeToJavaScriptTicks(value, offset);
+
+      writer.Write(@"""\/Date(");
+      writer.Write(javaScriptTicks);
+      
+      switch (kind)
+      {
+        case DateTimeKind.Local:
+        case DateTimeKind.Unspecified:
+          writer.Write((offset.Ticks >= 0L) ? "+" : "-");
+
+          int absHours = Math.Abs(offset.Hours);
+          if (absHours < 10)
+            writer.Write(0);
+          writer.Write(absHours);
+          int absMinutes = Math.Abs(offset.Minutes);
+          if (absMinutes < 10)
+            writer.Write(0);
+          writer.Write(absMinutes);
+          break;
+      }
+
+      writer.Write(@")\/""");
+    }
+
+    private static long ToUniversalTicks(DateTime dateTime)
+    {
+      if (dateTime.Kind == DateTimeKind.Utc)
+        return dateTime.Ticks;
+
+      return ToUniversalTicks(dateTime, GetUtcOffset(dateTime));
+    }
+
+    private static long ToUniversalTicks(DateTime dateTime, TimeSpan offset)
+    {
+      if (dateTime.Kind == DateTimeKind.Utc)
+        return dateTime.Ticks;
+
+      long ticks = dateTime.Ticks - offset.Ticks;
+      if (ticks > 3155378975999999999L)
+        return 3155378975999999999L;
+
+      if (ticks < 0L)
+        return 0L;
+
+      return ticks;
+    }
+
+    internal static long ConvertDateTimeToJavaScriptTicks(DateTime dateTime, TimeSpan offset)
+    {
+      long universialTicks = ToUniversalTicks(dateTime, offset);
+
+      return UniversialTicksToJavaScriptTicks(universialTicks);
+    }
+
+    internal static long ConvertDateTimeToJavaScriptTicks(DateTime dateTime)
+    {
+      return ConvertDateTimeToJavaScriptTicks(dateTime, true);
+    }
+
+    internal static long ConvertDateTimeToJavaScriptTicks(DateTime dateTime, bool convertToUtc)
+    {
+      long ticks = (convertToUtc) ? ToUniversalTicks(dateTime) : dateTime.Ticks;
+
+      return UniversialTicksToJavaScriptTicks(ticks);
+    }
+
+    private static long UniversialTicksToJavaScriptTicks(long universialTicks)
+    {
+      long javaScriptTicks = (universialTicks - InitialJavaScriptDateTicks) / 10000;
+
+      return javaScriptTicks;
+    }
+
+    internal static DateTime ConvertJavaScriptTicksToDateTime(long javaScriptTicks)
+    {
+      DateTime dateTime = new DateTime((javaScriptTicks * 10000) + InitialJavaScriptDateTicks, DateTimeKind.Utc);
+
+      return dateTime;
+    }
+
+    /// <summary>
+    /// Converts the <see cref="Boolean"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="Boolean"/>.</returns>
+    public static string ToString(bool value)
+    {
+      return (value) ? True : False;
+    }
+
+    /// <summary>
+    /// Converts the <see cref="Char"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="Char"/>.</returns>
+    public static string ToString(char value)
+    {
+      return ToString(char.ToString(value));
+    }
+
+    /// <summary>
+    /// Converts the <see cref="Enum"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="Enum"/>.</returns>
+    public static string ToString(Enum value)
+    {
+      return value.ToString("D");
+    }
+
+    /// <summary>
+    /// Converts the <see cref="Int32"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="Int32"/>.</returns>
+    public static string ToString(int value)
+    {
+      return value.ToString(null, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Converts the <see cref="Int16"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="Int16"/>.</returns>
+    public static string ToString(short value)
+    {
+      return value.ToString(null, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Converts the <see cref="UInt16"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="UInt16"/>.</returns>
+    [CLSCompliant(false)]
+    public static string ToString(ushort value)
+    {
+      return value.ToString(null, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Converts the <see cref="UInt32"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="UInt32"/>.</returns>
+    [CLSCompliant(false)]
+    public static string ToString(uint value)
+    {
+      return value.ToString(null, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Converts the <see cref="Int64"/>  to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="Int64"/>.</returns>
+    public static string ToString(long value)
+    {
+      return value.ToString(null, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Converts the <see cref="UInt64"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="UInt64"/>.</returns>
+    [CLSCompliant(false)]
+    public static string ToString(ulong value)
+    {
+      return value.ToString(null, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Converts the <see cref="Single"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="Single"/>.</returns>
+    public static string ToString(float value)
+    {
+      return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture));
+    }
+
+    /// <summary>
+    /// Converts the <see cref="Double"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="Double"/>.</returns>
+    public static string ToString(double value)
+    {
+      return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture));
+    }
+
+    private static string EnsureDecimalPlace(double value, string text)
+    {
+      if (double.IsNaN(value) || double.IsInfinity(value) || text.IndexOf('.') != -1 || text.IndexOf('E') != -1)
+        return text;
+
+      return text + ".0";
+    }
+
+    private static string EnsureDecimalPlace(string text)
+    {
+      if (text.IndexOf('.') != -1)
+        return text;
+
+      return text + ".0";
+    }
+
+    /// <summary>
+    /// Converts the <see cref="Byte"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="Byte"/>.</returns>
+    public static string ToString(byte value)
+    {
+      return value.ToString(null, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Converts the <see cref="SByte"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="SByte"/>.</returns>
+    [CLSCompliant(false)]
+    public static string ToString(sbyte value)
+    {
+      return value.ToString(null, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Converts the <see cref="Decimal"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="SByte"/>.</returns>
+    public static string ToString(decimal value)
+    {
+      return EnsureDecimalPlace(value.ToString(null, CultureInfo.InvariantCulture));
+    }
+
+    /// <summary>
+    /// Converts the <see cref="Guid"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="Guid"/>.</returns>
+    public static string ToString(Guid value)
+    {
+      return '"' + value.ToString("D", CultureInfo.InvariantCulture) + '"';
+    }
+
+    /// <summary>
+    /// Converts the <see cref="String"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="String"/>.</returns>
+    public static string ToString(string value)
+    {
+      return ToString(value, '"');
+    }
+
+    /// <summary>
+    /// Converts the <see cref="String"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <param name="delimter">The string delimiter character.</param>
+    /// <returns>A JSON string representation of the <see cref="String"/>.</returns>
+    public static string ToString(string value, char delimter)
+    {
+      return JavaScriptUtils.ToEscapedJavaScriptString(value, delimter, true);
+    }
+
+    /// <summary>
+    /// Converts the <see cref="Object"/> to its JSON string representation.
+    /// </summary>
+    /// <param name="value">The value to convert.</param>
+    /// <returns>A JSON string representation of the <see cref="Object"/>.</returns>
+    public static string ToString(object value)
+    {
+      if (value == null)
+        return Null;
+
+      IConvertible convertible = value as IConvertible;
+
+      if (convertible != null)
+      {
+        switch (convertible.GetTypeCode())
+        {
+          case TypeCode.String:
+            return ToString(convertible.ToString(CultureInfo.InvariantCulture));
+          case TypeCode.Char:
+            return ToString(convertible.ToChar(CultureInfo.InvariantCulture));
+          case TypeCode.Boolean:
+            return ToString(convertible.ToBoolean(CultureInfo.InvariantCulture));
+          case TypeCode.SByte:
+            return ToString(convertible.ToSByte(CultureInfo.InvariantCulture));
+          case TypeCode.Int16:
+            return ToString(convertible.ToInt16(CultureInfo.InvariantCulture));
+          case TypeCode.UInt16:
+            return ToString(convertible.ToUInt16(CultureInfo.InvariantCulture));
+          case TypeCode.Int32:
+            return ToString(convertible.ToInt32(CultureInfo.InvariantCulture));
+          case TypeCode.Byte:
+            return ToString(convertible.ToByte(CultureInfo.InvariantCulture));
+          case TypeCode.UInt32:
+            return ToString(convertible.ToUInt32(CultureInfo.InvariantCulture));
+          case TypeCode.Int64:
+            return ToString(convertible.ToInt64(CultureInfo.InvariantCulture));
+          case TypeCode.UInt64:
+            return ToString(convertible.ToUInt64(CultureInfo.InvariantCulture));
+          case TypeCode.Single:
+            return ToString(convertible.ToSingle(CultureInfo.InvariantCulture));
+          case TypeCode.Double:
+            return ToString(convertible.ToDouble(CultureInfo.InvariantCulture));
+          case TypeCode.DateTime:
+            return ToString(convertible.ToDateTime(CultureInfo.InvariantCulture));
+          case TypeCode.Decimal:
+            return ToString(convertible.ToDecimal(CultureInfo.InvariantCulture));
+          case TypeCode.DBNull:
+            return Null;
+        }
+      }
+#if !PocketPC && !NET20
+      else if (value is DateTimeOffset)
+      {
+        return ToString((DateTimeOffset)value);
+      }
+#endif
+
+      throw new ArgumentException("Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType()));
+    }
+
+    private static bool IsJsonPrimitiveTypeCode(TypeCode typeCode)
+    {
+      switch (typeCode)
+      {
+        case TypeCode.String:
+        case TypeCode.Char:
+        case TypeCode.Boolean:
+        case TypeCode.SByte:
+        case TypeCode.Int16:
+        case TypeCode.UInt16:
+        case TypeCode.Int32:
+        case TypeCode.Byte:
+        case TypeCode.UInt32:
+        case TypeCode.Int64:
+        case TypeCode.UInt64:
+        case TypeCode.Single:
+        case TypeCode.Double:
+        case TypeCode.DateTime:
+        case TypeCode.Decimal:
+        case TypeCode.DBNull:
+          return true;
+        default:
+          return false;
+      }
+    }
+
+    internal static bool IsJsonPrimitiveType(Type type)
+    {
+      if (ReflectionUtils.IsNullableType(type))
+        type = Nullable.GetUnderlyingType(type);
+
+#if !PocketPC && !NET20
+     if (type == typeof(DateTimeOffset))
+        return true;
+#endif
+      if (type == typeof(byte[]))
+        return true;
+
+      return IsJsonPrimitiveTypeCode(Type.GetTypeCode(type));
+    }
+
+    internal static bool IsJsonPrimitive(object value)
+    {
+      if (value == null)
+        return true;
+
+      IConvertible convertible = value as IConvertible;
+
+      if (convertible != null)
+        return IsJsonPrimitiveTypeCode(convertible.GetTypeCode());
+
+#if !PocketPC && !NET20
+      if (value is DateTimeOffset)
+        return true;
+#endif
+
+      if (value is byte[])
+        return true;
+
+      return false;
+    }
+
+    /// <summary>
+    /// Serializes the specified object to a JSON string.
+    /// </summary>
+    /// <param name="value">The object to serialize.</param>
+    /// <returns>A JSON string representation of the object.</returns>
+    public static string SerializeObject(object value)
+    {
+      return SerializeObject(value, Formatting.None, (JsonSerializerSettings)null);
+    }
+
+    /// <summary>
+    /// Serializes the specified object to a JSON string.
+    /// </summary>
+    /// <param name="value">The object to serialize.</param>
+    /// <param name="formatting">Indicates how the output is formatted.</param>
+    /// <returns>
+    /// A JSON string representation of the object.
+    /// </returns>
+    public static string SerializeObject(object value, Formatting formatting)
+    {
+      return SerializeObject(value, formatting, (JsonSerializerSettings)null);
+    }
+
+    /// <summary>
+    /// Serializes the specified object to a JSON string using a collection of <see cref="JsonConverter"/>.
+    /// </summary>
+    /// <param name="value">The object to serialize.</param>
+    /// <param name="converters">A collection converters used while serializing.</param>
+    /// <returns>A JSON string representation of the object.</returns>
+    public static string SerializeObject(object value, params JsonConverter[] converters)
+    {
+      return SerializeObject(value, Formatting.None, converters);
+    }
+
+    /// <summary>
+    /// Serializes the specified object to a JSON string using a collection of <see cref="JsonConverter"/>.
+    /// </summary>
+    /// <param name="value">The object to serialize.</param>
+    /// <param name="formatting">Indicates how the output is formatted.</param>
+    /// <param name="converters">A collection converters used while serializing.</param>
+    /// <returns>A JSON string representation of the object.</returns>
+    public static string SerializeObject(object value, Formatting formatting, params JsonConverter[] converters)
+    {
+      JsonSerializerSettings settings = (converters != null && converters.Length > 0)
+        ? new JsonSerializerSettings { Converters = converters }
+        : null;
+
+      return SerializeObject(value, formatting, settings);
+    }
+
+    /// <summary>
+    /// Serializes the specified object to a JSON string using a collection of <see cref="JsonConverter"/>.
+    /// </summary>
+    /// <param name="value">The object to serialize.</param>
+    /// <param name="formatting">Indicates how the output is formatted.</param>
+    /// <param name="settings">The <see cref="JsonSerializerSettings"/> used to serialize the object.
+    /// If this is null, default serialization settings will be is used.</param>
+    /// <returns>
+    /// A JSON string representation of the object.
+    /// </returns>
+    public static string SerializeObject(object value, Formatting formatting, JsonSerializerSettings settings)
+    {
+      JsonSerializer jsonSerializer = JsonSerializer.Create(settings);
+
+      StringBuilder sb = new StringBuilder(128);
+      StringWriter sw = new StringWriter(sb, CultureInfo.InvariantCulture);
+      using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
+      {
+        jsonWriter.Formatting = formatting;
+
+        jsonSerializer.Serialize(jsonWriter, value);
+      }
+
+      return sw.ToString();
+    }
+
+    /// <summary>
+    /// Deserializes the JSON to a .NET object.
+    /// </summary>
+    /// <param name="value">The JSON to deserialize.</param>
+    /// <returns>The deserialized object from the Json string.</returns>
+    public static object DeserializeObject(string value)
+    {
+      return DeserializeObject(value, null, (JsonSerializerSettings)null);
+    }
+
+    /// <summary>
+    /// Deserializes the JSON to a .NET object.
+    /// </summary>
+    /// <param name="value">The JSON to deserialize.</param>
+    /// <param name="settings">
+    /// The <see cref="JsonSerializerSettings"/> used to deserialize the object.
+    /// If this is null, default serialization settings will be is used.
+    /// </param>
+    /// <returns>The deserialized object from the JSON string.</returns>
+    public static object DeserializeObject(string value, JsonSerializerSettings settings)
+    {
+      return DeserializeObject(value, null, settings);
+    }
+
+    /// <summary>
+    /// Deserializes the JSON to the specified .NET type.
+    /// </summary>
+    /// <param name="value">The JSON to deserialize.</param>
+    /// <param name="type">The <see cref="Type"/> of object being deserialized.</param>
+    /// <returns>The deserialized object from the Json string.</returns>
+    public static object DeserializeObject(string value, Type type)
+    {
+      return DeserializeObject(value, type, (JsonSerializerSettings)null);
+    }
+
+    /// <summary>
+    /// Deserializes the JSON to the specified .NET type.
+    /// </summary>
+    /// <typeparam name="T">The type of the object to deserialize to.</typeparam>
+    /// <param name="value">The JSON to deserialize.</param>
+    /// <returns>The deserialized object from the Json string.</returns>
+    public static T DeserializeObject<T>(string value)
+    {
+      return DeserializeObject<T>(value, (JsonSerializerSettings)null);
+    }
+
+    /// <summary>
+    /// Deserializes the JSON to the given anonymous type.
+    /// </summary>
+    /// <typeparam name="T">
+    /// The anonymous type to deserialize to. This can't be specified
+    /// traditionally and must be infered from the anonymous type passed
+    /// as a parameter.
+    /// </typeparam>
+    /// <param name="value">The JSON to deserialize.</param>
+    /// <param name="anonymousTypeObject">The anonymous type object.</param>
+    /// <returns>The deserialized anonymous type from the JSON string.</returns>
+    public static T DeserializeAnonymousType<T>(string value, T anonymousTypeObject)
+    {
+      return DeserializeObject<T>(value);
+    }
+
+    /// <summary>
+    /// Deserializes the JSON to the specified .NET type.
+    /// </summary>
+    /// <typeparam name="T">The type of the object to deserialize to.</typeparam>
+    /// <param name="value">The JSON to deserialize.</param>
+    /// <param name="converters">Converters to use while deserializing.</param>
+    /// <returns>The deserialized object from the JSON string.</returns>
+    public static T DeserializeObject<T>(string value, params JsonConverter[] converters)
+    {
+      return (T)DeserializeObject(value, typeof(T), converters);
+    }
+
+    /// <summary>
+    /// Deserializes the JSON to the specified .NET type.
+    /// </summary>
+    /// <typeparam name="T">The type of the object to deserialize to.</typeparam>
+    /// <param name="value">The object to deserialize.</param>
+    /// <param name="settings">
+    /// The <see cref="JsonSerializerSettings"/> used to deserialize the object.
+    /// If this is null, default serialization settings will be is used.
+    /// </param>
+    /// <returns>The deserialized object from the JSON string.</returns>
+    public static T DeserializeObject<T>(string value, JsonSerializerSettings settings)
+    {
+      return (T)DeserializeObject(value, typeof(T), settings);
+    }
+
+    /// <summary>
+    /// Deserializes the JSON to the specified .NET type.
+    /// </summary>
+    /// <param name="value">The JSON to deserialize.</param>
+    /// <param name="type">The type of the object to deserialize.</param>
+    /// <param name="converters">Converters to use while deserializing.</param>
+    /// <returns>The deserialized object from the JSON string.</returns>
+    public static object DeserializeObject(string value, Type type, params JsonConverter[] converters)
+    {
+      JsonSerializerSettings settings = (converters != null && converters.Length > 0)
+        ? new JsonSerializerSettings { Converters = converters }
+        : null;
+
+      return DeserializeObject(value, type, settings);
+    }
+
+    /// <summary>
+    /// Deserializes the JSON to the specified .NET type.
+    /// </summary>
+    /// <param name="value">The JSON to deserialize.</param>
+    /// <param name="type">The type of the object to deserialize to.</param>
+    /// <param name="settings">
+    /// The <see cref="JsonSerializerSettings"/> used to deserialize the object.
+    /// If this is null, default serialization settings will be is used.
+    /// </param>
+    /// <returns>The deserialized object from the JSON string.</returns>
+    public static object DeserializeObject(string value, Type type, JsonSerializerSettings settings)
+    {
+      StringReader sr = new StringReader(value);
+      JsonSerializer jsonSerializer = JsonSerializer.Create(settings);
+
+      object deserializedValue;
+
+      using (JsonReader jsonReader = new JsonTextReader(sr))
+      {
+        deserializedValue = jsonSerializer.Deserialize(jsonReader, type);
+
+        if (jsonReader.Read() && jsonReader.TokenType != JsonToken.Comment)
+          throw new JsonSerializationException("Additional text found in JSON string after finishing deserializing object.");
+      }
+
+      return deserializedValue;
+    }
+
+    /// <summary>
+    /// Populates the object with values from the JSON string.
+    /// </summary>
+    /// <param name="value">The JSON to populate values from.</param>
+    /// <param name="target">The target object to populate values onto.</param>
+    public static void PopulateObject(string value, object target)
+    {
+      PopulateObject(value, target, null);
+    }
+
+
+    /// <summary>
+    /// Populates the object with values from the JSON string.
+    /// </summary>
+    /// <param name="value">The JSON to populate values from.</param>
+    /// <param name="target">The target object to populate values onto.</param>
+    /// <param name="settings">
+    /// The <see cref="JsonSerializerSettings"/> used to deserialize the object.
+    /// If this is null, default serialization settings will be is used.
+    /// </param>
+    public static void PopulateObject(string value, object target, JsonSerializerSettings settings)
+    {
+      StringReader sr = new StringReader(value);
+      JsonSerializer jsonSerializer = JsonSerializer.Create(settings);
+
+      using (JsonReader jsonReader = new JsonTextReader(sr))
+      {
+        jsonSerializer.Populate(jsonReader, target);
+
+        if (jsonReader.Read() && jsonReader.TokenType != JsonToken.Comment)
+          throw new JsonSerializationException("Additional text found in JSON string after finishing deserializing object.");
+      }
+    }
+
+#if !SILVERLIGHT
+    /// <summary>
+    /// Serializes the XML node to a JSON string.
+    /// </summary>
+    /// <param name="node">The node to serialize.</param>
+    /// <returns>A JSON string of the XmlNode.</returns>
+    public static string SerializeXmlNode(XmlNode node)
+    {
+      return SerializeXmlNode(node, Formatting.None);
+    }
+
+    /// <summary>
+    /// Serializes the XML node to a JSON string.
+    /// </summary>
+    /// <param name="node">The node to serialize.</param>
+    /// <param name="formatting">Indicates how the output is formatted.</param>
+    /// <returns>A JSON string of the XmlNode.</returns>
+    public static string SerializeXmlNode(XmlNode node, Formatting formatting)
+    {
+      XmlNodeConverter converter = new XmlNodeConverter();
+
+      return SerializeObject(node, formatting, converter);
+    }
+
+    /// <summary>
+    /// Serializes the XML node to a JSON string.
+    /// </summary>
+    /// <param name="node">The node to serialize.</param>
+    /// <param name="formatting">Indicates how the output is formatted.</param>
+    /// <param name="omitRootObject">Omits writing the root object.</param>
+    /// <returns>A JSON string of the XmlNode.</returns>
+    public static string SerializeXmlNode(XmlNode node, Formatting formatting, bool omitRootObject)
+    {
+      XmlNodeConverter converter = new XmlNodeConverter { OmitRootObject = omitRootObject };
+
+      return SerializeObject(node, formatting, converter);
+    }
+
+    /// <summary>
+    /// Deserializes the XmlNode from a JSON string.
+    /// </summary>
+    /// <param name="value">The JSON string.</param>
+    /// <returns>The deserialized XmlNode</returns>
+    public static XmlDocument DeserializeXmlNode(string value)
+    {
+      return DeserializeXmlNode(value, null);
+    }
+
+    /// <summary>
+    /// Deserializes the XmlNode from a JSON string nested in a root elment.
+    /// </summary>
+    /// <param name="value">The JSON string.</param>
+    /// <param name="deserializeRootElementName">The name of the root element to append when deserializing.</param>
+    /// <returns>The deserialized XmlNode</returns>
+    public static XmlDocument DeserializeXmlNode(string value, string deserializeRootElementName)
+    {
+      return DeserializeXmlNode(value, deserializeRootElementName, false);
+    }
+
+    /// <summary>
+    /// Deserializes the XmlNode from a JSON string nested in a root elment.
+    /// </summary>
+    /// <param name="value">The JSON string.</param>
+    /// <param name="deserializeRootElementName">The name of the root element to append when deserializing.</param>
+    /// <param name="writeArrayAttribute">
+    /// A flag to indicate whether to write the Json.NET array attribute.
+    /// This attribute helps preserve arrays when converting the written XML back to JSON.
+    /// </param>
+    /// <returns>The deserialized XmlNode</returns>
+    public static XmlDocument DeserializeXmlNode(string value, string deserializeRootElementName, bool writeArrayAttribute)
+    {
+      XmlNodeConverter converter = new XmlNodeConverter();
+      converter.DeserializeRootElementName = deserializeRootElementName;
+      converter.WriteArrayAttribute = writeArrayAttribute;
+
+      return (XmlDocument)DeserializeObject(value, typeof(XmlDocument), converter);
+    }
+#endif
+
+#if !NET20 && (!SILVERLIGHT || WINDOWS_PHONE)
+    /// <summary>
+    /// Serializes the <see cref="XNode"/> to a JSON string.
+    /// </summary>
+    /// <param name="node">The node to convert to JSON.</param>
+    /// <returns>A JSON string of the XNode.</returns>
+    public static string SerializeXNode(XObject node)
+    {
+      return SerializeXNode(node, Formatting.None);
+    }
+
+    /// <summary>
+    /// Serializes the <see cref="XNode"/> to a JSON string.
+    /// </summary>
+    /// <param name="node">The node to convert to JSON.</param>
+    /// <param name="formatting">Indicates how the output is formatted.</param>
+    /// <returns>A JSON string of the XNode.</returns>
+    public static string SerializeXNode(XObject node, Formatting formatting)
+    {
+      return SerializeXNode(node, formatting, false);
+    }
+
+    /// <summary>
+    /// Serializes the <see cref="XNode"/> to a JSON string.
+    /// </summary>
+    /// <param name="node">The node to serialize.</param>
+    /// <param name="formatting">Indicates how the output is formatted.</param>
+    /// <param name="omitRootObject">Omits writing the root object.</param>
+    /// <returns>A JSON string of the XNode.</returns>
+    public static string SerializeXNode(XObject node, Formatting formatting, bool omitRootObject)
+    {
+      XmlNodeConverter converter = new XmlNodeConverter { OmitRootObject = omitRootObject };
+
+      return SerializeObject(node, formatting, converter);
+    }
+
+    /// <summary>
+    /// Deserializes the <see cref="XNode"/> from a JSON string.
+    /// </summary>
+    /// <param name="value">The JSON string.</param>
+    /// <returns>The deserialized XNode</returns>
+    public static XDocument DeserializeXNode(string value)
+    {
+      return DeserializeXNode(value, null);
+    }
+
+    /// <summary>
+    /// Deserializes the <see cref="XNode"/> from a JSON string nested in a root elment.
+    /// </summary>
+    /// <param name="value">The JSON string.</param>
+    /// <param name="deserializeRootElementName">The name of the root element to append when deserializing.</param>
+    /// <returns>The deserialized XNode</returns>
+    public static XDocument DeserializeXNode(string value, string deserializeRootElementName)
+    {
+      return DeserializeXNode(value, deserializeRootElementName, false);
+    }
+
+    /// <summary>
+    /// Deserializes the <see cref="XNode"/> from a JSON string nested in a root elment.
+    /// </summary>
+    /// <param name="value">The JSON string.</param>
+    /// <param name="deserializeRootElementName">The name of the root element to append when deserializing.</param>
+    /// <param name="writeArrayAttribute">
+    /// A flag to indicate whether to write the Json.NET array attribute.
+    /// This attribute helps preserve arrays when converting the written XML back to JSON.
+    /// </param>
+    /// <returns>The deserialized XNode</returns>
+    public static XDocument DeserializeXNode(string value, string deserializeRootElementName, bool writeArrayAttribute)
+    {
+      XmlNodeConverter converter = new XmlNodeConverter();
+      converter.DeserializeRootElementName = deserializeRootElementName;
+      converter.WriteArrayAttribute = writeArrayAttribute;
+
+      return (XDocument)DeserializeObject(value, typeof(XDocument), converter);
+    }
+#endif
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonConverter.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonConverter.cs
new file mode 100644 (file)
index 0000000..dd619f2
--- /dev/null
@@ -0,0 +1,93 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Newtonsoft.Json.Utilities;
+using Newtonsoft.Json.Schema;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Converts an object to and from JSON.
+  /// </summary>
+  public abstract class JsonConverter
+  {
+    /// <summary>
+    /// Writes the JSON representation of the object.
+    /// </summary>
+    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
+    /// <param name="value">The value.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    public abstract void WriteJson(JsonWriter writer, object value, JsonSerializer serializer);
+
+    /// <summary>
+    /// Reads the JSON representation of the object.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
+    /// <param name="objectType">Type of the object.</param>
+    /// <param name="existingValue">The existing value of object being read.</param>
+    /// <param name="serializer">The calling serializer.</param>
+    /// <returns>The object value.</returns>
+    public abstract object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer);
+
+    /// <summary>
+    /// Determines whether this instance can convert the specified object type.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns>
+    ///        <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
+    /// </returns>
+    public abstract bool CanConvert(Type objectType);
+
+    /// <summary>
+    /// Gets the <see cref="JsonSchema"/> of the JSON produced by the JsonConverter.
+    /// </summary>
+    /// <returns>The <see cref="JsonSchema"/> of the JSON produced by the JsonConverter.</returns>
+    public virtual JsonSchema GetSchema()
+    {
+      return null;
+    }
+
+    /// <summary>
+    /// Gets a value indicating whether this <see cref="JsonConverter"/> can read JSON.
+    /// </summary>
+    /// <value><c>true</c> if this <see cref="JsonConverter"/> can read JSON; otherwise, <c>false</c>.</value>
+    public virtual bool CanRead
+    {
+       get { return true; }
+    }
+
+    /// <summary>
+    /// Gets a value indicating whether this <see cref="JsonConverter"/> can write JSON.
+    /// </summary>
+    /// <value><c>true</c> if this <see cref="JsonConverter"/> can write JSON; otherwise, <c>false</c>.</value>
+    public virtual bool CanWrite
+    {
+      get { return true; }
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonConverterAttribute.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonConverterAttribute.cs
new file mode 100644 (file)
index 0000000..2b46f93
--- /dev/null
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Utilities;
+using System.Globalization;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Instructs the <see cref="JsonSerializer"/> to use the specified <see cref="JsonConverter"/> when serializing the member or class.
+  /// </summary>
+  [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface | AttributeTargets.Enum, AllowMultiple = false)]
+  public sealed class JsonConverterAttribute : Attribute
+  {
+    private readonly Type _converterType;
+
+    /// <summary>
+    /// Gets the type of the converter.
+    /// </summary>
+    /// <value>The type of the converter.</value>
+    public Type ConverterType
+    {
+      get { return _converterType; }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonConverterAttribute"/> class.
+    /// </summary>
+    /// <param name="converterType">Type of the converter.</param>
+    public JsonConverterAttribute(Type converterType)
+    {
+      if (converterType == null)
+        throw new ArgumentNullException("converterType");
+
+      _converterType = converterType;
+    }
+
+    internal static JsonConverter CreateJsonConverterInstance(Type converterType)
+    {
+      try
+      {
+        return (JsonConverter)Activator.CreateInstance(converterType);
+      }
+      catch (Exception ex)
+      {
+        throw new Exception("Error creating {0}".FormatWith(CultureInfo.InvariantCulture, converterType), ex);
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonConverterCollection.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonConverterCollection.cs
new file mode 100644 (file)
index 0000000..50f70c5
--- /dev/null
@@ -0,0 +1,39 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Collections.ObjectModel;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Represents a collection of <see cref="JsonConverter"/>.
+  /// </summary>
+  public class JsonConverterCollection : Collection<JsonConverter>
+  {
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonIgnoreAttribute.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonIgnoreAttribute.cs
new file mode 100644 (file)
index 0000000..e7511a0
--- /dev/null
@@ -0,0 +1,39 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Instructs the <see cref="JsonSerializer"/> not to serialize the public field or public read/write property value.
+  /// </summary>
+  [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
+  public sealed class JsonIgnoreAttribute : Attribute
+  {
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonObjectAttribute.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonObjectAttribute.cs
new file mode 100644 (file)
index 0000000..588eefc
--- /dev/null
@@ -0,0 +1,73 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Instructs the <see cref="JsonSerializer"/> how to serialize the object.
+  /// </summary>
+  [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false)]
+  public sealed class JsonObjectAttribute : JsonContainerAttribute
+  {
+    private MemberSerialization _memberSerialization = MemberSerialization.OptOut;
+
+    /// <summary>
+    /// Gets or sets the member serialization.
+    /// </summary>
+    /// <value>The member serialization.</value>
+    public MemberSerialization MemberSerialization
+    {
+      get { return _memberSerialization; }
+      set { _memberSerialization = value; }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonObjectAttribute"/> class.
+    /// </summary>
+    public JsonObjectAttribute()
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonObjectAttribute"/> class with the specified member serialization.
+    /// </summary>
+    /// <param name="memberSerialization">The member serialization.</param>
+    public JsonObjectAttribute(MemberSerialization memberSerialization)
+    {
+      MemberSerialization = memberSerialization;
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonObjectAttribute"/> class with the specified container Id.
+    /// </summary>
+    /// <param name="id">The container Id.</param>
+    public JsonObjectAttribute(string id)
+      : base(id)
+    {
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonPropertyAttribute.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonPropertyAttribute.cs
new file mode 100644 (file)
index 0000000..a85e567
--- /dev/null
@@ -0,0 +1,110 @@
+using System;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Instructs the <see cref="JsonSerializer"/> to always serialize the member with the specified name.
+  /// </summary>
+  [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
+  public sealed class JsonPropertyAttribute : Attribute
+  {
+    // yuck. can't set nullable properties on an attribute in C#
+    // have to use this approach to get an unset default state
+    internal NullValueHandling? _nullValueHandling;
+    internal DefaultValueHandling? _defaultValueHandling;
+    internal ReferenceLoopHandling? _referenceLoopHandling;
+    internal ObjectCreationHandling? _objectCreationHandling;
+    internal TypeNameHandling? _typeNameHandling;
+    internal bool? _isReference;
+
+    /// <summary>
+    /// Gets or sets the null value handling used when serializing this property.
+    /// </summary>
+    /// <value>The null value handling.</value>
+    public NullValueHandling NullValueHandling
+    {
+      get { return _nullValueHandling ?? default(NullValueHandling); }
+      set { _nullValueHandling = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets the default value handling used when serializing this property.
+    /// </summary>
+    /// <value>The default value handling.</value>
+    public DefaultValueHandling DefaultValueHandling
+    {
+      get { return _defaultValueHandling ?? default(DefaultValueHandling); }
+      set { _defaultValueHandling = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets the reference loop handling used when serializing this property.
+    /// </summary>
+    /// <value>The reference loop handling.</value>
+    public ReferenceLoopHandling ReferenceLoopHandling
+    {
+      get { return _referenceLoopHandling ?? default(ReferenceLoopHandling); }
+      set { _referenceLoopHandling = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets the object creation handling used when deserializing this property.
+    /// </summary>
+    /// <value>The object creation handling.</value>
+    public ObjectCreationHandling ObjectCreationHandling
+    {
+      get { return _objectCreationHandling ?? default(ObjectCreationHandling); }
+      set { _objectCreationHandling = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets the type name handling used when serializing this property.
+    /// </summary>
+    /// <value>The type name handling.</value>
+    public TypeNameHandling TypeNameHandling
+    {
+      get { return _typeNameHandling ?? default(TypeNameHandling); }
+      set { _typeNameHandling = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets whether this property's value is serialized as a reference.
+    /// </summary>
+    /// <value>Whether this property's value is serialized as a reference.</value>
+    public bool IsReference
+    {
+      get { return _isReference ?? default(bool); }
+      set { _isReference = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets the name of the property.
+    /// </summary>
+    /// <value>The name of the property.</value>
+    public string PropertyName { get; set; }
+
+    /// <summary>
+    /// Gets or sets a value indicating whether this property is required.
+    /// </summary>
+    /// <value>
+    ///        A value indicating whether this property is required.
+    /// </value>
+    public Required Required { get; set; }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonPropertyAttribute"/> class.
+    /// </summary>
+    public JsonPropertyAttribute()
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonPropertyAttribute"/> class with the specified name.
+    /// </summary>
+    /// <param name="propertyName">Name of the property.</param>
+    public JsonPropertyAttribute(string propertyName)
+    {
+      PropertyName = propertyName;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonReader.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonReader.cs
new file mode 100644 (file)
index 0000000..f46197b
--- /dev/null
@@ -0,0 +1,457 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Globalization;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Represents a reader that provides fast, non-cached, forward-only access to serialized Json data.
+  /// </summary>
+  public abstract class JsonReader : IDisposable
+  {
+    /// <summary>
+    /// Specifies the state of the reader.
+    /// </summary>
+    protected enum State
+    {
+      /// <summary>
+      /// The Read method has not been called.
+      /// </summary>
+      Start,
+      /// <summary>
+      /// The end of the file has been reached successfully.
+      /// </summary>
+      Complete,
+      /// <summary>
+      /// Reader is at a property.
+      /// </summary>
+      Property,
+      /// <summary>
+      /// Reader is at the start of an object.
+      /// </summary>
+      ObjectStart,
+      /// <summary>
+      /// Reader is in an object.
+      /// </summary>
+      Object,
+      /// <summary>
+      /// Reader is at the start of an array.
+      /// </summary>
+      ArrayStart,
+      /// <summary>
+      /// Reader is in an array.
+      /// </summary>
+      Array,
+      /// <summary>
+      /// The Close method has been called.
+      /// </summary>
+      Closed,
+      /// <summary>
+      /// Reader has just read a value.
+      /// </summary>
+      PostValue,
+      /// <summary>
+      /// Reader is at the start of a constructor.
+      /// </summary>
+      ConstructorStart,
+      /// <summary>
+      /// Reader in a constructor.
+      /// </summary>
+      Constructor,
+      /// <summary>
+      /// An error occurred that prevents the read operation from continuing.
+      /// </summary>
+      Error,
+      /// <summary>
+      /// The end of the file has been reached successfully.
+      /// </summary>
+      Finished
+    }
+
+    // current Token data
+    private JsonToken _token;
+    private object _value;
+    private Type _valueType;
+    private char _quoteChar;
+    private State _currentState;
+    private JTokenType _currentTypeContext;
+
+    /// <summary>
+    /// Gets the current reader state.
+    /// </summary>
+    /// <value>The current reader state.</value>
+    protected State CurrentState
+    {
+      get { return _currentState; }
+    }
+
+    private int _top;
+
+    private readonly List<JTokenType> _stack;
+
+    /// <summary>
+    /// Gets or sets a value indicating whether the underlying stream or
+    /// <see cref="TextReader"/> should be closed when the reader is closed.
+    /// </summary>
+    /// <value>
+    /// true to close the underlying stream or <see cref="TextReader"/> when
+    /// the reader is closed; otherwise false. The default is true.
+    /// </value>
+    public bool CloseInput { get; set; }
+
+    /// <summary>
+    /// Gets the quotation mark character used to enclose the value of a string.
+    /// </summary>
+    public virtual char QuoteChar
+    {
+      get { return _quoteChar; }
+      protected internal set { _quoteChar = value; }
+    }
+
+    /// <summary>
+    /// Gets the type of the current Json token. 
+    /// </summary>
+    public virtual JsonToken TokenType
+    {
+      get { return _token; }
+    }
+
+    /// <summary>
+    /// Gets the text value of the current Json token.
+    /// </summary>
+    public virtual object Value
+    {
+      get { return _value; }
+    }
+
+    /// <summary>
+    /// Gets The Common Language Runtime (CLR) type for the current Json token.
+    /// </summary>
+    public virtual Type ValueType
+    {
+      get { return _valueType; }
+    }
+
+    /// <summary>
+    /// Gets the depth of the current token in the JSON document.
+    /// </summary>
+    /// <value>The depth of the current token in the JSON document.</value>
+    public virtual int Depth
+    {
+      get
+      {
+        int depth = _top - 1;
+        if (IsStartToken(TokenType))
+          return depth - 1;
+        else
+          return depth;
+      }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonReader"/> class with the specified <see cref="TextReader"/>.
+    /// </summary>
+    protected JsonReader()
+    {
+      _currentState = State.Start;
+      _stack = new List<JTokenType>();
+
+      CloseInput = true;
+      
+      Push(JTokenType.None);
+    }
+
+    private void Push(JTokenType value)
+    {
+      _stack.Add(value);
+      _top++;
+      _currentTypeContext = value;
+    }
+
+    private JTokenType Pop()
+    {
+      JTokenType value = Peek();
+      _stack.RemoveAt(_stack.Count - 1);
+      _top--;
+      _currentTypeContext = _stack[_top - 1];
+
+      return value;
+    }
+
+    private JTokenType Peek()
+    {
+      return _currentTypeContext;
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream.
+    /// </summary>
+    /// <returns>true if the next token was read successfully; false if there are no more tokens to read.</returns>
+    public abstract bool Read();
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="T:Byte[]"/>.
+    /// </summary>
+    /// <returns>A <see cref="T:Byte[]"/> or a null reference if the next JSON token is null.</returns>
+    public abstract byte[] ReadAsBytes();
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="Nullable{Decimal}"/>.
+    /// </summary>
+    /// <returns>A <see cref="Nullable{Decimal}"/>.</returns>
+    public abstract decimal? ReadAsDecimal();
+
+#if !NET20
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="Nullable{DateTimeOffset}"/>.
+    /// </summary>
+    /// <returns>A <see cref="Nullable{DateTimeOffset}"/>.</returns>
+    public abstract DateTimeOffset? ReadAsDateTimeOffset();
+#endif
+
+    /// <summary>
+    /// Skips the children of the current token.
+    /// </summary>
+    public void Skip()
+    {
+      if (IsStartToken(TokenType))
+      {
+        int depth = Depth;
+
+        while (Read() && (depth < Depth))
+        {
+        }
+      }
+    }
+
+    /// <summary>
+    /// Sets the current token.
+    /// </summary>
+    /// <param name="newToken">The new token.</param>
+    protected void SetToken(JsonToken newToken)
+    {
+      SetToken(newToken, null);
+    }
+
+    /// <summary>
+    /// Sets the current token and value.
+    /// </summary>
+    /// <param name="newToken">The new token.</param>
+    /// <param name="value">The value.</param>
+    protected virtual void SetToken(JsonToken newToken, object value)
+    {
+      _token = newToken;
+
+      switch (newToken)
+      {
+        case JsonToken.StartObject:
+          _currentState = State.ObjectStart;
+          Push(JTokenType.Object);
+          break;
+        case JsonToken.StartArray:
+          _currentState = State.ArrayStart;
+          Push(JTokenType.Array);
+          break;
+        case JsonToken.StartConstructor:
+          _currentState = State.ConstructorStart;
+          Push(JTokenType.Constructor);
+          break;
+        case JsonToken.EndObject:
+          ValidateEnd(JsonToken.EndObject);
+          _currentState = State.PostValue;
+          break;
+        case JsonToken.EndArray:
+          ValidateEnd(JsonToken.EndArray);
+          _currentState = State.PostValue;
+          break;
+        case JsonToken.EndConstructor:
+          ValidateEnd(JsonToken.EndConstructor);
+          _currentState = State.PostValue;
+          break;
+        case JsonToken.PropertyName:
+          _currentState = State.Property;
+          Push(JTokenType.Property);
+          break;
+        case JsonToken.Undefined:
+        case JsonToken.Integer:
+        case JsonToken.Float:
+        case JsonToken.Boolean:
+        case JsonToken.Null:
+        case JsonToken.Date:
+        case JsonToken.String:
+        case JsonToken.Raw:
+        case JsonToken.Bytes:
+          _currentState = State.PostValue;
+          break;
+      }
+
+      JTokenType current = Peek();
+      if (current == JTokenType.Property && _currentState == State.PostValue)
+        Pop();
+
+      if (value != null)
+      {
+        _value = value;
+        _valueType = value.GetType();
+      }
+      else
+      {
+        _value = null;
+        _valueType = null;
+      }
+    }
+
+    private void ValidateEnd(JsonToken endToken)
+    {
+      JTokenType currentObject = Pop();
+
+      if (GetTypeForCloseToken(endToken) != currentObject)
+        throw new JsonReaderException("JsonToken {0} is not valid for closing JsonType {1}.".FormatWith(CultureInfo.InvariantCulture, endToken, currentObject));
+    }
+
+    /// <summary>
+    /// Sets the state based on current token type.
+    /// </summary>
+    protected void SetStateBasedOnCurrent()
+    {
+      JTokenType currentObject = Peek();
+
+      switch (currentObject)
+      {
+        case JTokenType.Object:
+          _currentState = State.Object;
+          break;
+        case JTokenType.Array:
+          _currentState = State.Array;
+          break;
+        case JTokenType.Constructor:
+          _currentState = State.Constructor;
+          break;
+        case JTokenType.None:
+          _currentState = State.Finished;
+          break;
+        default:
+          throw new JsonReaderException("While setting the reader state back to current object an unexpected JsonType was encountered: {0}".FormatWith(CultureInfo.InvariantCulture, currentObject));
+      }
+    }
+
+    internal static bool IsPrimitiveToken(JsonToken token)
+    {
+      switch (token)
+      {
+        case JsonToken.Integer:
+        case JsonToken.Float:
+        case JsonToken.String:
+        case JsonToken.Boolean:
+        case JsonToken.Undefined:
+        case JsonToken.Null:
+        case JsonToken.Date:
+        case JsonToken.Bytes:
+          return true;
+        default:
+          return false;
+      }
+    }
+
+    internal static bool IsStartToken(JsonToken token)
+    {
+      switch (token)
+      {
+        case JsonToken.StartObject:
+        case JsonToken.StartArray:
+        case JsonToken.StartConstructor:
+        case JsonToken.PropertyName:
+          return true;
+        case JsonToken.None:
+        case JsonToken.Comment:
+        case JsonToken.Integer:
+        case JsonToken.Float:
+        case JsonToken.String:
+        case JsonToken.Boolean:
+        case JsonToken.Null:
+        case JsonToken.Undefined:
+        case JsonToken.EndObject:
+        case JsonToken.EndArray:
+        case JsonToken.EndConstructor:
+        case JsonToken.Date:
+        case JsonToken.Raw:
+        case JsonToken.Bytes:
+          return false;
+        default:
+          throw MiscellaneousUtils.CreateArgumentOutOfRangeException("token", token, "Unexpected JsonToken value.");
+      }
+    }
+
+    private JTokenType GetTypeForCloseToken(JsonToken token)
+    {
+      switch (token)
+      {
+        case JsonToken.EndObject:
+          return JTokenType.Object;
+        case JsonToken.EndArray:
+          return JTokenType.Array;
+        case JsonToken.EndConstructor:
+          return JTokenType.Constructor;
+        default:
+          throw new JsonReaderException("Not a valid close JsonToken: {0}".FormatWith(CultureInfo.InvariantCulture, token));
+      }
+    }
+
+    /// <summary>
+    /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+    /// </summary>
+    void IDisposable.Dispose()
+    {
+      Dispose(true);
+    }
+
+    /// <summary>
+    /// Releases unmanaged and - optionally - managed resources
+    /// </summary>
+    /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
+    protected virtual void Dispose(bool disposing)
+    {
+      if (_currentState != State.Closed && disposing)
+        Close();
+    }
+
+    /// <summary>
+    /// Changes the <see cref="State"/> to Closed. 
+    /// </summary>
+    public virtual void Close()
+    {
+      _currentState = State.Closed;
+      _token = JsonToken.None;
+      _value = null;
+      _valueType = null;
+    }
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonReaderException.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonReaderException.cs
new file mode 100644 (file)
index 0000000..a466768
--- /dev/null
@@ -0,0 +1,83 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// The exception thrown when an error occurs while reading Json text.
+  /// </summary>
+  public class JsonReaderException : Exception
+  {
+    /// <summary>
+    /// Gets the line number indicating where the error occurred.
+    /// </summary>
+    /// <value>The line number indicating where the error occurred.</value>
+    public int LineNumber { get; private set; }
+
+
+    /// <summary>
+    /// Gets the line position indicating where the error occurred.
+    /// </summary>
+    /// <value>The line position indicating where the error occurred.</value>
+    public int LinePosition { get; private set; }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonReaderException"/> class.
+    /// </summary>
+    public JsonReaderException()
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonReaderException"/> class
+    /// with a specified error message.
+    /// </summary>
+    /// <param name="message">The error message that explains the reason for the exception.</param>
+    public JsonReaderException(string message)
+      : base(message)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonReaderException"/> class
+    /// with a specified error message and a reference to the inner exception that is the cause of this exception.
+    /// </summary>
+    /// <param name="message">The error message that explains the reason for the exception.</param>
+    /// <param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
+    public JsonReaderException(string message, Exception innerException)
+      : base(message, innerException)
+    {
+    }
+
+    internal JsonReaderException(string message, Exception innerException, int lineNumber, int linePosition)
+      : base(message, innerException)
+    {
+      LineNumber = lineNumber;
+      LinePosition = linePosition;
+    }
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonSerializationException.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonSerializationException.cs
new file mode 100644 (file)
index 0000000..758caa4
--- /dev/null
@@ -0,0 +1,65 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// The exception thrown when an error occurs during Json serialization or deserialization.
+  /// </summary>
+  public class JsonSerializationException : Exception
+  {
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonSerializationException"/> class.
+    /// </summary>
+    public JsonSerializationException()
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonSerializationException"/> class
+    /// with a specified error message.
+    /// </summary>
+    /// <param name="message">The error message that explains the reason for the exception.</param>
+    public JsonSerializationException(string message)
+      : base(message)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonSerializationException"/> class
+    /// with a specified error message and a reference to the inner exception that is the cause of this exception.
+    /// </summary>
+    /// <param name="message">The error message that explains the reason for the exception.</param>
+    /// <param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
+    public JsonSerializationException(string message, Exception innerException)
+      : base(message, innerException)
+    {
+    }
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonSerializer.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonSerializer.cs
new file mode 100644 (file)
index 0000000..4bb5389
--- /dev/null
@@ -0,0 +1,484 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Runtime.Serialization.Formatters;
+using Newtonsoft.Json.Converters;
+using Newtonsoft.Json.Serialization;
+using Newtonsoft.Json.Utilities;
+using System.Runtime.Serialization;
+using ErrorEventArgs=Newtonsoft.Json.Serialization.ErrorEventArgs;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Serializes and deserializes objects into and from the JSON format.
+  /// The <see cref="JsonSerializer"/> enables you to control how objects are encoded into JSON.
+  /// </summary>
+  public class JsonSerializer
+  {
+    #region Properties
+    private TypeNameHandling _typeNameHandling;
+    private FormatterAssemblyStyle _typeNameAssemblyFormat;
+    private PreserveReferencesHandling _preserveReferencesHandling;
+    private ReferenceLoopHandling _referenceLoopHandling;
+    private MissingMemberHandling _missingMemberHandling;
+    private ObjectCreationHandling _objectCreationHandling;
+    private NullValueHandling _nullValueHandling;
+    private DefaultValueHandling _defaultValueHandling;
+    private ConstructorHandling _constructorHandling;
+    private JsonConverterCollection _converters;
+    private IContractResolver _contractResolver;
+    private IReferenceResolver _referenceResolver;
+    private SerializationBinder _binder;
+    private StreamingContext _context;
+
+    /// <summary>
+    /// Occurs when the <see cref="JsonSerializer"/> errors during serialization and deserialization.
+    /// </summary>
+    public virtual event EventHandler<ErrorEventArgs> Error;
+
+    /// <summary>
+    /// Gets or sets the <see cref="IReferenceResolver"/> used by the serializer when resolving references.
+    /// </summary>
+    public virtual IReferenceResolver ReferenceResolver
+    {
+      get
+      {
+        if (_referenceResolver == null)
+          _referenceResolver = new DefaultReferenceResolver();
+
+        return _referenceResolver;
+      }
+      set
+      {
+        if (value == null)
+          throw new ArgumentNullException("value", "Reference resolver cannot be null.");
+
+        _referenceResolver = value;
+      }
+    }
+
+    /// <summary>
+    /// Gets or sets the <see cref="SerializationBinder"/> used by the serializer when resolving type names.
+    /// </summary>
+    public virtual SerializationBinder Binder
+    {
+      get
+      {
+        return _binder;
+      }
+      set
+      {
+        if (value == null)
+          throw new ArgumentNullException("value", "Serialization binder cannot be null.");
+
+        _binder = value;
+      }
+    }
+
+    /// <summary>
+    /// Gets or sets how type name writing and reading is handled by the serializer.
+    /// </summary>
+    public virtual TypeNameHandling TypeNameHandling
+    {
+      get { return _typeNameHandling; }
+      set
+      {
+        if (value < TypeNameHandling.None || value > TypeNameHandling.Auto)
+          throw new ArgumentOutOfRangeException("value");
+
+        _typeNameHandling = value;
+      }
+    }
+
+    /// <summary>
+    /// Gets or sets how a type name assembly is written and resolved by the serializer.
+    /// </summary>
+    /// <value>The type name assembly format.</value>
+    public virtual FormatterAssemblyStyle TypeNameAssemblyFormat
+    {
+      get { return _typeNameAssemblyFormat; }
+      set
+      {
+        if (value < FormatterAssemblyStyle.Simple || value > FormatterAssemblyStyle.Full)
+          throw new ArgumentOutOfRangeException("value");
+
+        _typeNameAssemblyFormat = value;
+      }
+    }
+
+    /// <summary>
+    /// Gets or sets how object references are preserved by the serializer.
+    /// </summary>
+    public virtual PreserveReferencesHandling PreserveReferencesHandling
+    {
+      get { return _preserveReferencesHandling; }
+      set
+      {
+        if (value < PreserveReferencesHandling.None || value > PreserveReferencesHandling.All)
+          throw new ArgumentOutOfRangeException("value");
+
+        _preserveReferencesHandling = value;
+      }
+    }
+
+    /// <summary>
+    /// Get or set how reference loops (e.g. a class referencing itself) is handled.
+    /// </summary>
+    public virtual ReferenceLoopHandling ReferenceLoopHandling
+    {
+      get { return _referenceLoopHandling; }
+      set
+      {
+        if (value < ReferenceLoopHandling.Error || value > ReferenceLoopHandling.Serialize)
+          throw new ArgumentOutOfRangeException("value");
+
+        _referenceLoopHandling = value;
+      }
+    }
+
+    /// <summary>
+    /// Get or set how missing members (e.g. JSON contains a property that isn't a member on the object) are handled during deserialization.
+    /// </summary>
+    public virtual MissingMemberHandling MissingMemberHandling
+    {
+      get { return _missingMemberHandling; }
+      set
+      {
+        if (value < MissingMemberHandling.Ignore || value > MissingMemberHandling.Error)
+          throw new ArgumentOutOfRangeException("value");
+
+        _missingMemberHandling = value;
+      }
+    }
+
+    /// <summary>
+    /// Get or set how null values are handled during serialization and deserialization.
+    /// </summary>
+    public virtual NullValueHandling NullValueHandling
+    {
+      get { return _nullValueHandling; }
+      set
+      {
+        if (value < NullValueHandling.Include || value > NullValueHandling.Ignore)
+          throw new ArgumentOutOfRangeException("value");
+
+        _nullValueHandling = value;
+      }
+    }
+
+    /// <summary>
+    /// Get or set how null default are handled during serialization and deserialization.
+    /// </summary>
+    public virtual DefaultValueHandling DefaultValueHandling
+    {
+      get { return _defaultValueHandling; }
+      set
+      {
+        if (value < DefaultValueHandling.Include || value > DefaultValueHandling.Ignore)
+          throw new ArgumentOutOfRangeException("value");
+
+        _defaultValueHandling = value;
+      }
+    }
+
+    /// <summary>
+    /// Gets or sets how objects are created during deserialization.
+    /// </summary>
+    /// <value>The object creation handling.</value>
+    public virtual ObjectCreationHandling ObjectCreationHandling
+    {
+      get { return _objectCreationHandling; }
+      set
+      {
+        if (value < ObjectCreationHandling.Auto || value > ObjectCreationHandling.Replace)
+          throw new ArgumentOutOfRangeException("value");
+
+        _objectCreationHandling = value;
+      }
+    }
+
+    /// <summary>
+    /// Gets or sets how constructors are used during deserialization.
+    /// </summary>
+    /// <value>The constructor handling.</value>
+    public virtual ConstructorHandling ConstructorHandling
+    {
+      get { return _constructorHandling; }
+      set
+      {
+        if (value < ConstructorHandling.Default || value > ConstructorHandling.AllowNonPublicDefaultConstructor)
+          throw new ArgumentOutOfRangeException("value");
+
+        _constructorHandling = value;
+      }
+    }
+
+    /// <summary>
+    /// Gets a collection <see cref="JsonConverter"/> that will be used during serialization.
+    /// </summary>
+    /// <value>Collection <see cref="JsonConverter"/> that will be used during serialization.</value>
+    public virtual JsonConverterCollection Converters
+    {
+      get
+      {
+        if (_converters == null)
+          _converters = new JsonConverterCollection();
+
+        return _converters;
+      }
+    }
+
+    /// <summary>
+    /// Gets or sets the contract resolver used by the serializer when
+    /// serializing .NET objects to JSON and vice versa.
+    /// </summary>
+    public virtual IContractResolver ContractResolver
+    {
+      get
+      {
+        if (_contractResolver == null)
+          _contractResolver = DefaultContractResolver.Instance;
+
+        return _contractResolver;
+      }
+      set { _contractResolver = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets the <see cref="StreamingContext"/> used by the serializer when invoking serialization callback methods.
+    /// </summary>
+    /// <value>The context.</value>
+    public virtual StreamingContext Context
+    {
+      get { return _context; }
+      set { _context = value; }
+    }
+    #endregion
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonSerializer"/> class.
+    /// </summary>
+    public JsonSerializer()
+    {
+      _referenceLoopHandling = JsonSerializerSettings.DefaultReferenceLoopHandling;
+      _missingMemberHandling = JsonSerializerSettings.DefaultMissingMemberHandling;
+      _nullValueHandling = JsonSerializerSettings.DefaultNullValueHandling;
+      _defaultValueHandling = JsonSerializerSettings.DefaultDefaultValueHandling;
+      _objectCreationHandling = JsonSerializerSettings.DefaultObjectCreationHandling;
+      _preserveReferencesHandling = JsonSerializerSettings.DefaultPreserveReferencesHandling;
+      _constructorHandling = JsonSerializerSettings.DefaultConstructorHandling;
+      _typeNameHandling = JsonSerializerSettings.DefaultTypeNameHandling;
+      _context = JsonSerializerSettings.DefaultContext;
+
+      _binder = DefaultSerializationBinder.Instance;
+    }
+
+    /// <summary>
+    /// Creates a new <see cref="JsonSerializer"/> instance using the specified <see cref="JsonSerializerSettings"/>.
+    /// </summary>
+    /// <param name="settings">The settings to be applied to the <see cref="JsonSerializer"/>.</param>
+    /// <returns>A new <see cref="JsonSerializer"/> instance using the specified <see cref="JsonSerializerSettings"/>.</returns>
+    public static JsonSerializer Create(JsonSerializerSettings settings)
+    {
+      JsonSerializer jsonSerializer = new JsonSerializer();
+
+      if (settings != null)
+      {
+        if (!CollectionUtils.IsNullOrEmpty(settings.Converters))
+          jsonSerializer.Converters.AddRange(settings.Converters);
+
+        jsonSerializer.TypeNameHandling = settings.TypeNameHandling;
+        jsonSerializer.TypeNameAssemblyFormat = settings.TypeNameAssemblyFormat;
+        jsonSerializer.PreserveReferencesHandling = settings.PreserveReferencesHandling;
+        jsonSerializer.ReferenceLoopHandling = settings.ReferenceLoopHandling;
+        jsonSerializer.MissingMemberHandling = settings.MissingMemberHandling;
+        jsonSerializer.ObjectCreationHandling = settings.ObjectCreationHandling;
+        jsonSerializer.NullValueHandling = settings.NullValueHandling;
+        jsonSerializer.DefaultValueHandling = settings.DefaultValueHandling;
+        jsonSerializer.ConstructorHandling = settings.ConstructorHandling;
+        jsonSerializer.Context = settings.Context;
+
+        if (settings.Error != null)
+          jsonSerializer.Error += settings.Error;
+
+        if (settings.ContractResolver != null)
+          jsonSerializer.ContractResolver = settings.ContractResolver;
+        if (settings.ReferenceResolver != null)
+          jsonSerializer.ReferenceResolver = settings.ReferenceResolver;
+        if (settings.Binder != null)
+          jsonSerializer.Binder = settings.Binder;
+      }
+
+      return jsonSerializer;
+    }
+
+    /// <summary>
+    /// Populates the JSON values onto the target object.
+    /// </summary>
+    /// <param name="reader">The <see cref="TextReader"/> that contains the JSON structure to reader values from.</param>
+    /// <param name="target">The target object to populate values onto.</param>
+    public void Populate(TextReader reader, object target)
+    {
+      Populate(new JsonTextReader(reader), target);
+    }
+
+    /// <summary>
+    /// Populates the JSON values onto the target object.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> that contains the JSON structure to reader values from.</param>
+    /// <param name="target">The target object to populate values onto.</param>
+    public void Populate(JsonReader reader, object target)
+    {
+      PopulateInternal(reader, target);
+    }
+
+    internal virtual void PopulateInternal(JsonReader reader, object target)
+    {
+      ValidationUtils.ArgumentNotNull(reader, "reader");
+      ValidationUtils.ArgumentNotNull(target, "target");
+
+      JsonSerializerInternalReader serializerReader = new JsonSerializerInternalReader(this);
+      serializerReader.Populate(reader, target);
+    }
+
+    /// <summary>
+    /// Deserializes the Json structure contained by the specified <see cref="JsonReader"/>.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> that contains the JSON structure to deserialize.</param>
+    /// <returns>The <see cref="Object"/> being deserialized.</returns>
+    public object Deserialize(JsonReader reader)
+    {
+      return Deserialize(reader, null);
+    }
+
+    /// <summary>
+    /// Deserializes the Json structure contained by the specified <see cref="StringReader"/>
+    /// into an instance of the specified type.
+    /// </summary>
+    /// <param name="reader">The <see cref="TextReader"/> containing the object.</param>
+    /// <param name="objectType">The <see cref="Type"/> of object being deserialized.</param>
+    /// <returns>The instance of <paramref name="objectType"/> being deserialized.</returns>
+    public object Deserialize(TextReader reader, Type objectType)
+    {
+      return Deserialize(new JsonTextReader(reader), objectType);
+    }
+
+    /// <summary>
+    /// Deserializes the Json structure contained by the specified <see cref="JsonReader"/>
+    /// into an instance of the specified type.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> containing the object.</param>
+    /// <typeparam name="T">The type of the object to deserialize.</typeparam>
+    /// <returns>The instance of <typeparamref name="T"/> being deserialized.</returns>
+    public T Deserialize<T>(JsonReader reader)
+    {
+      return (T)Deserialize(reader, typeof(T));
+    }
+
+    /// <summary>
+    /// Deserializes the Json structure contained by the specified <see cref="JsonReader"/>
+    /// into an instance of the specified type.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> containing the object.</param>
+    /// <param name="objectType">The <see cref="Type"/> of object being deserialized.</param>
+    /// <returns>The instance of <paramref name="objectType"/> being deserialized.</returns>
+    public object Deserialize(JsonReader reader, Type objectType)
+    {
+      return DeserializeInternal(reader, objectType);
+    }
+
+    internal virtual object DeserializeInternal(JsonReader reader, Type objectType)
+    {
+      ValidationUtils.ArgumentNotNull(reader, "reader");
+
+      JsonSerializerInternalReader serializerReader = new JsonSerializerInternalReader(this);
+      return serializerReader.Deserialize(reader, objectType);
+    }
+
+    /// <summary>
+    /// Serializes the specified <see cref="Object"/> and writes the Json structure
+    /// to a <c>Stream</c> using the specified <see cref="TextWriter"/>. 
+    /// </summary>
+    /// <param name="textWriter">The <see cref="TextWriter"/> used to write the Json structure.</param>
+    /// <param name="value">The <see cref="Object"/> to serialize.</param>
+    public void Serialize(TextWriter textWriter, object value)
+    {
+      Serialize(new JsonTextWriter(textWriter), value);
+    }
+
+    /// <summary>
+    /// Serializes the specified <see cref="Object"/> and writes the Json structure
+    /// to a <c>Stream</c> using the specified <see cref="JsonWriter"/>. 
+    /// </summary>
+    /// <param name="jsonWriter">The <see cref="JsonWriter"/> used to write the Json structure.</param>
+    /// <param name="value">The <see cref="Object"/> to serialize.</param>
+    public void Serialize(JsonWriter jsonWriter, object value)
+    {
+      SerializeInternal(jsonWriter, value);
+    }
+
+    internal virtual void SerializeInternal(JsonWriter jsonWriter, object value)
+    {
+      ValidationUtils.ArgumentNotNull(jsonWriter, "jsonWriter");
+
+      JsonSerializerInternalWriter serializerWriter = new JsonSerializerInternalWriter(this);
+      serializerWriter.Serialize(jsonWriter, value);
+    }
+
+    internal JsonConverter GetMatchingConverter(Type type)
+    {
+      return GetMatchingConverter(_converters, type);
+    }
+
+    internal static JsonConverter GetMatchingConverter(IList<JsonConverter> converters, Type objectType)
+    {
+      ValidationUtils.ArgumentNotNull(objectType, "objectType");
+
+      if (converters != null)
+      {
+        for (int i = 0; i < converters.Count; i++)
+        {
+          JsonConverter converter = converters[i];
+
+          if (converter.CanConvert(objectType))
+            return converter;
+        }
+      }
+
+      return null;
+    }
+
+    internal void OnError(ErrorEventArgs e)
+    {
+      EventHandler<ErrorEventArgs> error = Error;
+      if (error != null)
+        error(this, e);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonSerializerSettings.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonSerializerSettings.cs
new file mode 100644 (file)
index 0000000..278493d
--- /dev/null
@@ -0,0 +1,136 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.Serialization.Formatters;
+using System.Text;
+using Newtonsoft.Json.Serialization;
+using Newtonsoft.Json.Utilities;
+using System.Runtime.Serialization;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Specifies the settings on a <see cref="JsonSerializer"/> object.
+  /// </summary>
+  public class JsonSerializerSettings
+  {
+    internal const ReferenceLoopHandling DefaultReferenceLoopHandling = ReferenceLoopHandling.Error;
+    internal const MissingMemberHandling DefaultMissingMemberHandling = MissingMemberHandling.Ignore;
+    internal const NullValueHandling DefaultNullValueHandling = NullValueHandling.Include;
+    internal const DefaultValueHandling DefaultDefaultValueHandling = DefaultValueHandling.Include;
+    internal const ObjectCreationHandling DefaultObjectCreationHandling = ObjectCreationHandling.Auto;
+    internal const PreserveReferencesHandling DefaultPreserveReferencesHandling = PreserveReferencesHandling.None;
+    internal const ConstructorHandling DefaultConstructorHandling = ConstructorHandling.Default;
+    internal const TypeNameHandling DefaultTypeNameHandling = TypeNameHandling.None;
+    internal const FormatterAssemblyStyle DefaultTypeNameAssemblyFormat = FormatterAssemblyStyle.Simple;
+    internal static readonly StreamingContext DefaultContext = new StreamingContext();
+
+    /// <summary>
+    /// Gets or sets how reference loops (e.g. a class referencing itself) is handled.
+    /// </summary>
+    /// <value>Reference loop handling.</value>
+    public ReferenceLoopHandling ReferenceLoopHandling { get; set; }
+
+    /// <summary>
+    /// Gets or sets how missing members (e.g. JSON contains a property that isn't a member on the object) are handled during deserialization.
+    /// </summary>
+    /// <value>Missing member handling.</value>
+    public MissingMemberHandling MissingMemberHandling { get; set; }
+
+    /// <summary>
+    /// Gets or sets how objects are created during deserialization.
+    /// </summary>
+    /// <value>The object creation handling.</value>
+    public ObjectCreationHandling ObjectCreationHandling { get; set; }
+
+    /// <summary>
+    /// Gets or sets how null values are handled during serialization and deserialization.
+    /// </summary>
+    /// <value>Null value handling.</value>
+    public NullValueHandling NullValueHandling { get; set; }
+
+    /// <summary>
+    /// Gets or sets how null default are handled during serialization and deserialization.
+    /// </summary>
+    /// <value>The default value handling.</value>
+    public DefaultValueHandling DefaultValueHandling { get; set; }
+
+    /// <summary>
+    /// Gets or sets a collection <see cref="JsonConverter"/> that will be used during serialization.
+    /// </summary>
+    /// <value>The converters.</value>
+    public IList<JsonConverter> Converters { get; set; }
+
+    /// <summary>
+    /// Gets or sets how object references are preserved by the serializer.
+    /// </summary>
+    /// <value>The preserve references handling.</value>
+    public PreserveReferencesHandling PreserveReferencesHandling { get; set; }
+
+    /// <summary>
+    /// Gets or sets how type name writing and reading is handled by the serializer.
+    /// </summary>
+    /// <value>The type name handling.</value>
+    public TypeNameHandling TypeNameHandling { get; set; }
+
+    /// <summary>
+    /// Gets or sets how a type name assembly is written and resolved by the serializer.
+    /// </summary>
+    /// <value>The type name assembly format.</value>
+    public FormatterAssemblyStyle TypeNameAssemblyFormat { get; set; }
+
+    /// <summary>
+    /// Gets or sets how constructors are used during deserialization.
+    /// </summary>
+    /// <value>The constructor handling.</value>
+    public ConstructorHandling ConstructorHandling { get; set; }
+
+    /// <summary>
+    /// Gets or sets the contract resolver used by the serializer when
+    /// serializing .NET objects to JSON and vice versa.
+    /// </summary>
+    /// <value>The contract resolver.</value>
+    public IContractResolver ContractResolver { get; set; }
+
+    /// <summary>
+    /// Gets or sets the <see cref="IReferenceResolver"/> used by the serializer when resolving references.
+    /// </summary>
+    /// <value>The reference resolver.</value>
+    public IReferenceResolver ReferenceResolver { get; set; }
+
+    /// <summary>
+    /// Gets or sets the <see cref="SerializationBinder"/> used by the serializer when resolving type names.
+    /// </summary>
+    /// <value>The binder.</value>
+    public SerializationBinder Binder { get; set; }
+
+    /// <summary>
+    /// Gets or sets the error handler called during serialization and deserialization.
+    /// </summary>
+    /// <value>The error handler called during serialization and deserialization.</value>
+    public EventHandler<ErrorEventArgs> Error { get; set; }
+
+    /// <summary>
+    /// Gets or sets the <see cref="StreamingContext"/> used by the serializer when invoking serialization callback methods.
+    /// </summary>
+    /// <value>The context.</value>
+    public StreamingContext Context { get; set; }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonSerializerSettings"/> class.
+    /// </summary>
+    public JsonSerializerSettings()
+    {
+      ReferenceLoopHandling = DefaultReferenceLoopHandling;
+      MissingMemberHandling = DefaultMissingMemberHandling;
+      ObjectCreationHandling = DefaultObjectCreationHandling;
+      NullValueHandling = DefaultNullValueHandling;
+      DefaultValueHandling = DefaultDefaultValueHandling;
+      PreserveReferencesHandling = DefaultPreserveReferencesHandling;
+      TypeNameHandling = DefaultTypeNameHandling;
+      TypeNameAssemblyFormat = DefaultTypeNameAssemblyFormat;
+      Context = DefaultContext;
+      Converters = new List<JsonConverter>();
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonTextReader.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonTextReader.cs
new file mode 100644 (file)
index 0000000..b71d0c8
--- /dev/null
@@ -0,0 +1,1052 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+using System.Xml;
+using System.Globalization;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Represents a reader that provides fast, non-cached, forward-only access to serialized Json data.
+  /// </summary>
+  public class JsonTextReader : JsonReader, IJsonLineInfo
+  {
+    private enum ReadType
+    {
+      Read,
+      ReadAsBytes,
+      ReadAsDecimal,
+#if !NET20
+      ReadAsDateTimeOffset
+#endif
+    }
+
+    private readonly TextReader _reader;
+    private readonly StringBuffer _buffer;
+    private char? _lastChar;
+    private int _currentLinePosition;
+    private int _currentLineNumber;
+    private bool _end;
+    private ReadType _readType;
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonReader"/> class with the specified <see cref="TextReader"/>.
+    /// </summary>
+    /// <param name="reader">The <c>TextReader</c> containing the XML data to read.</param>
+    public JsonTextReader(TextReader reader)
+    {
+      if (reader == null)
+        throw new ArgumentNullException("reader");
+
+      _reader = reader;
+      _buffer = new StringBuffer(4096);
+      _currentLineNumber = 1;
+    }
+
+    private void ParseString(char quote)
+    {
+      ReadStringIntoBuffer(quote);
+
+      if (_readType == ReadType.ReadAsBytes)
+      {
+        byte[] data;
+        if (_buffer.Position == 0)
+        {
+          data = new byte[0];
+        }
+        else
+        {
+          data = Convert.FromBase64CharArray(_buffer.GetInternalBuffer(), 0, _buffer.Position);
+          _buffer.Position = 0;
+        }
+
+        SetToken(JsonToken.Bytes, data);
+      }
+      else
+      {
+        string text = _buffer.ToString();
+        _buffer.Position = 0;
+
+        if (text.StartsWith("/Date(", StringComparison.Ordinal) && text.EndsWith(")/", StringComparison.Ordinal))
+        {
+          ParseDate(text);
+        }
+        else
+        {
+          SetToken(JsonToken.String, text);
+          QuoteChar = quote;
+        } 
+      }
+    }
+
+    private void ReadStringIntoBuffer(char quote)
+    {
+      while (true)
+      {
+        char currentChar = MoveNext();
+
+        switch (currentChar)
+        {
+          case '\0':
+            if (_end)
+              throw CreateJsonReaderException("Unterminated string. Expected delimiter: {0}. Line {1}, position {2}.", quote, _currentLineNumber, _currentLinePosition);
+
+            _buffer.Append('\0');
+            break;
+          case '\\':
+            if ((currentChar = MoveNext()) != '\0' || !_end)
+            {
+              switch (currentChar)
+              {
+                case 'b':
+                  _buffer.Append('\b');
+                  break;
+                case 't':
+                  _buffer.Append('\t');
+                  break;
+                case 'n':
+                  _buffer.Append('\n');
+                  break;
+                case 'f':
+                  _buffer.Append('\f');
+                  break;
+                case 'r':
+                  _buffer.Append('\r');
+                  break;
+                case '\\':
+                  _buffer.Append('\\');
+                  break;
+                case '"':
+                case '\'':
+                case '/':
+                  _buffer.Append(currentChar);
+                  break;
+                case 'u':
+                  char[] hexValues = new char[4];
+                  for (int i = 0; i < hexValues.Length; i++)
+                  {
+                    if ((currentChar = MoveNext()) != '\0' || !_end)
+                      hexValues[i] = currentChar;
+                    else
+                      throw CreateJsonReaderException("Unexpected end while parsing unicode character. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
+                  }
+
+                  char hexChar = Convert.ToChar(int.Parse(new string(hexValues), NumberStyles.HexNumber, NumberFormatInfo.InvariantInfo));
+                  _buffer.Append(hexChar);
+                  break;
+                default:
+                  throw CreateJsonReaderException("Bad JSON escape sequence: {0}. Line {1}, position {2}.", @"\" + currentChar, _currentLineNumber, _currentLinePosition);
+              }
+            }
+            else
+            {
+              throw CreateJsonReaderException("Unterminated string. Expected delimiter: {0}. Line {1}, position {2}.", quote, _currentLineNumber, _currentLinePosition);
+            }
+            break;
+          case '"':
+          case '\'':
+            if (currentChar == quote)
+            {
+              return;
+            }
+            else
+            {
+              _buffer.Append(currentChar);
+            }
+            break;
+          default:
+            _buffer.Append(currentChar);
+            break;
+        }
+      }
+    }
+
+    private JsonReaderException CreateJsonReaderException(string format, params object[] args)
+    {
+      string message = format.FormatWith(CultureInfo.InvariantCulture, args);
+      return new JsonReaderException(message, null, _currentLineNumber, _currentLinePosition);
+    }
+
+    private TimeSpan ReadOffset(string offsetText)
+    {
+      bool negative = (offsetText[0] == '-');
+
+      int hours = int.Parse(offsetText.Substring(1, 2), NumberStyles.Integer, CultureInfo.InvariantCulture);
+      int minutes = 0;
+      if (offsetText.Length >= 5)
+        minutes = int.Parse(offsetText.Substring(3, 2), NumberStyles.Integer, CultureInfo.InvariantCulture);
+
+      TimeSpan offset = TimeSpan.FromHours(hours) + TimeSpan.FromMinutes(minutes);
+      if (negative)
+        offset = offset.Negate();
+      
+      return offset;
+    }
+
+    private void ParseDate(string text)
+    {
+      string value = text.Substring(6, text.Length - 8);
+      DateTimeKind kind = DateTimeKind.Utc;
+
+      int index = value.IndexOf('+', 1);
+
+      if (index == -1)
+        index = value.IndexOf('-', 1);
+
+      TimeSpan offset = TimeSpan.Zero;
+
+      if (index != -1)
+      {
+        kind = DateTimeKind.Local;
+        offset = ReadOffset(value.Substring(index));
+        value = value.Substring(0, index);
+      }
+
+      long javaScriptTicks = long.Parse(value, NumberStyles.Integer, CultureInfo.InvariantCulture);
+
+      DateTime utcDateTime = JsonConvert.ConvertJavaScriptTicksToDateTime(javaScriptTicks);
+
+#if !NET20
+      if (_readType == ReadType.ReadAsDateTimeOffset)
+      {
+        SetToken(JsonToken.Date, new DateTimeOffset(utcDateTime.Add(offset).Ticks, offset));
+      }
+      else
+#endif
+      {
+        DateTime dateTime;
+
+        switch (kind)
+        {
+          case DateTimeKind.Unspecified:
+            dateTime = DateTime.SpecifyKind(utcDateTime.ToLocalTime(), DateTimeKind.Unspecified);
+            break;
+          case DateTimeKind.Local:
+            dateTime = utcDateTime.ToLocalTime();
+            break;
+          default:
+            dateTime = utcDateTime;
+            break;
+        }
+
+        SetToken(JsonToken.Date, dateTime);
+      }
+    }
+
+    private const int LineFeedValue = StringUtils.LineFeed;
+    private const int CarriageReturnValue = StringUtils.CarriageReturn;
+
+    private char MoveNext()
+    {
+      int value = _reader.Read();
+
+      switch (value)
+      {
+        case -1:
+          _end = true;
+          return '\0';
+        case CarriageReturnValue:
+          if (_reader.Peek() == LineFeedValue)
+            _reader.Read();
+
+          _currentLineNumber++;
+          _currentLinePosition = 0;
+          break;
+        case LineFeedValue:
+          _currentLineNumber++;
+          _currentLinePosition = 0;
+          break;
+        default:
+          _currentLinePosition++;
+          break;
+      }
+
+      return (char)value;
+    }
+
+    private bool HasNext()
+    {
+      return (_reader.Peek() != -1);
+    }
+
+    private int PeekNext()
+    {
+      return _reader.Peek();
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream.
+    /// </summary>
+    /// <returns>
+    /// true if the next token was read successfully; false if there are no more tokens to read.
+    /// </returns>
+    public override bool Read()
+    {
+      _readType = ReadType.Read;
+      return ReadInternal();
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="T:Byte[]"/>.
+    /// </summary>
+    /// <returns>
+    /// A <see cref="T:Byte[]"/> or a null reference if the next JSON token is null.
+    /// </returns>
+    public override byte[] ReadAsBytes()
+    {
+      _readType = ReadType.ReadAsBytes;
+
+      do
+      {
+        if (!ReadInternal())
+        throw CreateJsonReaderException("Unexpected end when reading bytes: Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
+      } while (TokenType == JsonToken.Comment);
+
+      if (TokenType == JsonToken.Null)
+        return null;
+      if (TokenType == JsonToken.Bytes)
+        return (byte[]) Value;
+
+      throw CreateJsonReaderException("Unexpected token when reading bytes: {0}. Line {1}, position {2}.", TokenType, _currentLineNumber, _currentLinePosition);
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="Nullable{Decimal}"/>.
+    /// </summary>
+    /// <returns>A <see cref="Nullable{Decimal}"/>.</returns>
+    public override decimal? ReadAsDecimal()
+    {
+      _readType = ReadType.ReadAsDecimal;
+      
+      do
+      {
+        if (!ReadInternal())
+          throw CreateJsonReaderException("Unexpected end when reading decimal: Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
+      } while (TokenType == JsonToken.Comment);
+      if (TokenType == JsonToken.Null)
+        return null;
+      if (TokenType == JsonToken.Float)
+        return (decimal?)Value;
+
+      decimal d;
+      if (TokenType == JsonToken.String && decimal.TryParse((string)Value, NumberStyles.Number, CultureInfo.InvariantCulture, out d))
+      {
+        SetToken(JsonToken.Float, d);
+        return d;
+      }
+
+      throw CreateJsonReaderException("Unexpected token when reading decimal: {0}. Line {1}, position {2}.", TokenType, _currentLineNumber, _currentLinePosition);
+    }
+
+#if !NET20
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="Nullable{DateTimeOffset}"/>.
+    /// </summary>
+    /// <returns>A <see cref="DateTimeOffset"/>.</returns>
+    public override DateTimeOffset? ReadAsDateTimeOffset()
+    {
+      _readType = ReadType.ReadAsDateTimeOffset;
+
+      do
+      {
+        if (!ReadInternal())
+          throw CreateJsonReaderException("Unexpected end when reading date: Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
+      } while (TokenType == JsonToken.Comment);
+
+      if (TokenType == JsonToken.Null)
+        return null;
+      if (TokenType == JsonToken.Date)
+        return (DateTimeOffset)Value;
+
+      throw CreateJsonReaderException("Unexpected token when reading date: {0}. Line {1}, position {2}.", TokenType, _currentLineNumber, _currentLinePosition);
+    }
+#endif
+
+    private bool ReadInternal()
+    {
+      while (true)
+      {
+        char currentChar;
+        if (_lastChar != null)
+        {
+          currentChar = _lastChar.Value;
+          _lastChar = null;
+        }
+        else
+        {
+          currentChar = MoveNext();
+        }
+
+        if (currentChar == '\0' && _end)
+          return false;
+
+        switch (CurrentState)
+        {
+          case State.Start:
+          case State.Property:
+          case State.Array:
+          case State.ArrayStart:
+          case State.Constructor:
+          case State.ConstructorStart:
+            return ParseValue(currentChar);
+          case State.Complete:
+            break;
+          case State.Object:
+          case State.ObjectStart:
+            return ParseObject(currentChar);
+          case State.PostValue:
+            // returns true if it hits
+            // end of object or array
+            if (ParsePostValue(currentChar))
+              return true;
+            break;
+          case State.Closed:
+            break;
+          case State.Error:
+            break;
+          default:
+            throw CreateJsonReaderException("Unexpected state: {0}. Line {1}, position {2}.", CurrentState, _currentLineNumber, _currentLinePosition);
+        }
+      }
+    }
+
+    private bool ParsePostValue(char currentChar)
+    {
+      do
+      {
+        switch (currentChar)
+        {
+          case '}':
+            SetToken(JsonToken.EndObject);
+            return true;
+          case ']':
+            SetToken(JsonToken.EndArray);
+            return true;
+          case ')':
+            SetToken(JsonToken.EndConstructor);
+            return true;
+          case '/':
+            ParseComment();
+            return true;
+          case ',':
+            // finished parsing
+            SetStateBasedOnCurrent();
+            return false;
+          case ' ':
+          case StringUtils.Tab:
+          case StringUtils.LineFeed:
+          case StringUtils.CarriageReturn:
+            // eat
+            break;
+          default:
+            if (char.IsWhiteSpace(currentChar))
+            {
+              // eat
+            }
+            else
+            {
+              throw CreateJsonReaderException("After parsing a value an unexpected character was encountered: {0}. Line {1}, position {2}.", currentChar, _currentLineNumber, _currentLinePosition);
+            }
+            break;
+        }
+      } while ((currentChar = MoveNext()) != '\0' || !_end);
+
+      return false;
+    }
+
+    private bool ParseObject(char currentChar)
+    {
+      do
+      {
+        switch (currentChar)
+        {
+          case '}':
+            SetToken(JsonToken.EndObject);
+            return true;
+          case '/':
+            ParseComment();
+            return true;
+          case ' ':
+          case StringUtils.Tab:
+          case StringUtils.LineFeed:
+          case StringUtils.CarriageReturn:
+            // eat
+            break;
+          default:
+            if (char.IsWhiteSpace(currentChar))
+            {
+              // eat
+            }
+            else
+            {
+              return ParseProperty(currentChar);
+            }
+            break;
+        }
+      } while ((currentChar = MoveNext()) != '\0' || !_end);
+
+      return false;
+    }
+
+    private bool ParseProperty(char firstChar)
+    {
+      char currentChar = firstChar;
+      char quoteChar;
+
+      if (ValidIdentifierChar(currentChar))
+      {
+        quoteChar = '\0';
+        currentChar = ParseUnquotedProperty(currentChar);
+      }
+      else if (currentChar == '"' || currentChar == '\'')
+      {
+        quoteChar = currentChar;
+        ReadStringIntoBuffer(quoteChar);
+        currentChar = MoveNext();
+      }
+      else
+      {
+        throw CreateJsonReaderException("Invalid property identifier character: {0}. Line {1}, position {2}.", currentChar, _currentLineNumber, _currentLinePosition);
+      }
+
+      if (currentChar != ':')
+      {
+        currentChar = MoveNext();
+
+        // finished property. skip any whitespace and move to colon
+        EatWhitespace(currentChar, false, out currentChar);
+
+        if (currentChar != ':')
+          throw CreateJsonReaderException("Invalid character after parsing property name. Expected ':' but got: {0}. Line {1}, position {2}.", currentChar, _currentLineNumber, _currentLinePosition);
+      }
+
+      SetToken(JsonToken.PropertyName, _buffer.ToString());
+      QuoteChar = quoteChar;
+      _buffer.Position = 0;
+
+      return true;
+    }
+
+    private bool ValidIdentifierChar(char value)
+    {
+      return (char.IsLetterOrDigit(value) || value == '_' || value == '$');
+    }
+
+    private char ParseUnquotedProperty(char firstChar)
+    {
+      // parse unquoted property name until whitespace or colon
+      _buffer.Append(firstChar);
+
+      char currentChar;
+
+      while ((currentChar = MoveNext()) != '\0' || !_end)
+      {
+        if (char.IsWhiteSpace(currentChar) || currentChar == ':')
+        {
+          return currentChar;
+        }
+        else if (ValidIdentifierChar(currentChar))
+        {
+          _buffer.Append(currentChar);
+        }
+        else
+        {
+          throw CreateJsonReaderException("Invalid JavaScript property identifier character: {0}. Line {1}, position {2}.", currentChar, _currentLineNumber, _currentLinePosition);
+        }
+      }
+
+      throw CreateJsonReaderException("Unexpected end when parsing unquoted property name. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
+    }
+
+    private bool ParseValue(char currentChar)
+    {
+      do
+      {
+        switch (currentChar)
+        {
+          case '"':
+          case '\'':
+            ParseString(currentChar);
+            return true;
+          case 't':
+            ParseTrue();
+            return true;
+          case 'f':
+            ParseFalse();
+            return true;
+          case 'n':
+            if (HasNext())
+            {
+              char next = (char)PeekNext();
+
+              if (next == 'u')
+                ParseNull();
+              else if (next == 'e')
+                ParseConstructor();
+              else
+                throw CreateJsonReaderException("Unexpected character encountered while parsing value: {0}. Line {1}, position {2}.", currentChar, _currentLineNumber, _currentLinePosition);
+            }
+            else
+            {
+              throw CreateJsonReaderException("Unexpected end. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
+            }
+            return true;
+          case 'N':
+            ParseNumberNaN();
+            return true;
+          case 'I':
+            ParseNumberPositiveInfinity();
+            return true;
+          case '-':
+            if (PeekNext() == 'I')
+              ParseNumberNegativeInfinity();
+            else
+              ParseNumber(currentChar);
+            return true;
+          case '/':
+            ParseComment();
+            return true;
+          case 'u':
+            ParseUndefined();
+            return true;
+          case '{':
+            SetToken(JsonToken.StartObject);
+            return true;
+          case '[':
+            SetToken(JsonToken.StartArray);
+            return true;
+          case '}':
+            SetToken(JsonToken.EndObject);
+            return true;
+          case ']':
+            SetToken(JsonToken.EndArray);
+            return true;
+          case ',':
+            SetToken(JsonToken.Undefined);
+            return true;
+          case ')':
+            SetToken(JsonToken.EndConstructor);
+            return true;
+          case ' ':
+          case StringUtils.Tab:
+          case StringUtils.LineFeed:
+          case StringUtils.CarriageReturn:
+            // eat
+            break;
+          default:
+            if (char.IsWhiteSpace(currentChar))
+            {
+              // eat
+            }
+            else if (char.IsNumber(currentChar) || currentChar == '-' || currentChar == '.')
+            {
+              ParseNumber(currentChar);
+              return true;
+            }
+            else
+            {
+              throw CreateJsonReaderException("Unexpected character encountered while parsing value: {0}. Line {1}, position {2}.", currentChar, _currentLineNumber, _currentLinePosition);
+            }
+            break;
+        }
+      } while ((currentChar = MoveNext()) != '\0' || !_end);
+
+      return false;
+    }
+
+    private bool EatWhitespace(char initialChar, bool oneOrMore, out char finalChar)
+    {
+      bool whitespace = false;
+      char currentChar = initialChar;
+      while (currentChar == ' ' || char.IsWhiteSpace(currentChar))
+      {
+        whitespace = true;
+        currentChar = MoveNext();
+      }
+
+      finalChar = currentChar;
+
+      return (!oneOrMore || whitespace);
+    }
+
+    private void ParseConstructor()
+    {
+      if (MatchValue('n', "new", true))
+      {
+        char currentChar = MoveNext();
+
+        if (EatWhitespace(currentChar, true, out currentChar))
+        {
+          while (char.IsLetter(currentChar))
+          {
+            _buffer.Append(currentChar);
+            currentChar = MoveNext();
+          }
+
+          EatWhitespace(currentChar, false, out currentChar);
+
+          if (currentChar != '(')
+            throw CreateJsonReaderException("Unexpected character while parsing constructor: {0}. Line {1}, position {2}.", currentChar, _currentLineNumber, _currentLinePosition);
+
+          string constructorName = _buffer.ToString();
+          _buffer.Position = 0;
+
+          SetToken(JsonToken.StartConstructor, constructorName);
+        }
+      }
+    }
+
+    private void ParseNumber(char firstChar)
+    {
+      char currentChar = firstChar;
+
+      // parse until seperator character or end
+      bool end = false;
+      do
+      {
+        if (IsSeperator(currentChar))
+        {
+          end = true;
+          _lastChar = currentChar;
+        }
+        else
+        {
+          _buffer.Append(currentChar);
+        }
+
+      } while (!end && ((currentChar = MoveNext()) != '\0' || !_end));
+
+      string number = _buffer.ToString();
+      object numberValue;
+      JsonToken numberType;
+
+      bool nonBase10 = (firstChar == '0' && !number.StartsWith("0.", StringComparison.OrdinalIgnoreCase));
+
+      if (_readType == ReadType.ReadAsDecimal)
+      {
+        if (nonBase10)
+        {
+          // decimal.Parse doesn't support parsing hexadecimal values
+          long integer = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase)
+            ? Convert.ToInt64(number, 16)
+            : Convert.ToInt64(number, 8);
+
+          numberValue = Convert.ToDecimal(integer);
+        }
+        else
+        {
+          numberValue = decimal.Parse(number, NumberStyles.Number | NumberStyles.AllowExponent, CultureInfo.InvariantCulture);
+        }
+
+        numberType = JsonToken.Float;
+      }
+      else
+      {
+        if (nonBase10)
+        {
+          numberValue = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase)
+            ? Convert.ToInt64(number, 16)
+            : Convert.ToInt64(number, 8);
+          numberType = JsonToken.Integer;
+        }
+        else if (number.IndexOf(".", StringComparison.OrdinalIgnoreCase) != -1 || number.IndexOf("e", StringComparison.OrdinalIgnoreCase) != -1)
+        {
+          numberValue = Convert.ToDouble(number, CultureInfo.InvariantCulture);
+          numberType = JsonToken.Float;
+        }
+        else
+        {
+          try
+          {
+            numberValue = Convert.ToInt64(number, CultureInfo.InvariantCulture);
+          }
+          catch (OverflowException ex)
+          {
+            throw new JsonReaderException("JSON integer {0} is too large or small for an Int64.".FormatWith(CultureInfo.InvariantCulture, number), ex);
+          }
+
+          numberType = JsonToken.Integer;
+        }
+      }
+
+      _buffer.Position = 0;
+
+      SetToken(numberType, numberValue);
+    }
+
+    private void ParseComment()
+    {
+      // should have already parsed / character before reaching this method
+
+      char currentChar = MoveNext();
+
+      if (currentChar == '*')
+      {
+        while ((currentChar = MoveNext()) != '\0' || !_end)
+        {
+          if (currentChar == '*')
+          {
+            if ((currentChar = MoveNext()) != '\0' || !_end)
+            {
+              if (currentChar == '/')
+              {
+                break;
+              }
+              else
+              {
+                _buffer.Append('*');
+                _buffer.Append(currentChar);
+              }
+            }
+          }
+          else
+          {
+            _buffer.Append(currentChar);
+          }
+        }
+      }
+      else
+      {
+        throw CreateJsonReaderException("Error parsing comment. Expected: *. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
+      }
+
+      SetToken(JsonToken.Comment, _buffer.ToString());
+
+      _buffer.Position = 0;
+    }
+
+    private bool MatchValue(char firstChar, string value)
+    {
+      char currentChar = firstChar;
+
+      int i = 0;
+      do
+      {
+        if (currentChar != value[i])
+        {
+          break;
+        }
+        i++;
+      }
+      while (i < value.Length && ((currentChar = MoveNext()) != '\0' || !_end));
+
+      return (i == value.Length);
+    }
+
+    private bool MatchValue(char firstChar, string value, bool noTrailingNonSeperatorCharacters)
+    {
+      // will match value and then move to the next character, checking that it is a seperator character
+      bool match = MatchValue(firstChar, value);
+
+      if (!noTrailingNonSeperatorCharacters)
+      {
+        return match;
+      }
+      else
+      {
+        int c = PeekNext();
+        char next = (c != -1) ? (char) c : '\0';
+        bool matchAndNoTrainingNonSeperatorCharacters = (match && (next == '\0' || IsSeperator(next)));
+
+        return matchAndNoTrainingNonSeperatorCharacters;
+      }
+    }
+
+    private bool IsSeperator(char c)
+    {
+      switch (c)
+      {
+        case '}':
+        case ']':
+        case ',':
+          return true;
+        case '/':
+          // check next character to see if start of a comment
+          return (HasNext() && PeekNext() == '*');
+        case ')':
+          if (CurrentState == State.Constructor || CurrentState == State.ConstructorStart)
+            return true;
+          break;
+        case ' ':
+        case StringUtils.Tab:
+        case StringUtils.LineFeed:
+        case StringUtils.CarriageReturn:
+          return true;
+        default:
+          if (char.IsWhiteSpace(c))
+            return true;
+          break;
+      }
+
+      return false;
+    }
+
+    private void ParseTrue()
+    {
+      // check characters equal 'true'
+      // and that it is followed by either a seperator character
+      // or the text ends
+      if (MatchValue('t', JsonConvert.True, true))
+      {
+        SetToken(JsonToken.Boolean, true);
+      }
+      else
+      {
+        throw CreateJsonReaderException("Error parsing boolean value. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
+      }
+    }
+
+    private void ParseNull()
+    {
+      if (MatchValue('n', JsonConvert.Null, true))
+      {
+        SetToken(JsonToken.Null);
+      }
+      else
+      {
+        throw CreateJsonReaderException("Error parsing null value. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
+      }
+    }
+
+    private void ParseUndefined()
+    {
+      if (MatchValue('u', JsonConvert.Undefined, true))
+      {
+        SetToken(JsonToken.Undefined);
+      }
+      else
+      {
+        throw CreateJsonReaderException("Error parsing undefined value. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
+      }
+    }
+
+    private void ParseFalse()
+    {
+      if (MatchValue('f', JsonConvert.False, true))
+      {
+        SetToken(JsonToken.Boolean, false);
+      }
+      else
+      {
+        throw CreateJsonReaderException("Error parsing boolean value. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
+      }
+    }
+
+    private void ParseNumberNegativeInfinity()
+    {
+      if (MatchValue('-', JsonConvert.NegativeInfinity, true))
+      {
+        SetToken(JsonToken.Float, double.NegativeInfinity);
+      }
+      else
+      {
+        throw CreateJsonReaderException("Error parsing negative infinity value. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
+      }
+    }
+
+    private void ParseNumberPositiveInfinity()
+    {
+      if (MatchValue('I', JsonConvert.PositiveInfinity, true))
+      {
+        SetToken(JsonToken.Float, double.PositiveInfinity);
+      }
+      else
+      {
+        throw CreateJsonReaderException("Error parsing positive infinity value. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
+      }
+    }
+
+    private void ParseNumberNaN()
+    {
+      if (MatchValue('N', JsonConvert.NaN, true))
+      {
+        SetToken(JsonToken.Float, double.NaN);
+      }
+      else
+      {
+        throw CreateJsonReaderException("Error parsing NaN value. Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
+      }
+    }
+
+    /// <summary>
+    /// Changes the state to closed. 
+    /// </summary>
+    public override void Close()
+    {
+      base.Close();
+
+      if (CloseInput && _reader != null)
+        _reader.Close();
+
+      if (_buffer != null)
+        _buffer.Clear();
+    }
+
+    /// <summary>
+    /// Gets a value indicating whether the class can return line information.
+    /// </summary>
+    /// <returns>
+    ///        <c>true</c> if LineNumber and LinePosition can be provided; otherwise, <c>false</c>.
+    /// </returns>
+    public bool HasLineInfo()
+    {
+      return true;
+    }
+
+    /// <summary>
+    /// Gets the current line number.
+    /// </summary>
+    /// <value>
+    /// The current line number or 0 if no line information is available (for example, HasLineInfo returns false).
+    /// </value>
+    public int LineNumber
+    {
+      get
+      {
+        if (CurrentState == State.Start)
+          return 0;
+
+        return _currentLineNumber;
+      }
+    }
+
+    /// <summary>
+    /// Gets the current line position.
+    /// </summary>
+    /// <value>
+    /// The current line position or 0 if no line information is available (for example, HasLineInfo returns false).
+    /// </value>
+    public int LinePosition
+    {
+      get { return _currentLinePosition; }
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonTextWriter.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonTextWriter.cs
new file mode 100644 (file)
index 0000000..ea26daf
--- /dev/null
@@ -0,0 +1,490 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+using System.Xml;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Represents a writer that provides a fast, non-cached, forward-only way of generating Json data.
+  /// </summary>
+  public class JsonTextWriter : JsonWriter
+  {
+    private readonly TextWriter _writer;
+    private Base64Encoder _base64Encoder;
+    private char _indentChar;
+    private int _indentation;
+    private char _quoteChar;
+    private bool _quoteName;
+
+    private Base64Encoder Base64Encoder
+    {
+      get
+      {
+        if (_base64Encoder == null)
+          _base64Encoder = new Base64Encoder(_writer);
+
+        return _base64Encoder;
+      }
+    }
+
+    /// <summary>
+    /// Gets or sets how many IndentChars to write for each level in the hierarchy when <see cref="Formatting"/> is set to <c>Formatting.Indented</c>.
+    /// </summary>
+    public int Indentation
+    {
+      get { return _indentation; }
+      set
+      {
+        if (value < 0)
+          throw new ArgumentException("Indentation value must be greater than 0.");
+
+        _indentation = value;
+      }
+    }
+
+    /// <summary>
+    /// Gets or sets which character to use to quote attribute values.
+    /// </summary>
+    public char QuoteChar
+    {
+      get { return _quoteChar; }
+      set
+      {
+        if (value != '"' && value != '\'')
+          throw new ArgumentException(@"Invalid JavaScript string quote character. Valid quote characters are ' and "".");
+
+        _quoteChar = value;
+      }
+    }
+
+    /// <summary>
+    /// Gets or sets which character to use for indenting when <see cref="Formatting"/> is set to <c>Formatting.Indented</c>.
+    /// </summary>
+    public char IndentChar
+    {
+      get { return _indentChar; }
+      set { _indentChar = value; }
+    }
+
+    /// <summary>
+    /// Gets or sets a value indicating whether object names will be surrounded with quotes.
+    /// </summary>
+    public bool QuoteName
+    {
+      get { return _quoteName; }
+      set { _quoteName = value; }
+    }
+
+    /// <summary>
+    /// Creates an instance of the <c>JsonWriter</c> class using the specified <see cref="TextWriter"/>. 
+    /// </summary>
+    /// <param name="textWriter">The <c>TextWriter</c> to write to.</param>
+    public JsonTextWriter(TextWriter textWriter)
+    {
+      if (textWriter == null)
+        throw new ArgumentNullException("textWriter");
+
+      _writer = textWriter;
+      _quoteChar = '"';
+      _quoteName = true;
+      _indentChar = ' ';
+      _indentation = 2;
+    }
+
+    /// <summary>
+    /// Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream.
+    /// </summary>
+    public override void Flush()
+    {
+      _writer.Flush();
+    }
+
+    /// <summary>
+    /// Closes this stream and the underlying stream.
+    /// </summary>
+    public override void Close()
+    {
+      base.Close();
+
+      if (CloseOutput && _writer != null)
+        _writer.Close();
+    }
+
+    /// <summary>
+    /// Writes the beginning of a Json object.
+    /// </summary>
+    public override void WriteStartObject()
+    {
+      base.WriteStartObject();
+
+      _writer.Write("{");
+    }
+
+    /// <summary>
+    /// Writes the beginning of a Json array.
+    /// </summary>
+    public override void WriteStartArray()
+    {
+      base.WriteStartArray();
+
+      _writer.Write("[");
+    }
+
+    /// <summary>
+    /// Writes the start of a constructor with the given name.
+    /// </summary>
+    /// <param name="name">The name of the constructor.</param>
+    public override void WriteStartConstructor(string name)
+    {
+      base.WriteStartConstructor(name);
+
+      _writer.Write("new ");
+      _writer.Write(name);
+      _writer.Write("(");
+    }
+
+    /// <summary>
+    /// Writes the specified end token.
+    /// </summary>
+    /// <param name="token">The end token to write.</param>
+    protected override void WriteEnd(JsonToken token)
+    {
+      switch (token)
+      {
+        case JsonToken.EndObject:
+          _writer.Write("}");
+          break;
+        case JsonToken.EndArray:
+          _writer.Write("]");
+          break;
+        case JsonToken.EndConstructor:
+          _writer.Write(")");
+          break;
+        default:
+          throw new JsonWriterException("Invalid JsonToken: " + token);
+      }
+    }
+
+    /// <summary>
+    /// Writes the property name of a name/value pair on a Json object.
+    /// </summary>
+    /// <param name="name">The name of the property.</param>
+    public override void WritePropertyName(string name)
+    {
+      base.WritePropertyName(name);
+
+      JavaScriptUtils.WriteEscapedJavaScriptString(_writer, name, _quoteChar, _quoteName);
+
+      _writer.Write(':');
+    }
+
+    /// <summary>
+    /// Writes indent characters.
+    /// </summary>
+    protected override void WriteIndent()
+    {
+      if (Formatting == Formatting.Indented)
+      {
+        _writer.Write(Environment.NewLine);
+
+        // levels of indentation multiplied by the indent count
+        int currentIndentCount = Top * _indentation;
+
+        for (int i = 0; i < currentIndentCount; i++)
+        {
+          _writer.Write(_indentChar);
+        }
+      }
+    }
+
+    /// <summary>
+    /// Writes the JSON value delimiter.
+    /// </summary>
+    protected override void WriteValueDelimiter()
+    {
+      _writer.Write(',');
+    }
+
+    /// <summary>
+    /// Writes an indent space.
+    /// </summary>
+    protected override void WriteIndentSpace()
+    {
+      _writer.Write(' ');
+    }
+
+    private void WriteValueInternal(string value, JsonToken token)
+    {
+      _writer.Write(value);
+    }
+
+    #region WriteValue methods
+    /// <summary>
+    /// Writes a null value.
+    /// </summary>
+    public override void WriteNull()
+    {
+      base.WriteNull();
+      WriteValueInternal(JsonConvert.Null, JsonToken.Null);
+    }
+
+    /// <summary>
+    /// Writes an undefined value.
+    /// </summary>
+    public override void WriteUndefined()
+    {
+      base.WriteUndefined();
+      WriteValueInternal(JsonConvert.Undefined, JsonToken.Undefined);
+    }
+
+    /// <summary>
+    /// Writes raw JSON.
+    /// </summary>
+    /// <param name="json">The raw JSON to write.</param>
+    public override void WriteRaw(string json)
+    {
+      base.WriteRaw(json);
+
+      _writer.Write(json);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="String"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="String"/> value to write.</param>
+    public override void WriteValue(string value)
+    {
+      base.WriteValue(value);
+      if (value == null)
+        WriteValueInternal(JsonConvert.Null, JsonToken.Null);
+      else
+        JavaScriptUtils.WriteEscapedJavaScriptString(_writer, value, _quoteChar, true);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Int32"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Int32"/> value to write.</param>
+    public override void WriteValue(int value)
+    {
+      base.WriteValue(value);
+      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="UInt32"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="UInt32"/> value to write.</param>
+    [CLSCompliant(false)]
+    public override void WriteValue(uint value)
+    {
+      base.WriteValue(value);
+      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Int64"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Int64"/> value to write.</param>
+    public override void WriteValue(long value)
+    {
+      base.WriteValue(value);
+      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="UInt64"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="UInt64"/> value to write.</param>
+    [CLSCompliant(false)]
+    public override void WriteValue(ulong value)
+    {
+      base.WriteValue(value);
+      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Single"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Single"/> value to write.</param>
+    public override void WriteValue(float value)
+    {
+      base.WriteValue(value);
+      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Float);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Double"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Double"/> value to write.</param>
+    public override void WriteValue(double value)
+    {
+      base.WriteValue(value);
+      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Float);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Boolean"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Boolean"/> value to write.</param>
+    public override void WriteValue(bool value)
+    {
+      base.WriteValue(value);
+      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Boolean);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Int16"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Int16"/> value to write.</param>
+    public override void WriteValue(short value)
+    {
+      base.WriteValue(value);
+      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="UInt16"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="UInt16"/> value to write.</param>
+    [CLSCompliant(false)]
+    public override void WriteValue(ushort value)
+    {
+      base.WriteValue(value);
+      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Char"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Char"/> value to write.</param>
+    public override void WriteValue(char value)
+    {
+      base.WriteValue(value);
+      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Byte"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Byte"/> value to write.</param>
+    public override void WriteValue(byte value)
+    {
+      base.WriteValue(value);
+      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="SByte"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="SByte"/> value to write.</param>
+    [CLSCompliant(false)]
+    public override void WriteValue(sbyte value)
+    {
+      base.WriteValue(value);
+      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Decimal"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Decimal"/> value to write.</param>
+    public override void WriteValue(decimal value)
+    {
+      base.WriteValue(value);
+      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Float);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="DateTime"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="DateTime"/> value to write.</param>
+    public override void WriteValue(DateTime value)
+    {
+      base.WriteValue(value);
+      JsonConvert.WriteDateTimeString(_writer, value);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="T:Byte[]"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="T:Byte[]"/> value to write.</param>
+    public override void WriteValue(byte[] value)
+    {
+      base.WriteValue(value);
+
+      if (value != null)
+      {
+        _writer.Write(_quoteChar);
+        Base64Encoder.Encode(value, 0, value.Length);
+        Base64Encoder.Flush();
+        _writer.Write(_quoteChar);
+      }
+    }
+
+#if !PocketPC && !NET20
+    /// <summary>
+    /// Writes a <see cref="DateTimeOffset"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="DateTimeOffset"/> value to write.</param>
+    public override void WriteValue(DateTimeOffset value)
+    {
+      base.WriteValue(value);
+      WriteValueInternal(JsonConvert.ToString(value), JsonToken.Date);
+    }
+#endif
+    #endregion
+
+    /// <summary>
+    /// Writes out a comment <code>/*...*/</code> containing the specified text. 
+    /// </summary>
+    /// <param name="text">Text to place inside the comment.</param>
+    public override void WriteComment(string text)
+    {
+      base.WriteComment(text);
+
+      _writer.Write("/*");
+      _writer.Write(text);
+      _writer.Write("*/");
+    }
+
+    /// <summary>
+    /// Writes out the given white space.
+    /// </summary>
+    /// <param name="ws">The string of white space characters.</param>
+    public override void WriteWhitespace(string ws)
+    {
+      base.WriteWhitespace(ws);
+
+      _writer.Write(ws);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonToken.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonToken.cs
new file mode 100644 (file)
index 0000000..9be0d19
--- /dev/null
@@ -0,0 +1,110 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Specifies the type of Json token.
+  /// </summary>
+  public enum JsonToken
+  {
+    /// <summary>
+    /// This is returned by the <see cref="JsonReader"/> if a <see cref="JsonReader.Read"/> method has not been called. 
+    /// </summary>
+    None,
+    /// <summary>
+    /// An object start token.
+    /// </summary>
+    StartObject,
+    /// <summary>
+    /// An array start token.
+    /// </summary>
+    StartArray,
+    /// <summary>
+    /// A constructor start token.
+    /// </summary>
+    StartConstructor,
+    /// <summary>
+    /// An object property name.
+    /// </summary>
+    PropertyName,
+    /// <summary>
+    /// A comment.
+    /// </summary>
+    Comment,
+    /// <summary>
+    /// Raw JSON.
+    /// </summary>
+    Raw,
+    /// <summary>
+    /// An interger.
+    /// </summary>
+    Integer,
+    /// <summary>
+    /// A float.
+    /// </summary>
+    Float,
+    /// <summary>
+    /// A string.
+    /// </summary>
+    String,
+    /// <summary>
+    /// A boolean.
+    /// </summary>
+    Boolean,
+    /// <summary>
+    /// A null token.
+    /// </summary>
+    Null,
+    /// <summary>
+    /// An undefined token.
+    /// </summary>
+    Undefined,
+    /// <summary>
+    /// An object end token.
+    /// </summary>
+    EndObject,
+    /// <summary>
+    /// An array end token.
+    /// </summary>
+    EndArray,
+    /// <summary>
+    /// A constructor end token.
+    /// </summary>
+    EndConstructor,
+    /// <summary>
+    /// A Date.
+    /// </summary>
+    Date,
+    /// <summary>
+    /// Byte data.
+    /// </summary>
+    Bytes
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonValidatingReader.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonValidatingReader.cs
new file mode 100644 (file)
index 0000000..ab75cbc
--- /dev/null
@@ -0,0 +1,751 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Schema;
+using Newtonsoft.Json.Utilities;
+using System.Globalization;
+using System.Text.RegularExpressions;
+using System.IO;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Represents a reader that provides <see cref="JsonSchema"/> validation.
+  /// </summary>
+  public class JsonValidatingReader : JsonReader, IJsonLineInfo
+  {
+    private class SchemaScope
+    {
+      private readonly JTokenType _tokenType;
+      private readonly IList<JsonSchemaModel> _schemas;
+      private readonly Dictionary<string, bool> _requiredProperties;
+
+      public string CurrentPropertyName { get; set; }
+      public int ArrayItemCount { get; set; }
+
+      public IList<JsonSchemaModel> Schemas
+      {
+        get { return _schemas; }
+      }
+
+      public Dictionary<string, bool> RequiredProperties
+      {
+        get { return _requiredProperties; }
+      }
+
+      public JTokenType TokenType
+      {
+        get { return _tokenType; }
+      }
+
+      public SchemaScope(JTokenType tokenType, IList<JsonSchemaModel> schemas)
+      {
+        _tokenType = tokenType;
+        _schemas = schemas;
+
+        _requiredProperties = schemas.SelectMany<JsonSchemaModel, string>(GetRequiredProperties).Distinct().ToDictionary(p => p, p => false);
+      }
+
+      private IEnumerable<string> GetRequiredProperties(JsonSchemaModel schema)
+      {
+        if (schema == null || schema.Properties == null)
+          return Enumerable.Empty<string>();
+
+        return schema.Properties.Where(p => p.Value.Required).Select(p => p.Key);
+      }
+    }
+
+    private readonly JsonReader _reader;
+    private readonly Stack<SchemaScope> _stack;
+    private JsonSchema _schema;
+    private JsonSchemaModel _model;
+    private SchemaScope _currentScope;
+
+    /// <summary>
+    /// Sets an event handler for receiving schema validation errors.
+    /// </summary>
+    public event ValidationEventHandler ValidationEventHandler;
+
+    /// <summary>
+    /// Gets the text value of the current Json token.
+    /// </summary>
+    /// <value></value>
+    public override object Value
+    {
+      get { return _reader.Value; }
+    }
+
+    /// <summary>
+    /// Gets the depth of the current token in the JSON document.
+    /// </summary>
+    /// <value>The depth of the current token in the JSON document.</value>
+    public override int Depth
+    {
+      get { return _reader.Depth; }
+    }
+
+    /// <summary>
+    /// Gets the quotation mark character used to enclose the value of a string.
+    /// </summary>
+    /// <value></value>
+    public override char QuoteChar
+    {
+      get { return _reader.QuoteChar; }
+      protected internal set { }
+    }
+
+    /// <summary>
+    /// Gets the type of the current Json token.
+    /// </summary>
+    /// <value></value>
+    public override JsonToken TokenType
+    {
+      get { return _reader.TokenType; }
+    }
+
+    /// <summary>
+    /// Gets The Common Language Runtime (CLR) type for the current Json token.
+    /// </summary>
+    /// <value></value>
+    public override Type ValueType
+    {
+      get { return _reader.ValueType; }
+    }
+
+    private void Push(SchemaScope scope)
+    {
+      _stack.Push(scope);
+      _currentScope = scope;
+    }
+
+    private SchemaScope Pop()
+    {
+      SchemaScope poppedScope = _stack.Pop();
+      _currentScope = (_stack.Count != 0)
+        ? _stack.Peek()
+        : null;
+
+      return poppedScope;
+    }
+
+    private IEnumerable<JsonSchemaModel> CurrentSchemas
+    {
+      get { return _currentScope.Schemas; }
+    }
+
+    private IEnumerable<JsonSchemaModel> CurrentMemberSchemas
+    {
+      get
+      {
+        if (_currentScope == null)
+          return new List<JsonSchemaModel>(new [] { _model });
+
+        if (_currentScope.Schemas == null || _currentScope.Schemas.Count == 0)
+          return Enumerable.Empty<JsonSchemaModel>();
+
+        switch (_currentScope.TokenType)
+        {
+          case JTokenType.None:
+            return _currentScope.Schemas;
+          case JTokenType.Object:
+            {
+              if (_currentScope.CurrentPropertyName == null)
+                throw new Exception("CurrentPropertyName has not been set on scope.");
+
+              IList<JsonSchemaModel> schemas = new List<JsonSchemaModel>();
+
+              foreach (JsonSchemaModel schema in CurrentSchemas)
+              {
+                JsonSchemaModel propertySchema;
+                if (schema.Properties != null && schema.Properties.TryGetValue(_currentScope.CurrentPropertyName, out propertySchema))
+                {
+                  schemas.Add(propertySchema);
+                }
+                if (schema.PatternProperties != null)
+                {
+                  foreach (KeyValuePair<string, JsonSchemaModel> patternProperty in schema.PatternProperties)
+                  {
+                    if (Regex.IsMatch(_currentScope.CurrentPropertyName, patternProperty.Key))
+                    {
+                      schemas.Add(patternProperty.Value);
+                    }
+                  }
+                }
+
+                if (schemas.Count == 0 && schema.AllowAdditionalProperties && schema.AdditionalProperties != null)
+                  schemas.Add(schema.AdditionalProperties);
+              }
+
+              return schemas;
+            }
+          case JTokenType.Array:
+            {
+              IList<JsonSchemaModel> schemas = new List<JsonSchemaModel>();
+              
+              foreach (JsonSchemaModel schema in CurrentSchemas)
+              {
+                if (!CollectionUtils.IsNullOrEmpty(schema.Items))
+                {
+                  if (schema.Items.Count == 1)
+                    schemas.Add(schema.Items[0]);
+
+                  if (schema.Items.Count > (_currentScope.ArrayItemCount - 1))
+                    schemas.Add(schema.Items[_currentScope.ArrayItemCount - 1]);
+                }
+
+                if (schema.AllowAdditionalProperties && schema.AdditionalProperties != null)
+                  schemas.Add(schema.AdditionalProperties);
+              }
+
+              return schemas;
+            }
+          case JTokenType.Constructor:
+            return Enumerable.Empty<JsonSchemaModel>();
+          default:
+            throw new ArgumentOutOfRangeException("TokenType", "Unexpected token type: {0}".FormatWith(CultureInfo.InvariantCulture, _currentScope.TokenType));
+        }
+      }
+    }
+
+    private void RaiseError(string message, JsonSchemaModel schema)
+    {
+      IJsonLineInfo lineInfo = this;
+
+      string exceptionMessage = (lineInfo.HasLineInfo())
+                                  ? message + " Line {0}, position {1}.".FormatWith(CultureInfo.InvariantCulture, lineInfo.LineNumber, lineInfo.LinePosition)
+                                  : message;
+
+      OnValidationEvent(new JsonSchemaException(exceptionMessage, null, lineInfo.LineNumber, lineInfo.LinePosition));
+    }
+
+    private void OnValidationEvent(JsonSchemaException exception)
+    {
+      ValidationEventHandler handler = ValidationEventHandler;
+      if (handler != null)
+        handler(this, new ValidationEventArgs(exception));
+      else
+        throw exception;
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonValidatingReader"/> class that
+    /// validates the content returned from the given <see cref="JsonReader"/>.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read from while validating.</param>
+    public JsonValidatingReader(JsonReader reader)
+    {
+      ValidationUtils.ArgumentNotNull(reader, "reader");
+      _reader = reader;
+      _stack = new Stack<SchemaScope>();
+    }
+
+    /// <summary>
+    /// Gets or sets the schema.
+    /// </summary>
+    /// <value>The schema.</value>
+    public JsonSchema Schema
+    {
+      get { return _schema; }
+      set
+      {
+        if (TokenType != JsonToken.None)
+          throw new Exception("Cannot change schema while validating JSON.");
+
+        _schema = value;
+        _model = null;
+      }
+    }
+
+    /// <summary>
+    /// Gets the <see cref="JsonReader"/> used to construct this <see cref="JsonValidatingReader"/>.
+    /// </summary>
+    /// <value>The <see cref="JsonReader"/> specified in the constructor.</value>
+    public JsonReader Reader
+    {
+      get { return _reader; }
+    }
+
+    private void ValidateInEnumAndNotDisallowed(JsonSchemaModel schema)
+    {
+      if (schema == null)
+        return;
+
+      JToken value = new JValue(_reader.Value);
+
+      if (schema.Enum != null)
+      {
+        StringWriter sw = new StringWriter(CultureInfo.InvariantCulture);
+        value.WriteTo(new JsonTextWriter(sw));
+        if (!schema.Enum.ContainsValue(value, new JTokenEqualityComparer()))
+          RaiseError("Value {0} is not defined in enum.".FormatWith(CultureInfo.InvariantCulture, sw.ToString()),
+                     schema);
+      }
+
+      JsonSchemaType? currentNodeType = GetCurrentNodeSchemaType();
+      if (currentNodeType != null)
+      {
+        if (JsonSchemaGenerator.HasFlag(schema.Disallow, currentNodeType.Value))
+          RaiseError("Type {0} is disallowed.".FormatWith(CultureInfo.InvariantCulture, currentNodeType), schema);
+      }
+    }
+
+    private JsonSchemaType? GetCurrentNodeSchemaType()
+    {
+      switch (_reader.TokenType)
+      {
+        case JsonToken.StartObject:
+          return JsonSchemaType.Object;
+        case JsonToken.StartArray:
+          return JsonSchemaType.Array;
+        case JsonToken.Integer:
+          return JsonSchemaType.Integer;
+        case JsonToken.Float:
+          return JsonSchemaType.Float;
+        case JsonToken.String:
+          return JsonSchemaType.String;
+        case JsonToken.Boolean:
+          return JsonSchemaType.Boolean;
+        case JsonToken.Null:
+          return JsonSchemaType.Null;
+        default:
+          return null;
+      }
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="T:Byte[]"/>.
+    /// </summary>
+    /// <returns>
+    /// A <see cref="T:Byte[]"/> or a null reference if the next JSON token is null.
+    /// </returns>
+    public override byte[] ReadAsBytes()
+    {
+      byte[] data = _reader.ReadAsBytes();
+
+      ValidateCurrentToken();
+      return data;
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="Nullable{Decimal}"/>.
+    /// </summary>
+    /// <returns>A <see cref="Nullable{Decimal}"/>.</returns>
+    public override decimal? ReadAsDecimal()
+    {
+      decimal? d = _reader.ReadAsDecimal();
+
+      ValidateCurrentToken();
+      return d;
+    }
+
+#if !NET20
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="Nullable{DateTimeOffset}"/>.
+    /// </summary>
+    /// <returns>A <see cref="Nullable{DateTimeOffset}"/>.</returns>
+    public override DateTimeOffset? ReadAsDateTimeOffset()
+    {
+      DateTimeOffset? dateTimeOffset = _reader.ReadAsDateTimeOffset();
+
+      ValidateCurrentToken();
+      return dateTimeOffset;
+    }
+#endif
+
+    /// <summary>
+    /// Reads the next JSON token from the stream.
+    /// </summary>
+    /// <returns>
+    /// true if the next token was read successfully; false if there are no more tokens to read.
+    /// </returns>
+    public override bool Read()
+    {
+      if (!_reader.Read())
+        return false;
+
+      if (_reader.TokenType == JsonToken.Comment)
+        return true;
+
+      ValidateCurrentToken();
+      return true;
+    }
+
+    private void ValidateCurrentToken()
+    {
+      // first time validate has been called. build model
+      if (_model == null)
+      {
+        JsonSchemaModelBuilder builder = new JsonSchemaModelBuilder();
+        _model = builder.Build(_schema);
+      }
+
+      //ValidateValueToken();
+
+      switch (_reader.TokenType)
+      {
+        case JsonToken.StartObject:
+          ProcessValue();
+          IList<JsonSchemaModel> objectSchemas = CurrentMemberSchemas.Where(ValidateObject).ToList();
+          Push(new SchemaScope(JTokenType.Object, objectSchemas));
+          break;
+        case JsonToken.StartArray:
+          ProcessValue();
+          IList<JsonSchemaModel> arraySchemas = CurrentMemberSchemas.Where(ValidateArray).ToList();
+          Push(new SchemaScope(JTokenType.Array, arraySchemas));
+          break;
+        case JsonToken.StartConstructor:
+          Push(new SchemaScope(JTokenType.Constructor, null));
+          break;
+        case JsonToken.PropertyName:
+          foreach (JsonSchemaModel schema in CurrentSchemas)
+          {
+            ValidatePropertyName(schema);
+          }
+          break;
+        case JsonToken.Raw:
+          break;
+        case JsonToken.Integer:
+          ProcessValue();
+          foreach (JsonSchemaModel schema in CurrentMemberSchemas)
+          {
+            ValidateInteger(schema);
+          }
+          break;
+        case JsonToken.Float:
+          ProcessValue();
+          foreach (JsonSchemaModel schema in CurrentMemberSchemas)
+          {
+            ValidateFloat(schema);
+          }
+          break;
+        case JsonToken.String:
+          ProcessValue();
+          foreach (JsonSchemaModel schema in CurrentMemberSchemas)
+          {
+            ValidateString(schema);
+          }
+          break;
+        case JsonToken.Boolean:
+          ProcessValue();
+          foreach (JsonSchemaModel schema in CurrentMemberSchemas)
+          {
+            ValidateBoolean(schema);
+          }
+          break;
+        case JsonToken.Null:
+          ProcessValue();
+          foreach (JsonSchemaModel schema in CurrentMemberSchemas)
+          {
+            ValidateNull(schema);
+          }
+          break;
+        case JsonToken.Undefined:
+          break;
+        case JsonToken.EndObject:
+          foreach (JsonSchemaModel schema in CurrentSchemas)
+          {
+            ValidateEndObject(schema);
+          }
+          Pop();
+          break;
+        case JsonToken.EndArray:
+          foreach (JsonSchemaModel schema in CurrentSchemas)
+          {
+            ValidateEndArray(schema);
+          }
+          Pop();
+          break;
+        case JsonToken.EndConstructor:
+          Pop();
+          break;
+        case JsonToken.Date:
+          break;
+        default:
+          throw new ArgumentOutOfRangeException();
+      }
+    }
+
+    private void ValidateEndObject(JsonSchemaModel schema)
+    {
+      if (schema == null)
+        return;
+
+      Dictionary<string, bool> requiredProperties = _currentScope.RequiredProperties;
+
+      if (requiredProperties != null)
+      {
+        List<string> unmatchedRequiredProperties =
+          requiredProperties.Where(kv => !kv.Value).Select(kv => kv.Key).ToList();
+
+        if (unmatchedRequiredProperties.Count > 0)
+          RaiseError("Required properties are missing from object: {0}.".FormatWith(CultureInfo.InvariantCulture, string.Join(", ", unmatchedRequiredProperties.ToArray())), schema);
+      }
+    }
+
+    private void ValidateEndArray(JsonSchemaModel schema)
+    {
+      if (schema == null)
+        return;
+
+      int arrayItemCount = _currentScope.ArrayItemCount;
+
+      if (schema.MaximumItems != null && arrayItemCount > schema.MaximumItems)
+        RaiseError("Array item count {0} exceeds maximum count of {1}.".FormatWith(CultureInfo.InvariantCulture, arrayItemCount, schema.MaximumItems), schema);
+
+      if (schema.MinimumItems != null && arrayItemCount < schema.MinimumItems)
+        RaiseError("Array item count {0} is less than minimum count of {1}.".FormatWith(CultureInfo.InvariantCulture, arrayItemCount, schema.MinimumItems), schema);
+    }
+
+    private void ValidateNull(JsonSchemaModel schema)
+    {
+      if (schema == null)
+        return;
+
+      if (!TestType(schema, JsonSchemaType.Null))
+        return;
+
+      ValidateInEnumAndNotDisallowed(schema);
+    }
+
+    private void ValidateBoolean(JsonSchemaModel schema)
+    {
+      if (schema == null)
+        return;
+
+      if (!TestType(schema, JsonSchemaType.Boolean))
+        return;
+
+      ValidateInEnumAndNotDisallowed(schema);
+    }
+
+    private void ValidateString(JsonSchemaModel schema)
+    {
+      if (schema == null)
+        return;
+
+      if (!TestType(schema, JsonSchemaType.String))
+        return;
+
+      ValidateInEnumAndNotDisallowed(schema);
+
+      string value = _reader.Value.ToString();
+
+      if (schema.MaximumLength != null && value.Length > schema.MaximumLength)
+        RaiseError("String '{0}' exceeds maximum length of {1}.".FormatWith(CultureInfo.InvariantCulture, value, schema.MaximumLength), schema);
+
+      if (schema.MinimumLength != null && value.Length < schema.MinimumLength)
+        RaiseError("String '{0}' is less than minimum length of {1}.".FormatWith(CultureInfo.InvariantCulture, value, schema.MinimumLength), schema);
+
+      if (schema.Patterns != null)
+      {
+        foreach (string pattern in schema.Patterns)
+        {
+          if (!Regex.IsMatch(value, pattern))
+            RaiseError("String '{0}' does not match regex pattern '{1}'.".FormatWith(CultureInfo.InvariantCulture, value, pattern), schema);
+        }
+      }
+    }
+
+    private void ValidateInteger(JsonSchemaModel schema)
+    {
+      if (schema == null)
+        return;
+
+      if (!TestType(schema, JsonSchemaType.Integer))
+        return;
+
+      ValidateInEnumAndNotDisallowed(schema);
+      
+      long value = Convert.ToInt64(_reader.Value, CultureInfo.InvariantCulture);
+
+      if (schema.Maximum != null)
+      {
+        if (value > schema.Maximum)
+          RaiseError("Integer {0} exceeds maximum value of {1}.".FormatWith(CultureInfo.InvariantCulture, value, schema.Maximum), schema);
+        if (schema.ExclusiveMaximum && value == schema.Maximum)
+          RaiseError("Integer {0} equals maximum value of {1} and exclusive maximum is true.".FormatWith(CultureInfo.InvariantCulture, value, schema.Maximum), schema);
+      }
+
+      if (schema.Minimum != null)
+      {
+        if (value < schema.Minimum)
+          RaiseError("Integer {0} is less than minimum value of {1}.".FormatWith(CultureInfo.InvariantCulture, value, schema.Minimum), schema);
+        if (schema.ExclusiveMinimum && value == schema.Minimum)
+          RaiseError("Integer {0} equals minimum value of {1} and exclusive minimum is true.".FormatWith(CultureInfo.InvariantCulture, value, schema.Minimum), schema);
+      }
+
+      if (schema.DivisibleBy != null && !IsZero(value % schema.DivisibleBy.Value))
+        RaiseError("Integer {0} is not evenly divisible by {1}.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(value), schema.DivisibleBy), schema);
+    }
+
+    private void ProcessValue()
+    {
+      if (_currentScope != null && _currentScope.TokenType == JTokenType.Array)
+      {
+        _currentScope.ArrayItemCount++;
+
+        foreach (JsonSchemaModel currentSchema in CurrentSchemas)
+        {
+          if (currentSchema != null && currentSchema.Items != null && currentSchema.Items.Count > 1 && _currentScope.ArrayItemCount >= currentSchema.Items.Count)
+            RaiseError("Index {0} has not been defined and the schema does not allow additional items.".FormatWith(CultureInfo.InvariantCulture, _currentScope.ArrayItemCount), currentSchema);
+        }
+      }
+    }
+
+    private void ValidateFloat(JsonSchemaModel schema)
+    {
+      if (schema == null)
+        return;
+
+      if (!TestType(schema, JsonSchemaType.Float))
+        return;
+
+      ValidateInEnumAndNotDisallowed(schema);
+      
+      double value = Convert.ToDouble(_reader.Value, CultureInfo.InvariantCulture);
+
+      if (schema.Maximum != null)
+      {
+        if (value > schema.Maximum)
+          RaiseError("Float {0} exceeds maximum value of {1}.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(value), schema.Maximum), schema);
+        if (schema.ExclusiveMaximum && value == schema.Maximum)
+          RaiseError("Float {0} equals maximum value of {1} and exclusive maximum is true.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(value), schema.Maximum), schema);
+      }
+
+      if (schema.Minimum != null)
+      {
+        if (value < schema.Minimum)
+          RaiseError("Float {0} is less than minimum value of {1}.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(value), schema.Minimum), schema);
+        if (schema.ExclusiveMinimum && value == schema.Minimum)
+          RaiseError("Float {0} equals minimum value of {1} and exclusive minimum is true.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(value), schema.Minimum), schema);
+      }
+
+      if (schema.DivisibleBy != null && !IsZero(value % schema.DivisibleBy.Value))
+        RaiseError("Float {0} is not evenly divisible by {1}.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(value), schema.DivisibleBy), schema);
+    }
+
+    private static bool IsZero(double value)
+    {
+      double epsilon = 2.2204460492503131e-016;
+
+      return Math.Abs(value) < 10.0 * epsilon;
+    }
+
+    private void ValidatePropertyName(JsonSchemaModel schema)
+    {
+      if (schema == null)
+        return;
+
+      string propertyName = Convert.ToString(_reader.Value, CultureInfo.InvariantCulture);
+
+      if (_currentScope.RequiredProperties.ContainsKey(propertyName))
+        _currentScope.RequiredProperties[propertyName] = true;
+
+      if (!schema.AllowAdditionalProperties)
+      {
+        bool propertyDefinied = IsPropertyDefinied(schema, propertyName);
+
+        if (!propertyDefinied)
+          RaiseError("Property '{0}' has not been defined and the schema does not allow additional properties.".FormatWith(CultureInfo.InvariantCulture, propertyName), schema);
+      }
+
+      _currentScope.CurrentPropertyName = propertyName;
+    }
+
+    private bool IsPropertyDefinied(JsonSchemaModel schema, string propertyName)
+    {
+      if (schema.Properties != null && schema.Properties.ContainsKey(propertyName))
+        return true;
+
+      if (schema.PatternProperties != null)
+      {
+        foreach (string pattern in schema.PatternProperties.Keys)
+        {
+          if (Regex.IsMatch(propertyName, pattern))
+            return true;
+        }
+      }
+
+      return false;
+    }
+
+    private bool ValidateArray(JsonSchemaModel schema)
+    {
+      if (schema == null)
+        return true;
+
+      return (TestType(schema, JsonSchemaType.Array));
+    }
+
+    private bool ValidateObject(JsonSchemaModel schema)
+    {
+      if (schema == null)
+        return true;
+
+      return (TestType(schema, JsonSchemaType.Object));
+    }
+
+    private bool TestType(JsonSchemaModel currentSchema, JsonSchemaType currentType)
+    {
+      if (!JsonSchemaGenerator.HasFlag(currentSchema.Type, currentType))
+      {
+        RaiseError("Invalid type. Expected {0} but got {1}.".FormatWith(CultureInfo.InvariantCulture, currentSchema.Type, currentType), currentSchema);
+        return false;
+      }
+
+      return true;
+    }
+
+    bool IJsonLineInfo.HasLineInfo()
+    {
+      IJsonLineInfo lineInfo = _reader as IJsonLineInfo;
+      return (lineInfo != null) ? lineInfo.HasLineInfo() : false;
+    }
+
+    int IJsonLineInfo.LineNumber
+    {
+      get
+      {
+        IJsonLineInfo lineInfo = _reader as IJsonLineInfo;
+        return (lineInfo != null) ? lineInfo.LineNumber : 0;
+      }
+    }
+
+    int IJsonLineInfo.LinePosition
+    {
+      get
+      {
+        IJsonLineInfo lineInfo = _reader as IJsonLineInfo;
+        return (lineInfo != null) ? lineInfo.LinePosition : 0;
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonWriter.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonWriter.cs
new file mode 100644 (file)
index 0000000..f86a1cf
--- /dev/null
@@ -0,0 +1,1134 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+using System.Xml;
+using Newtonsoft.Json.Utilities;
+using Newtonsoft.Json.Linq;
+using System.Globalization;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Specifies the state of the <see cref="JsonWriter"/>.
+  /// </summary>
+  public enum WriteState
+  {
+    /// <summary>
+    /// An exception has been thrown, which has left the <see cref="JsonWriter"/> in an invalid state.
+    /// You may call the <see cref="JsonWriter.Close"/> method to put the <see cref="JsonWriter"/> in the <c>Closed</c> state.
+    /// Any other <see cref="JsonWriter"/> method calls results in an <see cref="InvalidOperationException"/> being thrown. 
+    /// </summary>
+    Error,
+    /// <summary>
+    /// The <see cref="JsonWriter.Close"/> method has been called. 
+    /// </summary>
+    Closed,
+    /// <summary>
+    /// An object is being written. 
+    /// </summary>
+    Object,
+    /// <summary>
+    /// A array is being written.
+    /// </summary>
+    Array,
+    /// <summary>
+    /// A constructor is being written.
+    /// </summary>
+    Constructor,
+    /// <summary>
+    /// A property is being written.
+    /// </summary>
+    Property,
+    /// <summary>
+    /// A write method has not been called.
+    /// </summary>
+    Start
+  }
+
+  /// <summary>
+  /// Specifies formatting options for the <see cref="JsonTextWriter"/>.
+  /// </summary>
+  public enum Formatting
+  {
+    /// <summary>
+    /// No special formatting is applied. This is the default.
+    /// </summary>
+    None,
+    /// <summary>
+    /// Causes child objects to be indented according to the <see cref="JsonTextWriter.Indentation"/> and <see cref="JsonTextWriter.IndentChar"/> settings.
+    /// </summary>
+    Indented
+  }
+
+  /// <summary>
+  /// Represents a writer that provides a fast, non-cached, forward-only way of generating Json data.
+  /// </summary>
+  public abstract class JsonWriter : IDisposable
+  {
+    private enum State
+    {
+      Start,
+      Property,
+      ObjectStart,
+      Object,
+      ArrayStart,
+      Array,
+      ConstructorStart,
+      Constructor,
+      Bytes,
+      Closed,
+      Error
+    }
+
+    // array that gives a new state based on the current state an the token being written
+    private static readonly State[][] stateArray = new[] {
+//                      Start                   PropertyName            ObjectStart         Object            ArrayStart              Array                   ConstructorStart        Constructor             Closed          Error
+//                        
+/* None             */new[]{ State.Error,            State.Error,            State.Error,        State.Error,      State.Error,            State.Error,            State.Error,            State.Error,            State.Error,    State.Error },
+/* StartObject      */new[]{ State.ObjectStart,      State.ObjectStart,      State.Error,        State.Error,      State.ObjectStart,      State.ObjectStart,      State.ObjectStart,      State.ObjectStart,      State.Error,    State.Error },
+/* StartArray       */new[]{ State.ArrayStart,       State.ArrayStart,       State.Error,        State.Error,      State.ArrayStart,       State.ArrayStart,       State.ArrayStart,       State.ArrayStart,       State.Error,    State.Error },
+/* StartConstructor */new[]{ State.ConstructorStart, State.ConstructorStart, State.Error,        State.Error,      State.ConstructorStart, State.ConstructorStart, State.ConstructorStart, State.ConstructorStart, State.Error,    State.Error },
+/* StartProperty    */new[]{ State.Property,         State.Error,            State.Property,     State.Property,   State.Error,            State.Error,            State.Error,            State.Error,            State.Error,    State.Error },
+/* Comment          */new[]{ State.Start,            State.Property,         State.ObjectStart,  State.Object,     State.ArrayStart,       State.Array,            State.Constructor,      State.Constructor,      State.Error,    State.Error },
+/* Raw              */new[]{ State.Start,            State.Property,         State.ObjectStart,  State.Object,     State.ArrayStart,       State.Array,            State.Constructor,      State.Constructor,      State.Error,    State.Error },
+/* Value            */new[]{ State.Start,            State.Object,           State.Error,        State.Error,      State.Array,            State.Array,            State.Constructor,      State.Constructor,      State.Error,    State.Error },
+               };
+
+    private int _top;
+
+    private readonly List<JTokenType> _stack;
+    private State _currentState;
+    private Formatting _formatting;
+
+    /// <summary>
+    /// Gets or sets a value indicating whether the underlying stream or
+    /// <see cref="TextReader"/> should be closed when the writer is closed.
+    /// </summary>
+    /// <value>
+    /// true to close the underlying stream or <see cref="TextReader"/> when
+    /// the writer is closed; otherwise false. The default is true.
+    /// </value>
+    public bool CloseOutput { get; set; }
+
+    /// <summary>
+    /// Gets the top.
+    /// </summary>
+    /// <value>The top.</value>
+    protected internal int Top
+    {
+      get { return _top; }
+    }
+
+    /// <summary>
+    /// Gets the state of the writer.
+    /// </summary>
+    public WriteState WriteState
+    {
+      get
+      {
+        switch (_currentState)
+        {
+          case State.Error:
+            return WriteState.Error;
+          case State.Closed:
+            return WriteState.Closed;
+          case State.Object:
+          case State.ObjectStart:
+            return WriteState.Object;
+          case State.Array:
+          case State.ArrayStart:
+            return WriteState.Array;
+          case State.Constructor:
+          case State.ConstructorStart:
+            return WriteState.Constructor;
+          case State.Property:
+            return WriteState.Property;
+          case State.Start:
+            return WriteState.Start;
+          default:
+            throw new JsonWriterException("Invalid state: " + _currentState);
+        }
+      }
+    }
+
+    /// <summary>
+    /// Indicates how the output is formatted.
+    /// </summary>
+    public Formatting Formatting
+    {
+      get { return _formatting; }
+      set { _formatting = value; }
+    }
+
+    /// <summary>
+    /// Creates an instance of the <c>JsonWriter</c> class. 
+    /// </summary>
+    protected JsonWriter()
+    {
+      _stack = new List<JTokenType>(8);
+      _stack.Add(JTokenType.None);
+      _currentState = State.Start;
+      _formatting = Formatting.None;
+
+      CloseOutput = true;
+    }
+
+    private void Push(JTokenType value)
+    {
+      _top++;
+      if (_stack.Count <= _top)
+        _stack.Add(value);
+      else
+        _stack[_top] = value;
+    }
+
+    private JTokenType Pop()
+    {
+      JTokenType value = Peek();
+      _top--;
+
+      return value;
+    }
+
+    private JTokenType Peek()
+    {
+      return _stack[_top];
+    }
+
+    /// <summary>
+    /// Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream.
+    /// </summary>
+    public abstract void Flush();
+
+    /// <summary>
+    /// Closes this stream and the underlying stream.
+    /// </summary>
+    public virtual void Close()
+    {
+      AutoCompleteAll();
+    }
+
+    /// <summary>
+    /// Writes the beginning of a Json object.
+    /// </summary>
+    public virtual void WriteStartObject()
+    {
+      AutoComplete(JsonToken.StartObject);
+      Push(JTokenType.Object);
+    }
+
+    /// <summary>
+    /// Writes the end of a Json object.
+    /// </summary>
+    public void WriteEndObject()
+    {
+      AutoCompleteClose(JsonToken.EndObject);
+    }
+
+    /// <summary>
+    /// Writes the beginning of a Json array.
+    /// </summary>
+    public virtual void WriteStartArray()
+    {
+      AutoComplete(JsonToken.StartArray);
+      Push(JTokenType.Array);
+    }
+
+    /// <summary>
+    /// Writes the end of an array.
+    /// </summary>
+    public void WriteEndArray()
+    {
+      AutoCompleteClose(JsonToken.EndArray);
+    }
+
+    /// <summary>
+    /// Writes the start of a constructor with the given name.
+    /// </summary>
+    /// <param name="name">The name of the constructor.</param>
+    public virtual void WriteStartConstructor(string name)
+    {
+      AutoComplete(JsonToken.StartConstructor);
+      Push(JTokenType.Constructor);
+    }
+
+    /// <summary>
+    /// Writes the end constructor.
+    /// </summary>
+    public void WriteEndConstructor()
+    {
+      AutoCompleteClose(JsonToken.EndConstructor);
+    }
+
+    /// <summary>
+    /// Writes the property name of a name/value pair on a Json object.
+    /// </summary>
+    /// <param name="name">The name of the property.</param>
+    public virtual void WritePropertyName(string name)
+    {
+      AutoComplete(JsonToken.PropertyName);
+    }
+
+    /// <summary>
+    /// Writes the end of the current Json object or array.
+    /// </summary>
+    public void WriteEnd()
+    {
+      WriteEnd(Peek());
+    }
+
+    /// <summary>
+    /// Writes the current <see cref="JsonReader"/> token.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> to read the token from.</param>
+    public void WriteToken(JsonReader reader)
+    {
+      ValidationUtils.ArgumentNotNull(reader, "reader");
+
+      int initialDepth;
+
+      if (reader.TokenType == JsonToken.None)
+        initialDepth = -1;
+      else if (!IsStartToken(reader.TokenType))
+        initialDepth = reader.Depth + 1;
+      else
+        initialDepth = reader.Depth;
+
+      WriteToken(reader, initialDepth);
+    }
+
+    internal void WriteToken(JsonReader reader, int initialDepth)
+    {
+      do
+      {
+        switch (reader.TokenType)
+        {
+          case JsonToken.None:
+            // read to next
+            break;
+          case JsonToken.StartObject:
+            WriteStartObject();
+            break;
+          case JsonToken.StartArray:
+            WriteStartArray();
+            break;
+          case JsonToken.StartConstructor:
+            string constructorName = reader.Value.ToString();
+            // write a JValue date when the constructor is for a date
+            if (string.Compare(constructorName, "Date", StringComparison.Ordinal) == 0)
+              WriteConstructorDate(reader);
+            else
+              WriteStartConstructor(reader.Value.ToString());
+            break;
+          case JsonToken.PropertyName:
+            WritePropertyName(reader.Value.ToString());
+            break;
+          case JsonToken.Comment:
+            WriteComment(reader.Value.ToString());
+            break;
+          case JsonToken.Integer:
+            WriteValue((long)reader.Value);
+            break;
+          case JsonToken.Float:
+            WriteValue((double)reader.Value);
+            break;
+          case JsonToken.String:
+            WriteValue(reader.Value.ToString());
+            break;
+          case JsonToken.Boolean:
+            WriteValue((bool)reader.Value);
+            break;
+          case JsonToken.Null:
+            WriteNull();
+            break;
+          case JsonToken.Undefined:
+            WriteUndefined();
+            break;
+          case JsonToken.EndObject:
+            WriteEndObject();
+            break;
+          case JsonToken.EndArray:
+            WriteEndArray();
+            break;
+          case JsonToken.EndConstructor:
+            WriteEndConstructor();
+            break;
+          case JsonToken.Date:
+            WriteValue((DateTime)reader.Value);
+            break;
+          case JsonToken.Raw:
+            WriteRawValue((string)reader.Value);
+            break;
+          case JsonToken.Bytes:
+            WriteValue((byte[])reader.Value);
+            break;
+          default:
+            throw MiscellaneousUtils.CreateArgumentOutOfRangeException("TokenType", reader.TokenType, "Unexpected token type.");
+        }
+      }
+      while (
+        // stop if we have reached the end of the token being read
+        initialDepth - 1 < reader.Depth - (IsEndToken(reader.TokenType) ? 1 : 0)
+        && reader.Read());
+    }
+
+    private void WriteConstructorDate(JsonReader reader)
+    {
+      if (!reader.Read())
+        throw new Exception("Unexpected end while reading date constructor.");
+      if (reader.TokenType != JsonToken.Integer)
+        throw new Exception("Unexpected token while reading date constructor. Expected Integer, got " + reader.TokenType);
+
+      long ticks = (long)reader.Value;
+      DateTime date = JsonConvert.ConvertJavaScriptTicksToDateTime(ticks);
+
+      if (!reader.Read())
+        throw new Exception("Unexpected end while reading date constructor.");
+      if (reader.TokenType != JsonToken.EndConstructor)
+        throw new Exception("Unexpected token while reading date constructor. Expected EndConstructor, got " + reader.TokenType);
+
+      WriteValue(date);
+    }
+
+    private bool IsEndToken(JsonToken token)
+    {
+      switch (token)
+      {
+        case JsonToken.EndObject:
+        case JsonToken.EndArray:
+        case JsonToken.EndConstructor:
+          return true;
+        default:
+          return false;
+      }
+    }
+
+    private bool IsStartToken(JsonToken token)
+    {
+      switch (token)
+      {
+        case JsonToken.StartObject:
+        case JsonToken.StartArray:
+        case JsonToken.StartConstructor:
+          return true;
+        default:
+          return false;
+      }
+    }
+
+    private void WriteEnd(JTokenType type)
+    {
+      switch (type)
+      {
+        case JTokenType.Object:
+          WriteEndObject();
+          break;
+        case JTokenType.Array:
+          WriteEndArray();
+          break;
+        case JTokenType.Constructor:
+          WriteEndConstructor();
+          break;
+        default:
+          throw new JsonWriterException("Unexpected type when writing end: " + type);
+      }
+    }
+
+    private void AutoCompleteAll()
+    {
+      while (_top > 0)
+      {
+        WriteEnd();
+      }
+    }
+
+    private JTokenType GetTypeForCloseToken(JsonToken token)
+    {
+      switch (token)
+      {
+        case JsonToken.EndObject:
+          return JTokenType.Object;
+        case JsonToken.EndArray:
+          return JTokenType.Array;
+        case JsonToken.EndConstructor:
+          return JTokenType.Constructor;
+        default:
+          throw new JsonWriterException("No type for token: " + token);
+      }
+    }
+
+    private JsonToken GetCloseTokenForType(JTokenType type)
+    {
+      switch (type)
+      {
+        case JTokenType.Object:
+          return JsonToken.EndObject;
+        case JTokenType.Array:
+          return JsonToken.EndArray;
+        case JTokenType.Constructor:
+          return JsonToken.EndConstructor;
+        default:
+          throw new JsonWriterException("No close token for type: " + type);
+      }
+    }
+
+    private void AutoCompleteClose(JsonToken tokenBeingClosed)
+    {
+      // write closing symbol and calculate new state
+
+      int levelsToComplete = 0;
+
+      for (int i = 0; i < _top; i++)
+      {
+        int currentLevel = _top - i;
+
+        if (_stack[currentLevel] == GetTypeForCloseToken(tokenBeingClosed))
+        {
+          levelsToComplete = i + 1;
+          break;
+        }
+      }
+
+      if (levelsToComplete == 0)
+        throw new JsonWriterException("No token to close.");
+
+      for (int i = 0; i < levelsToComplete; i++)
+      {
+        JsonToken token = GetCloseTokenForType(Pop());
+
+        if (_currentState != State.ObjectStart && _currentState != State.ArrayStart)
+          WriteIndent();
+
+        WriteEnd(token);
+      }
+
+      JTokenType currentLevelType = Peek();
+
+      switch (currentLevelType)
+      {
+        case JTokenType.Object:
+          _currentState = State.Object;
+          break;
+        case JTokenType.Array:
+          _currentState = State.Array;
+          break;
+        case JTokenType.Constructor:
+          _currentState = State.Array;
+          break;
+        case JTokenType.None:
+          _currentState = State.Start;
+          break;
+        default:
+          throw new JsonWriterException("Unknown JsonType: " + currentLevelType);
+      }
+    }
+
+    /// <summary>
+    /// Writes the specified end token.
+    /// </summary>
+    /// <param name="token">The end token to write.</param>
+    protected virtual void WriteEnd(JsonToken token)
+    {
+    }
+
+    /// <summary>
+    /// Writes indent characters.
+    /// </summary>
+    protected virtual void WriteIndent()
+    {
+    }
+
+    /// <summary>
+    /// Writes the JSON value delimiter.
+    /// </summary>
+    protected virtual void WriteValueDelimiter()
+    {
+    }
+
+    /// <summary>
+    /// Writes an indent space.
+    /// </summary>
+    protected virtual void WriteIndentSpace()
+    {
+    }
+
+    internal void AutoComplete(JsonToken tokenBeingWritten)
+    {
+      int token;
+
+      switch (tokenBeingWritten)
+      {
+        default:
+          token = (int)tokenBeingWritten;
+          break;
+        case JsonToken.Integer:
+        case JsonToken.Float:
+        case JsonToken.String:
+        case JsonToken.Boolean:
+        case JsonToken.Null:
+        case JsonToken.Undefined:
+        case JsonToken.Date:
+        case JsonToken.Bytes:
+          // a value is being written
+          token = 7;
+          break;
+      }
+
+      // gets new state based on the current state and what is being written
+      State newState = stateArray[token][(int)_currentState];
+
+      if (newState == State.Error)
+        throw new JsonWriterException("Token {0} in state {1} would result in an invalid JavaScript object.".FormatWith(CultureInfo.InvariantCulture, tokenBeingWritten.ToString(), _currentState.ToString()));
+
+      if ((_currentState == State.Object || _currentState == State.Array || _currentState == State.Constructor) && tokenBeingWritten != JsonToken.Comment)
+      {
+        WriteValueDelimiter();
+      }
+      else if (_currentState == State.Property)
+      {
+        if (_formatting == Formatting.Indented)
+          WriteIndentSpace();
+      }
+
+      WriteState writeState = WriteState;
+
+      // don't indent a property when it is the first token to be written (i.e. at the start)
+      if ((tokenBeingWritten == JsonToken.PropertyName && writeState != WriteState.Start) ||
+        writeState == WriteState.Array || writeState == WriteState.Constructor)
+      {
+        WriteIndent();
+      }
+
+      _currentState = newState;
+    }
+
+    #region WriteValue methods
+    /// <summary>
+    /// Writes a null value.
+    /// </summary>
+    public virtual void WriteNull()
+    {
+      AutoComplete(JsonToken.Null);
+    }
+
+    /// <summary>
+    /// Writes an undefined value.
+    /// </summary>
+    public virtual void WriteUndefined()
+    {
+      AutoComplete(JsonToken.Undefined);
+    }
+
+    /// <summary>
+    /// Writes raw JSON without changing the writer's state.
+    /// </summary>
+    /// <param name="json">The raw JSON to write.</param>
+    public virtual void WriteRaw(string json)
+    {
+    }
+
+    /// <summary>
+    /// Writes raw JSON where a value is expected and updates the writer's state.
+    /// </summary>
+    /// <param name="json">The raw JSON to write.</param>
+    public virtual void WriteRawValue(string json)
+    {
+      // hack. want writer to change state as if a value had been written
+      AutoComplete(JsonToken.Undefined);
+      WriteRaw(json);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="String"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="String"/> value to write.</param>
+    public virtual void WriteValue(string value)
+    {
+      AutoComplete(JsonToken.String);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Int32"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Int32"/> value to write.</param>
+    public virtual void WriteValue(int value)
+    {
+      AutoComplete(JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="UInt32"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="UInt32"/> value to write.</param>
+    [CLSCompliant(false)]
+    public virtual void WriteValue(uint value)
+    {
+      AutoComplete(JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Int64"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Int64"/> value to write.</param>
+    public virtual void WriteValue(long value)
+    {
+      AutoComplete(JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="UInt64"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="UInt64"/> value to write.</param>
+    [CLSCompliant(false)]
+    public virtual void WriteValue(ulong value)
+    {
+      AutoComplete(JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Single"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Single"/> value to write.</param>
+    public virtual void WriteValue(float value)
+    {
+      AutoComplete(JsonToken.Float);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Double"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Double"/> value to write.</param>
+    public virtual void WriteValue(double value)
+    {
+      AutoComplete(JsonToken.Float);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Boolean"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Boolean"/> value to write.</param>
+    public virtual void WriteValue(bool value)
+    {
+      AutoComplete(JsonToken.Boolean);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Int16"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Int16"/> value to write.</param>
+    public virtual void WriteValue(short value)
+    {
+      AutoComplete(JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="UInt16"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="UInt16"/> value to write.</param>
+    [CLSCompliant(false)]
+    public virtual void WriteValue(ushort value)
+    {
+      AutoComplete(JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Char"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Char"/> value to write.</param>
+    public virtual void WriteValue(char value)
+    {
+      AutoComplete(JsonToken.String);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Byte"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Byte"/> value to write.</param>
+    public virtual void WriteValue(byte value)
+    {
+      AutoComplete(JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="SByte"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="SByte"/> value to write.</param>
+    [CLSCompliant(false)]
+    public virtual void WriteValue(sbyte value)
+    {
+      AutoComplete(JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Decimal"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Decimal"/> value to write.</param>
+    public virtual void WriteValue(decimal value)
+    {
+      AutoComplete(JsonToken.Float);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="DateTime"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="DateTime"/> value to write.</param>
+    public virtual void WriteValue(DateTime value)
+    {
+      AutoComplete(JsonToken.Date);
+    }
+
+#if !PocketPC && !NET20
+    /// <summary>
+    /// Writes a <see cref="DateTimeOffset"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="DateTimeOffset"/> value to write.</param>
+    public virtual void WriteValue(DateTimeOffset value)
+    {
+      AutoComplete(JsonToken.Date);
+    }
+#endif
+
+    /// <summary>
+    /// Writes a <see cref="Nullable{Int32}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{Int32}"/> value to write.</param>
+    public virtual void WriteValue(int? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Nullable{UInt32}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{UInt32}"/> value to write.</param>
+    [CLSCompliant(false)]
+    public virtual void WriteValue(uint? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Nullable{Int64}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{Int64}"/> value to write.</param>
+    public virtual void WriteValue(long? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Nullable{UInt64}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{UInt64}"/> value to write.</param>
+    [CLSCompliant(false)]
+    public virtual void WriteValue(ulong? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Nullable{Single}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{Single}"/> value to write.</param>
+    public virtual void WriteValue(float? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Nullable{Double}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{Double}"/> value to write.</param>
+    public virtual void WriteValue(double? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Nullable{Boolean}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{Boolean}"/> value to write.</param>
+    public virtual void WriteValue(bool? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Nullable{Int16}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{Int16}"/> value to write.</param>
+    public virtual void WriteValue(short? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Nullable{UInt16}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{UInt16}"/> value to write.</param>
+    [CLSCompliant(false)]
+    public virtual void WriteValue(ushort? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Nullable{Char}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{Char}"/> value to write.</param>
+    public virtual void WriteValue(char? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Nullable{Byte}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{Byte}"/> value to write.</param>
+    public virtual void WriteValue(byte? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Nullable{SByte}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{SByte}"/> value to write.</param>
+    [CLSCompliant(false)]
+    public virtual void WriteValue(sbyte? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Nullable{Decimal}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{Decimal}"/> value to write.</param>
+    public virtual void WriteValue(decimal? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Nullable{DateTime}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{DateTime}"/> value to write.</param>
+    public virtual void WriteValue(DateTime? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+
+#if !PocketPC && !NET20
+    /// <summary>
+    /// Writes a <see cref="Nullable{DateTimeOffset}"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Nullable{DateTimeOffset}"/> value to write.</param>
+    public virtual void WriteValue(DateTimeOffset? value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        WriteValue(value.Value);
+    }
+#endif
+
+    /// <summary>
+    /// Writes a <see cref="T:Byte[]"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="T:Byte[]"/> value to write.</param>
+    public virtual void WriteValue(byte[] value)
+    {
+      if (value == null)
+        WriteNull();
+      else
+        AutoComplete(JsonToken.Bytes);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Object"/> value.
+    /// An error will raised if the value cannot be written as a single JSON token.
+    /// </summary>
+    /// <param name="value">The <see cref="Object"/> value to write.</param>
+    public virtual void WriteValue(object value)
+    {
+      if (value == null)
+      {
+        WriteNull();
+        return;
+      }
+      else if (value is IConvertible)
+      {
+        IConvertible convertible = value as IConvertible;
+
+        switch (convertible.GetTypeCode())
+        {
+          case TypeCode.String:
+            WriteValue(convertible.ToString(CultureInfo.InvariantCulture));
+            return;
+          case TypeCode.Char:
+            WriteValue(convertible.ToChar(CultureInfo.InvariantCulture));
+            return;
+          case TypeCode.Boolean:
+            WriteValue(convertible.ToBoolean(CultureInfo.InvariantCulture));
+            return;
+          case TypeCode.SByte:
+            WriteValue(convertible.ToSByte(CultureInfo.InvariantCulture));
+            return;
+          case TypeCode.Int16:
+            WriteValue(convertible.ToInt16(CultureInfo.InvariantCulture));
+            return;
+          case TypeCode.UInt16:
+            WriteValue(convertible.ToUInt16(CultureInfo.InvariantCulture));
+            return;
+          case TypeCode.Int32:
+            WriteValue(convertible.ToInt32(CultureInfo.InvariantCulture));
+            return;
+          case TypeCode.Byte:
+            WriteValue(convertible.ToByte(CultureInfo.InvariantCulture));
+            return;
+          case TypeCode.UInt32:
+            WriteValue(convertible.ToUInt32(CultureInfo.InvariantCulture));
+            return;
+          case TypeCode.Int64:
+            WriteValue(convertible.ToInt64(CultureInfo.InvariantCulture));
+            return;
+          case TypeCode.UInt64:
+            WriteValue(convertible.ToUInt64(CultureInfo.InvariantCulture));
+            return;
+          case TypeCode.Single:
+            WriteValue(convertible.ToSingle(CultureInfo.InvariantCulture));
+            return;
+          case TypeCode.Double:
+            WriteValue(convertible.ToDouble(CultureInfo.InvariantCulture));
+            return;
+          case TypeCode.DateTime:
+            WriteValue(convertible.ToDateTime(CultureInfo.InvariantCulture));
+            return;
+          case TypeCode.Decimal:
+            WriteValue(convertible.ToDecimal(CultureInfo.InvariantCulture));
+            return;
+          case TypeCode.DBNull:
+            WriteNull();
+            return;
+        }
+      }
+#if !PocketPC && !NET20
+      else if (value is DateTimeOffset)
+      {
+        WriteValue((DateTimeOffset)value);
+        return;
+      }
+#endif
+      else if (value is byte[])
+      {
+        WriteValue((byte[])value);
+        return;
+      }
+
+      throw new ArgumentException("Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType()));
+    }
+    #endregion
+
+    /// <summary>
+    /// Writes out a comment <code>/*...*/</code> containing the specified text. 
+    /// </summary>
+    /// <param name="text">Text to place inside the comment.</param>
+    public virtual void WriteComment(string text)
+    {
+      AutoComplete(JsonToken.Comment);
+    }
+
+    /// <summary>
+    /// Writes out the given white space.
+    /// </summary>
+    /// <param name="ws">The string of white space characters.</param>
+    public virtual void WriteWhitespace(string ws)
+    {
+      if (ws != null)
+      {
+        if (!StringUtils.IsWhiteSpace(ws))
+          throw new JsonWriterException("Only white space characters should be used.");
+      }
+    }
+
+
+    void IDisposable.Dispose()
+    {
+      Dispose(true);
+    }
+
+    private void Dispose(bool disposing)
+    {
+      if (WriteState != WriteState.Closed)
+        Close();
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonWriterException.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/JsonWriterException.cs
new file mode 100644 (file)
index 0000000..a906f2c
--- /dev/null
@@ -0,0 +1,65 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// The exception thrown when an error occurs while reading Json text.
+  /// </summary>
+  public class JsonWriterException : Exception
+  {
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonWriterException"/> class.
+    /// </summary>
+    public JsonWriterException()
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonWriterException"/> class
+    /// with a specified error message.
+    /// </summary>
+    /// <param name="message">The error message that explains the reason for the exception.</param>
+    public JsonWriterException(string message)
+      : base(message)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonWriterException"/> class
+    /// with a specified error message and a reference to the inner exception that is the cause of this exception.
+    /// </summary>
+    /// <param name="message">The error message that explains the reason for the exception.</param>
+    /// <param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
+    public JsonWriterException(string message, Exception innerException)
+      : base(message, innerException)
+    {
+    }
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/ComponentModel/JPropertyDescriptor.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/ComponentModel/JPropertyDescriptor.cs
new file mode 100644 (file)
index 0000000..df63d36
--- /dev/null
@@ -0,0 +1,173 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+#if !SILVERLIGHT
+using System;
+using System.ComponentModel;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Linq.ComponentModel
+{
+  /// <summary>
+  /// Represents a view of a <see cref="JProperty"/>.
+  /// </summary>
+  public class JPropertyDescriptor : PropertyDescriptor
+  {
+    private readonly Type _propertyType;
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JPropertyDescriptor"/> class.
+    /// </summary>
+    /// <param name="name">The name.</param>
+    /// <param name="propertyType">Type of the property.</param>
+    public JPropertyDescriptor(string name, Type propertyType)
+      : base(name, null)
+    {
+      ValidationUtils.ArgumentNotNull(name, "name");
+      ValidationUtils.ArgumentNotNull(propertyType, "propertyType");
+
+      _propertyType = propertyType;
+    }
+
+    private static JObject CastInstance(object instance)
+    {
+      return (JObject)instance;
+    }
+
+    /// <summary>
+    /// When overridden in a derived class, returns whether resetting an object changes its value.
+    /// </summary>
+    /// <returns>
+    /// true if resetting the component changes its value; otherwise, false.
+    /// </returns>
+    /// <param name="component">The component to test for reset capability. 
+    ///                 </param>
+    public override bool CanResetValue(object component)
+    {
+      return false;
+    }
+
+    /// <summary>
+    /// When overridden in a derived class, gets the current value of the property on a component.
+    /// </summary>
+    /// <returns>
+    /// The value of a property for a given component.
+    /// </returns>
+    /// <param name="component">The component with the property for which to retrieve the value. 
+    ///                 </param>
+    public override object GetValue(object component)
+    {
+      JToken token = CastInstance(component)[Name];
+
+      return token;
+    }
+
+    /// <summary>
+    /// When overridden in a derived class, resets the value for this property of the component to the default value.
+    /// </summary>
+    /// <param name="component">The component with the property value that is to be reset to the default value. 
+    ///                 </param>
+    public override void ResetValue(object component)
+    {
+    }
+
+    /// <summary>
+    /// When overridden in a derived class, sets the value of the component to a different value.
+    /// </summary>
+    /// <param name="component">The component with the property value that is to be set. 
+    ///                 </param><param name="value">The new value. 
+    ///                 </param>
+    public override void SetValue(object component, object value)
+    {
+      JToken token = (value is JToken) ? (JToken) value : new JValue(value);
+
+      CastInstance(component)[Name] = token;
+    }
+
+    /// <summary>
+    /// When overridden in a derived class, determines a value indicating whether the value of this property needs to be persisted.
+    /// </summary>
+    /// <returns>
+    /// true if the property should be persisted; otherwise, false.
+    /// </returns>
+    /// <param name="component">The component with the property to be examined for persistence. 
+    ///                 </param>
+    public override bool ShouldSerializeValue(object component)
+    {
+      return false;
+    }
+
+    /// <summary>
+    /// When overridden in a derived class, gets the type of the component this property is bound to.
+    /// </summary>
+    /// <returns>
+    /// A <see cref="T:System.Type"/> that represents the type of component this property is bound to. When the <see cref="M:System.ComponentModel.PropertyDescriptor.GetValue(System.Object)"/> or <see cref="M:System.ComponentModel.PropertyDescriptor.SetValue(System.Object,System.Object)"/> methods are invoked, the object specified might be an instance of this type.
+    /// </returns>
+    public override Type ComponentType
+    {
+      get { return typeof(JObject); }
+    }
+
+    /// <summary>
+    /// When overridden in a derived class, gets a value indicating whether this property is read-only.
+    /// </summary>
+    /// <returns>
+    /// true if the property is read-only; otherwise, false.
+    /// </returns>
+    public override bool IsReadOnly
+    {
+      get { return false; }
+    }
+
+    /// <summary>
+    /// When overridden in a derived class, gets the type of the property.
+    /// </summary>
+    /// <returns>
+    /// A <see cref="T:System.Type"/> that represents the type of the property.
+    /// </returns>
+    public override Type PropertyType
+    {
+      get { return _propertyType; }
+    }
+
+    /// <summary>
+    /// Gets the hash code for the name of the member.
+    /// </summary>
+    /// <value></value>
+    /// <returns>
+    /// The hash code for the name of the member.
+    /// </returns>
+    protected override int NameHashCode
+    {
+      get
+      {
+        // override property to fix up an error in its documentation
+        int nameHashCode = base.NameHashCode;
+        return nameHashCode;
+      }
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/Extensions.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/Extensions.cs
new file mode 100644 (file)
index 0000000..0b737b2
--- /dev/null
@@ -0,0 +1,316 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Utilities;
+using System.Collections;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Linq
+{
+  /// <summary>
+  /// Contains the LINQ to JSON extension methods.
+  /// </summary>
+  public static class Extensions
+  {
+    /// <summary>
+    /// Returns a collection of tokens that contains the ancestors of every token in the source collection.
+    /// </summary>
+    /// <typeparam name="T">The type of the objects in source, constrained to <see cref="JToken"/>.</typeparam>
+    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
+    /// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the ancestors of every node in the source collection.</returns>
+    public static IJEnumerable<JToken> Ancestors<T>(this IEnumerable<T> source) where T : JToken
+    {
+      ValidationUtils.ArgumentNotNull(source, "source");
+
+      return source.SelectMany(j => j.Ancestors()).AsJEnumerable();
+    }
+
+    //TODO
+    //public static IEnumerable<JObject> AncestorsAndSelf<T>(this IEnumerable<T> source) where T : JObject
+    //{
+    //  ValidationUtils.ArgumentNotNull(source, "source");
+
+    //  return source.SelectMany(j => j.AncestorsAndSelf());
+    //}
+
+    /// <summary>
+    /// Returns a collection of tokens that contains the descendants of every token in the source collection.
+    /// </summary>
+    /// <typeparam name="T">The type of the objects in source, constrained to <see cref="JContainer"/>.</typeparam>
+    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
+    /// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the descendants of every node in the source collection.</returns>
+    public static IJEnumerable<JToken> Descendants<T>(this IEnumerable<T> source) where T : JContainer
+    {
+      ValidationUtils.ArgumentNotNull(source, "source");
+
+      return source.SelectMany(j => j.Descendants()).AsJEnumerable();
+    }
+
+    //TODO
+    //public static IEnumerable<JObject> DescendantsAndSelf<T>(this IEnumerable<T> source) where T : JContainer
+    //{
+    //  ValidationUtils.ArgumentNotNull(source, "source");
+
+    //  return source.SelectMany(j => j.DescendantsAndSelf());
+    //}
+
+    /// <summary>
+    /// Returns a collection of child properties of every object in the source collection.
+    /// </summary>
+    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JObject"/> that contains the source collection.</param>
+    /// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JProperty"/> that contains the properties of every object in the source collection.</returns>
+    public static IJEnumerable<JProperty> Properties(this IEnumerable<JObject> source)
+    {
+      ValidationUtils.ArgumentNotNull(source, "source");
+
+      return source.SelectMany(d => d.Properties()).AsJEnumerable();
+    }
+
+    /// <summary>
+    /// Returns a collection of child values of every object in the source collection with the given key.
+    /// </summary>
+    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
+    /// <param name="key">The token key.</param>
+    /// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the values of every node in the source collection with the given key.</returns>
+    public static IJEnumerable<JToken> Values(this IEnumerable<JToken> source, object key)
+    {
+      return Values<JToken, JToken>(source, key).AsJEnumerable();
+    }
+
+    /// <summary>
+    /// Returns a collection of child values of every object in the source collection.
+    /// </summary>
+    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
+    /// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the values of every node in the source collection.</returns>
+    public static IJEnumerable<JToken> Values(this IEnumerable<JToken> source)
+    {
+      return source.Values(null);
+    }
+
+    /// <summary>
+    /// Returns a collection of converted child values of every object in the source collection with the given key.
+    /// </summary>
+    /// <typeparam name="U">The type to convert the values to.</typeparam>
+    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
+    /// <param name="key">The token key.</param>
+    /// <returns>An <see cref="IEnumerable{T}"/> that contains the converted values of every node in the source collection with the given key.</returns>
+    public static IEnumerable<U> Values<U>(this IEnumerable<JToken> source, object key)
+    {
+      return Values<JToken, U>(source, key);
+    }
+
+    /// <summary>
+    /// Returns a collection of converted child values of every object in the source collection.
+    /// </summary>
+    /// <typeparam name="U">The type to convert the values to.</typeparam>
+    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
+    /// <returns>An <see cref="IEnumerable{T}"/> that contains the converted values of every node in the source collection.</returns>
+    public static IEnumerable<U> Values<U>(this IEnumerable<JToken> source)
+    {
+      return Values<JToken, U>(source, null);
+    }
+
+    /// <summary>
+    /// Converts the value.
+    /// </summary>
+    /// <typeparam name="U">The type to convert the value to.</typeparam>
+    /// <param name="value">A <see cref="JToken"/> cast as a <see cref="IEnumerable{T}"/> of <see cref="JToken"/>.</param>
+    /// <returns>A converted value.</returns>
+    public static U Value<U>(this IEnumerable<JToken> value)
+    {
+      return value.Value<JToken, U>();
+    }
+
+    /// <summary>
+    /// Converts the value.
+    /// </summary>
+    /// <typeparam name="T">The source collection type.</typeparam>
+    /// <typeparam name="U">The type to convert the value to.</typeparam>
+    /// <param name="value">A <see cref="JToken"/> cast as a <see cref="IEnumerable{T}"/> of <see cref="JToken"/>.</param>
+    /// <returns>A converted value.</returns>
+    public static U Value<T, U>(this IEnumerable<T> value) where T : JToken
+    {
+      ValidationUtils.ArgumentNotNull(value, "source");
+
+      JToken token = value as JToken;
+      if (token == null)
+        throw new ArgumentException("Source value must be a JToken.");
+
+      return token.Convert<JToken, U>();
+    }
+
+
+    internal static IEnumerable<U> Values<T, U>(this IEnumerable<T> source, object key) where T : JToken
+    {
+      ValidationUtils.ArgumentNotNull(source, "source");
+
+      foreach (JToken token in source)
+      {
+        if (key == null)
+        {
+          if (token is JValue)
+          {
+            yield return Convert<JValue, U>((JValue)token);
+          }
+          else
+          {
+            foreach (JToken t in token.Children())
+            {
+              yield return t.Convert<JToken, U>(); ;
+            }
+          }
+        }
+        else
+        {
+          JToken value = token[key];
+          if (value != null)
+            yield return value.Convert<JToken, U>();
+        }
+      }
+
+      yield break;
+    }
+
+    //TODO
+    //public static IEnumerable<T> InDocumentOrder<T>(this IEnumerable<T> source) where T : JObject;
+
+    //public static IEnumerable<JToken> Children<T>(this IEnumerable<T> source) where T : JToken
+    //{
+    //  ValidationUtils.ArgumentNotNull(source, "source");
+
+    //  return source.SelectMany(c => c.Children());
+    //}
+
+    /// <summary>
+    /// Returns a collection of child tokens of every array in the source collection.
+    /// </summary>
+    /// <typeparam name="T">The source collection type.</typeparam>
+    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
+    /// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the values of every node in the source collection.</returns>
+    public static IJEnumerable<JToken> Children<T>(this IEnumerable<T> source) where T : JToken
+    {
+      return Children<T, JToken>(source).AsJEnumerable();
+    }
+
+    /// <summary>
+    /// Returns a collection of converted child tokens of every array in the source collection.
+    /// </summary>
+    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
+    /// <typeparam name="U">The type to convert the values to.</typeparam>
+    /// <typeparam name="T">The source collection type.</typeparam>
+    /// <returns>An <see cref="IEnumerable{T}"/> that contains the converted values of every node in the source collection.</returns>
+    public static IEnumerable<U> Children<T, U>(this IEnumerable<T> source) where T : JToken
+    {
+      ValidationUtils.ArgumentNotNull(source, "source");
+
+      return source.SelectMany(c => c.Children()).Convert<JToken, U>();
+    }
+
+    internal static IEnumerable<U> Convert<T, U>(this IEnumerable<T> source) where T : JToken
+    {
+      ValidationUtils.ArgumentNotNull(source, "source");
+
+      bool cast = typeof(JToken).IsAssignableFrom(typeof(U));
+
+      foreach (JToken token in source)
+      {
+        yield return Convert<JToken, U>(token, cast);
+      }
+    }
+
+    internal static U Convert<T, U>(this T token) where T : JToken
+    {
+      bool cast = typeof(JToken).IsAssignableFrom(typeof(U));
+
+      return Convert<T, U>(token, cast);
+    }
+
+    internal static U Convert<T, U>(this T token, bool cast) where T : JToken
+    {
+      if (cast)
+      {
+        // HACK
+        return (U)(object)token;
+      }
+      else
+      {
+        if (token == null)
+          return default(U);
+
+        JValue value = token as JValue;
+        if (value == null)
+          throw new InvalidCastException("Cannot cast {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, token.GetType(), typeof(T)));
+
+        if (value.Value is U)
+          return (U)value.Value;
+
+        Type targetType = typeof(U);
+
+        if (ReflectionUtils.IsNullableType(targetType))
+        {
+          if (value.Value == null)
+            return default(U);
+
+          targetType = Nullable.GetUnderlyingType(targetType);
+        }
+
+        return (U)System.Convert.ChangeType(value.Value, targetType, CultureInfo.InvariantCulture);
+      }
+    }
+
+    //TODO
+    //public static void Remove<T>(this IEnumerable<T> source) where T : JContainer;
+
+    /// <summary>
+    /// Returns the input typed as <see cref="IJEnumerable{T}"/>.
+    /// </summary>
+    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
+    /// <returns>The input typed as <see cref="IJEnumerable{T}"/>.</returns>
+    public static IJEnumerable<JToken> AsJEnumerable(this IEnumerable<JToken> source)
+    {
+      return source.AsJEnumerable<JToken>();
+    }
+
+    /// <summary>
+    /// Returns the input typed as <see cref="IJEnumerable{T}"/>.
+    /// </summary>
+    /// <typeparam name="T">The source collection type.</typeparam>
+    /// <param name="source">An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> that contains the source collection.</param>
+    /// <returns>The input typed as <see cref="IJEnumerable{T}"/>.</returns>
+    public static IJEnumerable<T> AsJEnumerable<T>(this IEnumerable<T> source) where T : JToken
+    {
+      if (source == null)
+        return null;
+      else if (source is IJEnumerable<T>)
+        return (IJEnumerable<T>)source;
+      else
+        return new JEnumerable<T>(source);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/IJEnumerable.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/IJEnumerable.cs
new file mode 100644 (file)
index 0000000..09cdb95
--- /dev/null
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Linq
+{
+  /// <summary>
+  /// Represents a collection of <see cref="JToken"/> objects.
+  /// </summary>
+  /// <typeparam name="T">The type of token</typeparam>
+  public interface IJEnumerable<
+#if !(NET20 || NET35 || SILVERLIGHT)
+    out
+#endif
+    T> : IEnumerable<T> where T : JToken
+  {
+    /// <summary>
+    /// Gets the <see cref="IJEnumerable{JToken}"/> with the specified key.
+    /// </summary>
+    /// <value></value>
+    IJEnumerable<JToken> this[object key] { get; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JArray.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JArray.cs
new file mode 100644 (file)
index 0000000..3eea72c
--- /dev/null
@@ -0,0 +1,324 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Utilities;
+using System.IO;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Linq
+{
+  /// <summary>
+  /// Represents a JSON array.
+  /// </summary>
+  public class JArray : JContainer, IList<JToken>
+  {
+    /// <summary>
+    /// Gets the node type for this <see cref="JToken"/>.
+    /// </summary>
+    /// <value>The type.</value>
+    public override JTokenType Type
+    {
+      get { return JTokenType.Array; }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JArray"/> class.
+    /// </summary>
+    public JArray()
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JArray"/> class from another <see cref="JArray"/> object.
+    /// </summary>
+    /// <param name="other">A <see cref="JArray"/> object to copy from.</param>
+    public JArray(JArray other)
+      : base(other)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JArray"/> class with the specified content.
+    /// </summary>
+    /// <param name="content">The contents of the array.</param>
+    public JArray(params object[] content)
+      : this((object)content)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JArray"/> class with the specified content.
+    /// </summary>
+    /// <param name="content">The contents of the array.</param>
+    public JArray(object content)
+    {
+      Add(content);
+    }
+
+    internal override bool DeepEquals(JToken node)
+    {
+      JArray t = node as JArray;
+      return (t != null && ContentsEqual(t));
+    }
+
+    internal override JToken CloneToken()
+    {
+      return new JArray(this);
+    }
+
+    /// <summary>
+    /// Loads an <see cref="JArray"/> from a <see cref="JsonReader"/>. 
+    /// </summary>
+    /// <param name="reader">A <see cref="JsonReader"/> that will be read for the content of the <see cref="JArray"/>.</param>
+    /// <returns>A <see cref="JArray"/> that contains the JSON that was read from the specified <see cref="JsonReader"/>.</returns>
+    public static new JArray Load(JsonReader reader)
+    {
+      if (reader.TokenType == JsonToken.None)
+      {
+        if (!reader.Read())
+          throw new Exception("Error reading JArray from JsonReader.");
+      }
+      if (reader.TokenType != JsonToken.StartArray)
+        throw new Exception("Error reading JArray from JsonReader. Current JsonReader item is not an array: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
+
+      JArray a = new JArray();
+      a.SetLineInfo(reader as IJsonLineInfo);
+
+      a.ReadTokenFrom(reader);
+
+      return a;
+    }
+
+    /// <summary>
+    /// Load a <see cref="JArray"/> from a string that contains JSON.
+    /// </summary>
+    /// <param name="json">A <see cref="String"/> that contains JSON.</param>
+    /// <returns>A <see cref="JArray"/> populated from the string that contains JSON.</returns>
+    public static new JArray Parse(string json)
+    {
+      JsonReader jsonReader = new JsonTextReader(new StringReader(json));
+
+      return Load(jsonReader);
+    }
+
+    /// <summary>
+    /// Creates a <see cref="JArray"/> from an object.
+    /// </summary>
+    /// <param name="o">The object that will be used to create <see cref="JArray"/>.</param>
+    /// <returns>A <see cref="JArray"/> with the values of the specified object</returns>
+    public static new JArray FromObject(object o)
+    {
+      return FromObject(o, new JsonSerializer());
+    }
+
+    /// <summary>
+    /// Creates a <see cref="JArray"/> from an object.
+    /// </summary>
+    /// <param name="o">The object that will be used to create <see cref="JArray"/>.</param>
+    /// <param name="jsonSerializer">The <see cref="JsonSerializer"/> that will be used to read the object.</param>
+    /// <returns>A <see cref="JArray"/> with the values of the specified object</returns>
+    public static new JArray FromObject(object o, JsonSerializer jsonSerializer)
+    {
+      JToken token = FromObjectInternal(o, jsonSerializer);
+
+      if (token.Type != JTokenType.Array)
+        throw new ArgumentException("Object serialized to {0}. JArray instance expected.".FormatWith(CultureInfo.InvariantCulture, token.Type));
+
+      return (JArray)token;
+    }
+
+    /// <summary>
+    /// Writes this token to a <see cref="JsonWriter"/>.
+    /// </summary>
+    /// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param>
+    /// <param name="converters">A collection of <see cref="JsonConverter"/> which will be used when writing the token.</param>
+    public override void WriteTo(JsonWriter writer, params JsonConverter[] converters)
+    {
+      writer.WriteStartArray();
+
+      foreach (JToken token in Children())
+      {
+        token.WriteTo(writer, converters);
+      }
+
+      writer.WriteEndArray();
+    }
+
+    /// <summary>
+    /// Gets the <see cref="JToken"/> with the specified key.
+    /// </summary>
+    /// <value>The <see cref="JToken"/> with the specified key.</value>
+    public override JToken this[object key]
+    {
+      get
+      {
+        ValidationUtils.ArgumentNotNull(key, "o");
+
+        if (!(key is int))
+          throw new ArgumentException("Accessed JArray values with invalid key value: {0}. Array position index expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key)));
+
+        return GetItem((int)key);
+      }
+      set
+      {
+        ValidationUtils.ArgumentNotNull(key, "o");
+
+        if (!(key is int))
+          throw new ArgumentException("Set JArray values with invalid key value: {0}. Array position index expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key)));
+
+        SetItem((int)key, value);
+      }
+    }
+
+    /// <summary>
+    /// Gets or sets the <see cref="Newtonsoft.Json.Linq.JToken"/> at the specified index.
+    /// </summary>
+    /// <value></value>
+    public JToken this[int index]
+    {
+      get { return GetItem(index); }
+      set { SetItem(index, value); }
+    }
+
+    #region IList<JToken> Members
+
+    /// <summary>
+    /// Determines the index of a specific item in the <see cref="T:System.Collections.Generic.IList`1"/>.
+    /// </summary>
+    /// <param name="item">The object to locate in the <see cref="T:System.Collections.Generic.IList`1"/>.</param>
+    /// <returns>
+    /// The index of <paramref name="item"/> if found in the list; otherwise, -1.
+    /// </returns>
+    public int IndexOf(JToken item)
+    {
+      return IndexOfItem(item);
+    }
+
+    /// <summary>
+    /// Inserts an item to the <see cref="T:System.Collections.Generic.IList`1"/> at the specified index.
+    /// </summary>
+    /// <param name="index">The zero-based index at which <paramref name="item"/> should be inserted.</param>
+    /// <param name="item">The object to insert into the <see cref="T:System.Collections.Generic.IList`1"/>.</param>
+    /// <exception cref="T:System.ArgumentOutOfRangeException">
+    ///        <paramref name="index"/> is not a valid index in the <see cref="T:System.Collections.Generic.IList`1"/>.</exception>
+    /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.IList`1"/> is read-only.</exception>
+    public void Insert(int index, JToken item)
+    {
+      InsertItem(index, item);
+    }
+
+    /// <summary>
+    /// Removes the <see cref="T:System.Collections.Generic.IList`1"/> item at the specified index.
+    /// </summary>
+    /// <param name="index">The zero-based index of the item to remove.</param>
+    /// <exception cref="T:System.ArgumentOutOfRangeException">
+    ///        <paramref name="index"/> is not a valid index in the <see cref="T:System.Collections.Generic.IList`1"/>.</exception>
+    /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.IList`1"/> is read-only.</exception>
+    public void RemoveAt(int index)
+    {
+      RemoveItemAt(index);
+    }
+
+    #endregion
+
+    #region ICollection<JToken> Members
+
+    /// <summary>
+    /// Adds an item to the <see cref="T:System.Collections.Generic.ICollection`1"/>.
+    /// </summary>
+    /// <param name="item">The object to add to the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param>
+    /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.</exception>
+    public void Add(JToken item)
+    {
+      Add((object)item);
+    }
+
+    /// <summary>
+    /// Removes all items from the <see cref="T:System.Collections.Generic.ICollection`1"/>.
+    /// </summary>
+    /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only. </exception>
+    public void Clear()
+    {
+      ClearItems();
+    }
+
+    /// <summary>
+    /// Determines whether the <see cref="T:System.Collections.Generic.ICollection`1"/> contains a specific value.
+    /// </summary>
+    /// <param name="item">The object to locate in the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param>
+    /// <returns>
+    /// true if <paramref name="item"/> is found in the <see cref="T:System.Collections.Generic.ICollection`1"/>; otherwise, false.
+    /// </returns>
+    public bool Contains(JToken item)
+    {
+      return ContainsItem(item);
+    }
+
+    void ICollection<JToken>.CopyTo(JToken[] array, int arrayIndex)
+    {
+      CopyItemsTo(array, arrayIndex);
+    }
+
+    /// <summary>
+    /// Gets the number of elements contained in the <see cref="T:System.Collections.Generic.ICollection`1"/>.
+    /// </summary>
+    /// <value></value>
+    /// <returns>The number of elements contained in the <see cref="T:System.Collections.Generic.ICollection`1"/>.</returns>
+    public int Count
+    {
+      get { return CountItems(); }
+    }
+
+    bool ICollection<JToken>.IsReadOnly
+    {
+      get { return false; }
+    }
+
+    /// <summary>
+    /// Removes the first occurrence of a specific object from the <see cref="T:System.Collections.Generic.ICollection`1"/>.
+    /// </summary>
+    /// <param name="item">The object to remove from the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param>
+    /// <returns>
+    /// true if <paramref name="item"/> was successfully removed from the <see cref="T:System.Collections.Generic.ICollection`1"/>; otherwise, false. This method also returns false if <paramref name="item"/> is not found in the original <see cref="T:System.Collections.Generic.ICollection`1"/>.
+    /// </returns>
+    /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.</exception>
+    public bool Remove(JToken item)
+    {
+      return RemoveItem(item);
+    }
+
+    #endregion
+
+    internal override int GetDeepHashCode()
+    {
+      return ContentsHashCode();
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JConstructor.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JConstructor.cs
new file mode 100644 (file)
index 0000000..b75d605
--- /dev/null
@@ -0,0 +1,193 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Utilities;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Linq
+{
+  /// <summary>
+  /// Represents a JSON constructor.
+  /// </summary>
+  public class JConstructor : JContainer
+  {
+    private string _name;
+
+    /// <summary>
+    /// Gets or sets the name of this constructor.
+    /// </summary>
+    /// <value>The constructor name.</value>
+    public string Name
+    {
+      get { return _name; }
+      set { _name = value; }
+    }
+
+    /// <summary>
+    /// Gets the node type for this <see cref="JToken"/>.
+    /// </summary>
+    /// <value>The type.</value>
+    public override JTokenType Type
+    {
+      get { return JTokenType.Constructor; }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JConstructor"/> class.
+    /// </summary>
+    public JConstructor()
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JConstructor"/> class from another <see cref="JConstructor"/> object.
+    /// </summary>
+    /// <param name="other">A <see cref="JConstructor"/> object to copy from.</param>
+    public JConstructor(JConstructor other)
+      : base(other)
+    {
+      _name = other.Name;
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JConstructor"/> class with the specified name and content.
+    /// </summary>
+    /// <param name="name">The constructor name.</param>
+    /// <param name="content">The contents of the constructor.</param>
+    public JConstructor(string name, params object[] content)
+      : this(name, (object)content)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JConstructor"/> class with the specified name and content.
+    /// </summary>
+    /// <param name="name">The constructor name.</param>
+    /// <param name="content">The contents of the constructor.</param>
+    public JConstructor(string name, object content)
+      : this(name)
+    {
+      Add(content);
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JConstructor"/> class with the specified name.
+    /// </summary>
+    /// <param name="name">The constructor name.</param>
+    public JConstructor(string name)
+    {
+      ValidationUtils.ArgumentNotNullOrEmpty(name, "name");
+
+      _name = name;
+    }
+
+    internal override bool DeepEquals(JToken node)
+    {
+      JConstructor c = node as JConstructor;
+      return (c != null && _name == c.Name && ContentsEqual(c));
+    }
+
+    internal override JToken CloneToken()
+    {
+      return new JConstructor(this);
+    }
+
+    /// <summary>
+    /// Writes this token to a <see cref="JsonWriter"/>.
+    /// </summary>
+    /// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param>
+    /// <param name="converters">A collection of <see cref="JsonConverter"/> which will be used when writing the token.</param>
+    public override void WriteTo(JsonWriter writer, params JsonConverter[] converters)
+    {
+      writer.WriteStartConstructor(_name);
+
+      foreach (JToken token in Children())
+      {
+        token.WriteTo(writer, converters);
+      }
+
+      writer.WriteEndConstructor();
+    }
+
+    /// <summary>
+    /// Gets the <see cref="JToken"/> with the specified key.
+    /// </summary>
+    /// <value>The <see cref="JToken"/> with the specified key.</value>
+    public override JToken this[object key]
+    {
+      get
+      {
+        ValidationUtils.ArgumentNotNull(key, "o");
+
+        if (!(key is int))
+          throw new ArgumentException("Accessed JConstructor values with invalid key value: {0}. Argument position index expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key)));
+
+        return GetItem((int)key);
+      }
+      set
+      {
+        ValidationUtils.ArgumentNotNull(key, "o");
+
+        if (!(key is int))
+          throw new ArgumentException("Set JConstructor values with invalid key value: {0}. Argument position index expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key)));
+
+        SetItem((int)key, value);
+      }
+    }
+
+    internal override int GetDeepHashCode()
+    {
+      return _name.GetHashCode() ^ ContentsHashCode();
+    }
+
+    /// <summary>
+    /// Loads an <see cref="JConstructor"/> from a <see cref="JsonReader"/>. 
+    /// </summary>
+    /// <param name="reader">A <see cref="JsonReader"/> that will be read for the content of the <see cref="JConstructor"/>.</param>
+    /// <returns>A <see cref="JConstructor"/> that contains the JSON that was read from the specified <see cref="JsonReader"/>.</returns>
+    public static new JConstructor Load(JsonReader reader)
+    {
+      if (reader.TokenType == JsonToken.None)
+      {
+        if (!reader.Read())
+          throw new Exception("Error reading JConstructor from JsonReader.");
+      }
+
+      if (reader.TokenType != JsonToken.StartConstructor)
+        throw new Exception("Error reading JConstructor from JsonReader. Current JsonReader item is not a constructor: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
+
+      JConstructor c = new JConstructor((string)reader.Value);
+      c.SetLineInfo(reader as IJsonLineInfo);
+
+      c.ReadTokenFrom(reader);
+
+      return c;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JContainer.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JContainer.cs
new file mode 100644 (file)
index 0000000..954df2a
--- /dev/null
@@ -0,0 +1,1069 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using Newtonsoft.Json.Utilities;
+using System.Collections;
+using System.Diagnostics;
+using System.Globalization;
+using System.ComponentModel;
+using System.Collections.Specialized;
+#if !SILVERLIGHT
+using Newtonsoft.Json.Linq.ComponentModel;
+#endif
+
+namespace Newtonsoft.Json.Linq
+{
+  /// <summary>
+  /// Represents a token that can contain other tokens.
+  /// </summary>
+  public abstract class JContainer : JToken, IList<JToken>
+#if !SILVERLIGHT
+    , ITypedList, IBindingList
+#else
+    , IList, INotifyCollectionChanged
+#endif
+#if !(SILVERLIGHT || NET20 || NET35)
+    , INotifyCollectionChanged
+#endif
+  {
+#if !SILVERLIGHT
+    /// <summary>
+    /// Occurs when the list changes or an item in the list changes.
+    /// </summary>
+    public event ListChangedEventHandler ListChanged;
+
+    /// <summary>
+    /// Occurs before an item is added to the collection.
+    /// </summary>
+    public event AddingNewEventHandler AddingNew;
+#endif
+#if SILVERLIGHT || !(NET20 || NET35)
+    /// <summary>
+    /// Occurs when the items list of the collection has changed, or the collection is reset.
+    /// </summary>
+    public event NotifyCollectionChangedEventHandler CollectionChanged;
+#endif
+
+    private JToken _content;
+    private object _syncRoot;
+    private bool _busy;
+
+    internal JToken Content
+    {
+      get { return _content; }
+      set { _content = value; }
+    }
+
+    internal JContainer()
+    {
+    }
+
+    internal JContainer(JContainer other)
+    {
+      ValidationUtils.ArgumentNotNull(other, "c");
+
+      JToken content = other.Last;
+      if (content != null)
+      {
+        do
+        {
+          content = content._next;
+          Add(content.CloneToken());
+        }
+        while (content != other.Last);
+      }
+    }
+
+    internal void CheckReentrancy()
+    {
+      if (_busy)
+        throw new InvalidOperationException("Cannot change {0} during a collection change event.".FormatWith(CultureInfo.InvariantCulture, GetType()));
+    }
+
+ #if !SILVERLIGHT
+    /// <summary>
+    /// Raises the <see cref="AddingNew"/> event.
+    /// </summary>
+    /// <param name="e">The <see cref="AddingNewEventArgs"/> instance containing the event data.</param>
+    protected virtual void OnAddingNew(AddingNewEventArgs e)
+    {
+      AddingNewEventHandler handler = AddingNew;
+      if (handler != null)
+        handler(this, e);
+    }
+
+    /// <summary>
+    /// Raises the <see cref="ListChanged"/> event.
+    /// </summary>
+    /// <param name="e">The <see cref="ListChangedEventArgs"/> instance containing the event data.</param>
+    protected virtual void OnListChanged(ListChangedEventArgs e)
+    {
+      ListChangedEventHandler handler = ListChanged;
+
+      if (handler != null)
+      {
+        _busy = true;
+        try
+        {
+          handler(this, e);
+        }
+        finally
+        {
+          _busy = false;
+        }
+      }
+    }
+#endif
+#if SILVERLIGHT || !(NET20 || NET35)
+    /// <summary>
+    /// Raises the <see cref="CollectionChanged"/> event.
+    /// </summary>
+    /// <param name="e">The <see cref="NotifyCollectionChangedEventArgs"/> instance containing the event data.</param>
+    protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
+    {
+      NotifyCollectionChangedEventHandler handler = CollectionChanged;
+
+      if (handler != null)
+      {
+        _busy = true;
+        try
+        {
+          handler(this, e);
+        }
+        finally
+        {
+          _busy = false;
+        }
+      }
+    }
+#endif
+
+    /// <summary>
+    /// Gets a value indicating whether this token has childen tokens.
+    /// </summary>
+    /// <value>
+    ///        <c>true</c> if this token has child values; otherwise, <c>false</c>.
+    /// </value>
+    public override bool HasValues
+    {
+      get { return (_content != null); }
+    }
+
+    internal bool ContentsEqual(JContainer container)
+    {
+      JToken t1 = First;
+      JToken t2 = container.First;
+
+      if (t1 == t2)
+        return true;
+
+      do
+      {
+        if (t1 == null && t2 == null)
+          return true;
+
+        if (t1 != null && t2 != null && t1.DeepEquals(t2))
+        {
+          t1 = (t1 != Last) ? t1.Next : null;
+          t2 = (t2 != container.Last) ? t2.Next : null;
+        }
+        else
+        {
+          return false;
+        }
+      }
+      while (true);
+    }
+
+    /// <summary>
+    /// Get the first child token of this token.
+    /// </summary>
+    /// <value>
+    /// A <see cref="JToken"/> containing the first child token of the <see cref="JToken"/>.
+    /// </value>
+    public override JToken First
+    {
+      get
+      {
+        if (Last == null)
+          return null;
+
+        return Last._next;
+      }
+    }
+
+    /// <summary>
+    /// Get the last child token of this token.
+    /// </summary>
+    /// <value>
+    /// A <see cref="JToken"/> containing the last child token of the <see cref="JToken"/>.
+    /// </value>
+    public override JToken Last
+    {
+      [DebuggerStepThrough]
+      get { return _content; }
+    }
+
+    /// <summary>
+    /// Returns a collection of the child tokens of this token, in document order.
+    /// </summary>
+    /// <returns>
+    /// An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> containing the child tokens of this <see cref="JToken"/>, in document order.
+    /// </returns>
+    public override JEnumerable<JToken> Children()
+    {
+      return new JEnumerable<JToken>(ChildrenInternal());
+    }
+
+    internal IEnumerable<JToken> ChildrenInternal()
+    {
+      JToken first = First;
+      JToken current = first;
+      if (current == null)
+        yield break;
+
+      do
+      {
+        yield return current;
+      }
+      while ((current = current.Next) != null);
+    }
+
+    /// <summary>
+    /// Returns a collection of the child values of this token, in document order.
+    /// </summary>
+    /// <typeparam name="T">The type to convert the values to.</typeparam>
+    /// <returns>
+    /// A <see cref="IEnumerable{T}"/> containing the child values of this <see cref="JToken"/>, in document order.
+    /// </returns>
+    public override IEnumerable<T> Values<T>()
+    {
+      return Children().Convert<JToken, T>();
+    }
+
+    /// <summary>
+    /// Returns a collection of the descendant tokens for this token in document order.
+    /// </summary>
+    /// <returns>An <see cref="IEnumerable{JToken}"/> containing the descendant tokens of the <see cref="JToken"/>.</returns>
+    public IEnumerable<JToken> Descendants()
+    {
+      foreach (JToken o in Children())
+      {
+        yield return o;
+        JContainer c = o as JContainer;
+        if (c != null)
+        {
+          foreach (JToken d in c.Descendants())
+          {
+            yield return d;
+          }
+        }
+      }
+    }
+
+    internal bool IsMultiContent(object content)
+    {
+      return (content is IEnumerable && !(content is string) && !(content is JToken) && !(content is byte[]));
+    }
+
+    internal virtual void AddItem(bool isLast, JToken previous, JToken item)
+    {
+      CheckReentrancy();
+
+      ValidateToken(item, null);
+
+      item = EnsureParentToken(item);
+
+      JToken next = (previous != null) ? previous._next : item;
+
+      item.Parent = this;
+      item.Next = next;
+
+      if (previous != null)
+        previous.Next = item;
+
+      if (isLast || previous == null)
+        _content = item;
+
+#if !SILVERLIGHT
+      if (ListChanged != null)
+        OnListChanged(new ListChangedEventArgs(ListChangedType.ItemAdded, IndexOfItem(item)));
+#endif
+#if SILVERLIGHT || !(NET20 || NET35)
+      if (CollectionChanged != null)
+        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, IndexOfItem(item)));
+#endif
+    }
+
+    internal JToken EnsureParentToken(JToken item)
+    {
+      if (item.Parent != null)
+      {
+        item = item.CloneToken();
+      }
+      else
+      {
+        // check whether attempting to add a token to itself
+        JContainer parent = this;
+        while (parent.Parent != null)
+        {
+          parent = parent.Parent;
+        }
+        if (item == parent)
+        {
+          item = item.CloneToken();
+        }
+      }
+      return item;
+    }
+
+    internal void AddInternal(bool isLast, JToken previous, object content)
+    {
+      if (IsMultiContent(content))
+      {
+        IEnumerable enumerable = (IEnumerable) content;
+
+        JToken multiPrevious = previous;
+        foreach (object c in enumerable)
+        {
+          AddInternal(isLast, multiPrevious, c);
+          multiPrevious = (multiPrevious != null) ? multiPrevious._next : Last;
+        }
+      }
+      else
+      {
+        JToken item = CreateFromContent(content);
+
+        AddItem(isLast, previous, item);
+      }
+    }
+
+    internal int IndexOfItem(JToken item)
+    {
+      int index = 0;
+      foreach (JToken token in Children())
+      {
+        if (token == item)
+          return index;
+
+        index++;
+      }
+
+      return -1;
+    }
+
+    internal virtual void InsertItem(int index, JToken item)
+    {
+      if (index == 0)
+      {
+        AddFirst(item);
+      }
+      else
+      {
+        JToken token = GetItem(index);
+        AddInternal(false, token.Previous, item);
+      }
+    }
+
+    internal virtual void RemoveItemAt(int index)
+    {
+      if (index < 0)
+        throw new ArgumentOutOfRangeException("index", "index is less than 0.");
+
+      CheckReentrancy();
+
+      int currentIndex = 0;
+      foreach (JToken token in Children())
+      {
+        if (index == currentIndex)
+        {
+          token.Remove();
+
+#if !SILVERLIGHT
+          OnListChanged(new ListChangedEventArgs(ListChangedType.ItemDeleted, index));
+#endif
+#if SILVERLIGHT || !(NET20 || NET35)
+          OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, token, index));
+#endif
+
+          return;
+        }
+
+        currentIndex++;
+      }
+
+      throw new ArgumentOutOfRangeException("index", "index is equal to or greater than Count.");
+    }
+
+    internal virtual bool RemoveItem(JToken item)
+    {
+      if (item == null || item.Parent != this)
+        return false;
+
+      CheckReentrancy();
+
+      JToken content = _content;
+
+      int itemIndex = 0;
+      while (content._next != item)
+      {
+        itemIndex++;
+        content = content._next;
+      }
+      if (content == item)
+      {
+        // token is containers last child
+        _content = null;
+      }
+      else
+      {
+        if (_content == item)
+        {
+          _content = content;
+        }
+        content._next = item._next;
+      }
+      item.Parent = null;
+      item.Next = null;
+
+#if !SILVERLIGHT
+      OnListChanged(new ListChangedEventArgs(ListChangedType.ItemDeleted, itemIndex));
+#endif
+#if SILVERLIGHT || !(NET20 || NET35)
+      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, itemIndex));
+#endif
+
+      return true;
+    }
+
+    internal virtual JToken GetItem(int index)
+    {
+      return Children().ElementAt(index);
+    }
+
+    internal virtual void SetItem(int index, JToken item)
+    {
+      CheckReentrancy();
+
+      JToken token = GetItem(index);
+      token.Replace(item);
+
+#if !SILVERLIGHT
+      OnListChanged(new ListChangedEventArgs(ListChangedType.ItemChanged, index));
+#endif
+#if SILVERLIGHT || !(NET20 || NET35)
+      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, item, token, index));
+#endif
+    }
+
+    internal virtual void ClearItems()
+    {
+      CheckReentrancy();
+
+      while (_content != null)
+      {
+        JToken o = _content;
+
+        JToken next = o._next;
+        if (o != _content || next != o._next)
+          throw new InvalidOperationException("This operation was corrupted by external code.");
+
+        if (next != o)
+          o._next = next._next;
+        else
+          _content = null;
+
+        next.Parent = null;
+        next._next = null;
+      }
+
+#if !SILVERLIGHT
+      OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
+#endif
+#if SILVERLIGHT || !(NET20 || NET35)
+      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
+#endif
+    }
+
+    internal virtual void ReplaceItem(JToken existing, JToken replacement)
+    {
+      if (existing == null || existing.Parent != this)
+        return;
+
+      if (IsTokenUnchanged(existing, replacement))
+        return;
+
+      CheckReentrancy();
+
+      replacement = EnsureParentToken(replacement);
+
+      ValidateToken(replacement, existing);
+
+      JToken content = _content;
+
+      int itemIndex = 0;
+      while (content._next != existing)
+      {
+        itemIndex++;
+        content = content._next;
+      }
+
+      if (content == existing)
+      {
+        // token is containers last child
+        _content = replacement;
+        replacement._next = replacement;
+      }
+      else
+      {
+        if (_content == existing)
+        {
+          _content = replacement;
+        }
+        content._next = replacement;
+        replacement._next = existing._next;
+      }
+
+      replacement.Parent = this;
+
+      existing.Parent = null;
+      existing.Next = null;
+
+#if !SILVERLIGHT
+      OnListChanged(new ListChangedEventArgs(ListChangedType.ItemChanged, itemIndex));
+#endif
+#if SILVERLIGHT || !(NET20 || NET35)
+      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, replacement, existing, itemIndex));
+#endif
+    }
+
+    internal virtual bool ContainsItem(JToken item)
+    {
+      return (IndexOfItem(item) != -1);
+    }
+
+    internal virtual void CopyItemsTo(Array array, int arrayIndex)
+    {
+      if (array == null)
+        throw new ArgumentNullException("array");
+      if (arrayIndex < 0)
+        throw new ArgumentOutOfRangeException("arrayIndex", "arrayIndex is less than 0.");
+      if (arrayIndex >= array.Length)
+        throw new ArgumentException("arrayIndex is equal to or greater than the length of array.");
+      if (CountItems() > array.Length - arrayIndex)
+        throw new ArgumentException("The number of elements in the source JObject is greater than the available space from arrayIndex to the end of the destination array.");
+
+      int index = 0;
+      foreach (JToken token in Children())
+      {
+        array.SetValue(token, arrayIndex + index);
+        index++;
+      }
+    }
+
+    internal virtual int CountItems()
+    {
+      return Children().Count();
+    }
+
+    internal static bool IsTokenUnchanged(JToken currentValue, JToken newValue)
+    {
+      JValue v1 = currentValue as JValue;
+      if (v1 != null)
+      {
+        // null will get turned into a JValue of type null
+        if (v1.Type == JTokenType.Null && newValue == null)
+          return true;
+
+        return v1.Equals(newValue);
+      }
+
+      return false;
+    }
+
+    internal virtual void ValidateToken(JToken o, JToken existing)
+    {
+      ValidationUtils.ArgumentNotNull(o, "o");
+
+      if (o.Type == JTokenType.Property)
+        throw new ArgumentException("Can not add {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, o.GetType(), GetType()));
+    }
+
+    /// <summary>
+    /// Adds the specified content as children of this <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="content">The content to be added.</param>
+    public void Add(object content)
+    {
+      AddInternal(true, Last, content);
+    }
+
+    /// <summary>
+    /// Adds the specified content as the first children of this <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="content">The content to be added.</param>
+    public void AddFirst(object content)
+    {
+      AddInternal(false, Last, content);
+    }
+
+    internal JToken CreateFromContent(object content)
+    {
+      if (content is JToken)
+        return (JToken)content;
+      
+      return new JValue(content);
+    }
+
+    /// <summary>
+    /// Creates an <see cref="JsonWriter"/> that can be used to add tokens to the <see cref="JToken"/>.
+    /// </summary>
+    /// <returns>An <see cref="JsonWriter"/> that is ready to have content written to it.</returns>
+    public JsonWriter CreateWriter()
+    {
+      return new JTokenWriter(this);
+    }
+
+    /// <summary>
+    /// Replaces the children nodes of this token with the specified content.
+    /// </summary>
+    /// <param name="content">The content.</param>
+    public void ReplaceAll(object content)
+    {
+      ClearItems();
+      Add(content);
+    }
+
+    /// <summary>
+    /// Removes the child nodes from this token.
+    /// </summary>
+    public void RemoveAll()
+    {
+      ClearItems();
+    }
+
+    internal void ReadTokenFrom(JsonReader r)
+    {
+      int startDepth = r.Depth;
+
+      if (!r.Read())
+        throw new Exception("Error reading {0} from JsonReader.".FormatWith(CultureInfo.InvariantCulture, GetType().Name));
+
+      ReadContentFrom(r);
+
+      int endDepth = r.Depth;
+
+      if (endDepth > startDepth)
+        throw new Exception("Unexpected end of content while loading {0}.".FormatWith(CultureInfo.InvariantCulture, GetType().Name));
+    }
+
+    internal void ReadContentFrom(JsonReader r)
+    {
+      ValidationUtils.ArgumentNotNull(r, "r");
+      IJsonLineInfo lineInfo = r as IJsonLineInfo;
+
+      JContainer parent = this;
+
+      do
+      {
+        if (parent is JProperty && ((JProperty)parent).Value != null)
+        {
+          if (parent == this)
+            return;
+
+          parent = parent.Parent;
+        }
+
+        switch (r.TokenType)
+        {
+          case JsonToken.None:
+            // new reader. move to actual content
+            break;
+          case JsonToken.StartArray:
+            JArray a = new JArray();
+            a.SetLineInfo(lineInfo);
+            parent.Add(a);
+            parent = a;
+            break;
+
+          case JsonToken.EndArray:
+            if (parent == this)
+              return;
+
+            parent = parent.Parent;
+            break;
+          case JsonToken.StartObject:
+            JObject o = new JObject();
+            o.SetLineInfo(lineInfo);
+            parent.Add(o);
+            parent = o;
+            break;
+          case JsonToken.EndObject:
+            if (parent == this)
+              return;
+
+            parent = parent.Parent;
+            break;
+          case JsonToken.StartConstructor:
+            JConstructor constructor = new JConstructor(r.Value.ToString());
+            constructor.SetLineInfo(constructor);
+            parent.Add(constructor);
+            parent = constructor;
+            break;
+          case JsonToken.EndConstructor:
+            if (parent == this)
+              return;
+
+            parent = parent.Parent;
+            break;
+          case JsonToken.String:
+          case JsonToken.Integer:
+          case JsonToken.Float:
+          case JsonToken.Date:
+          case JsonToken.Boolean:
+          case JsonToken.Bytes:
+            JValue v = new JValue(r.Value);
+            v.SetLineInfo(lineInfo);
+            parent.Add(v);
+            break;
+          case JsonToken.Comment:
+            v = JValue.CreateComment(r.Value.ToString());
+            v.SetLineInfo(lineInfo);
+            parent.Add(v);
+            break;
+          case JsonToken.Null:
+            v = new JValue(null, JTokenType.Null);
+            v.SetLineInfo(lineInfo);
+            parent.Add(v);
+            break;
+          case JsonToken.Undefined:
+            v = new JValue(null, JTokenType.Undefined);
+            v.SetLineInfo(lineInfo);
+            parent.Add(v);
+            break;
+          case JsonToken.PropertyName:
+            string propertyName = r.Value.ToString();
+            JProperty property = new JProperty(propertyName);
+            property.SetLineInfo(lineInfo);
+            JObject parentObject = (JObject) parent;
+            // handle multiple properties with the same name in JSON
+            JProperty existingPropertyWithName = parentObject.Property(propertyName);
+            if (existingPropertyWithName == null)
+              parent.Add(property);
+            else
+              existingPropertyWithName.Replace(property);
+            parent = property;
+            break;
+          default:
+            throw new InvalidOperationException("The JsonReader should not be on a token of type {0}.".FormatWith(CultureInfo.InvariantCulture, r.TokenType));
+        }
+      }
+      while (r.Read());
+    }
+
+    internal int ContentsHashCode()
+    {
+      int hashCode = 0;
+      foreach (JToken item in Children())
+      {
+        hashCode ^= item.GetDeepHashCode();
+      }
+      return hashCode;
+    }
+
+#if !SILVERLIGHT
+    string ITypedList.GetListName(PropertyDescriptor[] listAccessors)
+    {
+      return string.Empty;
+    }
+
+    PropertyDescriptorCollection ITypedList.GetItemProperties(PropertyDescriptor[] listAccessors)
+    {
+      ICustomTypeDescriptor d = First as ICustomTypeDescriptor;
+      if (d != null)
+        return d.GetProperties();
+
+      return null;
+    }
+#endif
+
+    #region IList<JToken> Members
+
+    int IList<JToken>.IndexOf(JToken item)
+    {
+      return IndexOfItem(item);
+    }
+
+    void IList<JToken>.Insert(int index, JToken item)
+    {
+      InsertItem(index, item);
+    }
+
+    void IList<JToken>.RemoveAt(int index)
+    {
+      RemoveItemAt(index);
+    }
+
+    JToken IList<JToken>.this[int index]
+    {
+      get { return GetItem(index); }
+      set { SetItem(index, value); }
+    }
+
+    #endregion
+
+    #region ICollection<JToken> Members
+
+    void ICollection<JToken>.Add(JToken item)
+    {
+      Add(item);
+    }
+
+    void ICollection<JToken>.Clear()
+    {
+      ClearItems();
+    }
+
+    bool ICollection<JToken>.Contains(JToken item)
+    {
+      return ContainsItem(item);
+    }
+
+    void ICollection<JToken>.CopyTo(JToken[] array, int arrayIndex)
+    {
+      CopyItemsTo(array, arrayIndex);
+    }
+
+    int ICollection<JToken>.Count
+    {
+      get { return CountItems(); }
+    }
+
+    bool ICollection<JToken>.IsReadOnly
+    {
+      get { return false; }
+    }
+
+    bool ICollection<JToken>.Remove(JToken item)
+    {
+      return RemoveItem(item);
+    }
+
+    #endregion
+
+    private JToken EnsureValue(object value)
+    {
+      if (value == null)
+        return null;
+
+      if (value is JToken)
+        return (JToken) value;
+
+      throw new ArgumentException("Argument is not a JToken.");
+    }
+
+    #region IList Members
+
+    int IList.Add(object value)
+    {
+      Add(EnsureValue(value));
+      return CountItems() - 1;
+    }
+
+    void IList.Clear()
+    {
+      ClearItems();
+    }
+
+    bool IList.Contains(object value)
+    {
+      return ContainsItem(EnsureValue(value));
+    }
+
+    int IList.IndexOf(object value)
+    {
+      return IndexOfItem(EnsureValue(value));
+    }
+
+    void IList.Insert(int index, object value)
+    {
+      InsertItem(index, EnsureValue(value));
+    }
+
+    bool IList.IsFixedSize
+    {
+      get { return false; }
+    }
+
+    bool IList.IsReadOnly
+    {
+      get { return false; }
+    }
+
+    void IList.Remove(object value)
+    {
+      RemoveItem(EnsureValue(value));
+    }
+
+    void IList.RemoveAt(int index)
+    {
+      RemoveItemAt(index);
+    }
+
+    object IList.this[int index]
+    {
+      get { return GetItem(index); }
+      set { SetItem(index, EnsureValue(value)); }
+    }
+
+    #endregion
+
+    #region ICollection Members
+
+    void ICollection.CopyTo(Array array, int index)
+    {
+      CopyItemsTo(array, index);
+    }
+
+    int ICollection.Count
+    {
+      get { return CountItems(); }
+    }
+
+    bool ICollection.IsSynchronized
+    {
+      get { return false; }
+    }
+
+    object ICollection.SyncRoot
+    {
+      get
+      {
+        if (_syncRoot == null)
+          Interlocked.CompareExchange(ref _syncRoot, new object(), null);
+
+        return _syncRoot;
+      }
+
+    }
+
+    #endregion
+
+    #region IBindingList Members
+
+#if !SILVERLIGHT
+    void IBindingList.AddIndex(PropertyDescriptor property)
+    {
+    }
+
+    object IBindingList.AddNew()
+    {
+      AddingNewEventArgs args = new AddingNewEventArgs();
+      OnAddingNew(args);
+
+      if (args.NewObject == null)
+        throw new Exception("Could not determine new value to add to '{0}'.".FormatWith(CultureInfo.InvariantCulture, GetType()));
+
+      if (!(args.NewObject is JToken))
+        throw new Exception("New item to be added to collection must be compatible with {0}.".FormatWith(CultureInfo.InvariantCulture, typeof (JToken)));
+
+      JToken newItem = (JToken)args.NewObject;
+      Add(newItem);
+
+      return newItem;
+    }
+
+    bool IBindingList.AllowEdit
+    {
+      get { return true; }
+    }
+
+    bool IBindingList.AllowNew
+    {
+      get { return true; }
+    }
+
+    bool IBindingList.AllowRemove
+    {
+      get { return true; }
+    }
+
+    void IBindingList.ApplySort(PropertyDescriptor property, ListSortDirection direction)
+    {
+      throw new NotSupportedException();
+    }
+
+    int IBindingList.Find(PropertyDescriptor property, object key)
+    {
+      throw new NotSupportedException();
+    }
+
+    bool IBindingList.IsSorted
+    {
+      get { return false; }
+    }
+
+    void IBindingList.RemoveIndex(PropertyDescriptor property)
+    {
+    }
+
+    void IBindingList.RemoveSort()
+    {
+      throw new NotSupportedException();
+    }
+
+    ListSortDirection IBindingList.SortDirection
+    {
+      get { return ListSortDirection.Ascending; }
+    }
+
+    PropertyDescriptor IBindingList.SortProperty
+    {
+      get { return null; }
+    }
+
+    bool IBindingList.SupportsChangeNotification
+    {
+      get { return true; }
+    }
+
+    bool IBindingList.SupportsSearching
+    {
+      get { return false; }
+    }
+
+    bool IBindingList.SupportsSorting
+    {
+      get { return false; }
+    }
+#endif
+
+    #endregion
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JEnumerable.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JEnumerable.cs
new file mode 100644 (file)
index 0000000..44ca165
--- /dev/null
@@ -0,0 +1,91 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Utilities;
+using System.Collections;
+
+namespace Newtonsoft.Json.Linq
+{
+  /// <summary>
+  /// Represents a collection of <see cref="JToken"/> objects.
+  /// </summary>
+  /// <typeparam name="T">The type of token</typeparam>
+  public struct JEnumerable<T> : IJEnumerable<T> where T : JToken
+  {
+    /// <summary>
+    /// An empty collection of <see cref="JToken"/> objects.
+    /// </summary>
+    public static readonly JEnumerable<T> Empty = new JEnumerable<T>(Enumerable.Empty<T>());
+
+    private IEnumerable<T> _enumerable;
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JEnumerable{T}"/> struct.
+    /// </summary>
+    /// <param name="enumerable">The enumerable.</param>
+    public JEnumerable(IEnumerable<T> enumerable)
+    {
+      ValidationUtils.ArgumentNotNull(enumerable, "enumerable");
+
+      _enumerable = enumerable;
+    }
+
+    /// <summary>
+    /// Returns an enumerator that iterates through the collection.
+    /// </summary>
+    /// <returns>
+    /// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
+    /// </returns>
+    public IEnumerator<T> GetEnumerator()
+    {
+      return _enumerable.GetEnumerator();
+    }
+
+    /// <summary>
+    /// Returns an enumerator that iterates through a collection.
+    /// </summary>
+    /// <returns>
+    /// An <see cref="T:System.Collections.IEnumerator"/> object that can be used to iterate through the collection.
+    /// </returns>
+    IEnumerator IEnumerable.GetEnumerator()
+    {
+      return GetEnumerator();
+    }
+
+    /// <summary>
+    /// Gets the <see cref="IJEnumerable{JToken}"/> with the specified key.
+    /// </summary>
+    /// <value></value>
+    public IJEnumerable<JToken> this[object key]
+    {
+      get { return new JEnumerable<JToken>(Extensions.Values<T, JToken>(_enumerable, key)); }
+    }
+
+    /// <summary>
+    /// Determines whether the specified <see cref="System.Object"/> is equal to this instance.
+    /// </summary>
+    /// <param name="obj">The <see cref="System.Object"/> to compare with this instance.</param>
+    /// <returns>
+    ///        <c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.
+    /// </returns>
+    public override bool Equals(object obj)
+    {
+      if (obj is JEnumerable<T>)
+        return _enumerable.Equals(((JEnumerable<T>)obj)._enumerable);
+
+      return false;
+    }
+
+    /// <summary>
+    /// Returns a hash code for this instance.
+    /// </summary>
+    /// <returns>
+    /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. 
+    /// </returns>
+    public override int GetHashCode()
+    {
+      return _enumerable.GetHashCode();
+    }
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JObject.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JObject.cs
new file mode 100644 (file)
index 0000000..1691351
--- /dev/null
@@ -0,0 +1,698 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.ComponentModel;
+#if !(NET35 || NET20 || WINDOWS_PHONE)
+using System.Dynamic;
+using System.Linq.Expressions;
+#endif
+using System.Linq;
+using System.IO;
+using Newtonsoft.Json.Utilities;
+using System.Globalization;
+#if !PocketPC && !SILVERLIGHT
+using Newtonsoft.Json.Linq.ComponentModel;
+#endif
+
+namespace Newtonsoft.Json.Linq
+{
+  /// <summary>
+  /// Represents a JSON object.
+  /// </summary>
+  public class JObject : JContainer, IDictionary<string, JToken>, INotifyPropertyChanged
+#if !(PocketPC || SILVERLIGHT)
+    , ICustomTypeDescriptor
+#endif
+#if !(PocketPC || SILVERLIGHT || NET20)
+    , INotifyPropertyChanging
+#endif
+  {
+    /// <summary>
+    /// Occurs when a property value changes.
+    /// </summary>
+    public event PropertyChangedEventHandler PropertyChanged;
+
+#if !(PocketPC || SILVERLIGHT || NET20)
+    /// <summary>
+    /// Occurs when a property value is changing.
+    /// </summary>
+    public event PropertyChangingEventHandler PropertyChanging;
+#endif
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JObject"/> class.
+    /// </summary>
+    public JObject()
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JObject"/> class from another <see cref="JObject"/> object.
+    /// </summary>
+    /// <param name="other">A <see cref="JObject"/> object to copy from.</param>
+    public JObject(JObject other)
+      : base(other)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JObject"/> class with the specified content.
+    /// </summary>
+    /// <param name="content">The contents of the object.</param>
+    public JObject(params object[] content)
+      : this((object)content)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JObject"/> class with the specified content.
+    /// </summary>
+    /// <param name="content">The contents of the object.</param>
+    public JObject(object content)
+    {
+      Add(content);
+    }
+
+    internal override bool DeepEquals(JToken node)
+    {
+      JObject t = node as JObject;
+      return (t != null && ContentsEqual(t));
+    }
+
+    internal override void ValidateToken(JToken o, JToken existing)
+    {
+      ValidationUtils.ArgumentNotNull(o, "o");
+
+      if (o.Type != JTokenType.Property)
+        throw new ArgumentException("Can not add {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, o.GetType(), GetType()));
+
+      // looping over all properties every time isn't good
+      // need to think about performance here
+      JProperty property = (JProperty)o;
+      foreach (JProperty childProperty in Children())
+      {
+        if (childProperty != existing && string.Equals(childProperty.Name, property.Name, StringComparison.Ordinal))
+          throw new ArgumentException("Can not add property {0} to {1}. Property with the same name already exists on object.".FormatWith(CultureInfo.InvariantCulture, property.Name, GetType()));
+      }
+    }
+
+    internal void InternalPropertyChanged(JProperty childProperty)
+    {
+      OnPropertyChanged(childProperty.Name);
+#if !SILVERLIGHT
+      OnListChanged(new ListChangedEventArgs(ListChangedType.ItemChanged, IndexOfItem(childProperty)));
+#endif
+#if SILVERLIGHT || !(NET20 || NET35)
+      OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, childProperty, childProperty, IndexOfItem(childProperty)));
+#endif
+    }
+
+    internal void InternalPropertyChanging(JProperty childProperty)
+    {
+#if !PocketPC && !SILVERLIGHT && !NET20
+      OnPropertyChanging(childProperty.Name);
+#endif
+    }
+
+    internal override JToken CloneToken()
+    {
+      return new JObject(this);
+    }
+
+    /// <summary>
+    /// Gets the node type for this <see cref="JToken"/>.
+    /// </summary>
+    /// <value>The type.</value>
+    public override JTokenType Type
+    {
+      get { return JTokenType.Object; }
+    }
+
+    /// <summary>
+    /// Gets an <see cref="IEnumerable{JProperty}"/> of this object's properties.
+    /// </summary>
+    /// <returns>An <see cref="IEnumerable{JProperty}"/> of this object's properties.</returns>
+    public IEnumerable<JProperty> Properties()
+    {
+      return Children().Cast<JProperty>();
+    }
+
+    /// <summary>
+    /// Gets a <see cref="JProperty"/> the specified name.
+    /// </summary>
+    /// <param name="name">The property name.</param>
+    /// <returns>A <see cref="JProperty"/> with the specified name or null.</returns>
+    public JProperty Property(string name)
+    {
+      return Properties()
+        .Where(p => string.Equals(p.Name, name, StringComparison.Ordinal))
+        .SingleOrDefault();
+    }
+
+    /// <summary>
+    /// Gets an <see cref="JEnumerable{JToken}"/> of this object's property values.
+    /// </summary>
+    /// <returns>An <see cref="JEnumerable{JToken}"/> of this object's property values.</returns>
+    public JEnumerable<JToken> PropertyValues()
+    {
+      return new JEnumerable<JToken>(Properties().Select(p => p.Value));
+    }
+
+    /// <summary>
+    /// Gets the <see cref="JToken"/> with the specified key.
+    /// </summary>
+    /// <value>The <see cref="JToken"/> with the specified key.</value>
+    public override JToken this[object key]
+    {
+      get
+      {
+        ValidationUtils.ArgumentNotNull(key, "o");
+
+        string propertyName = key as string;
+        if (propertyName == null)
+          throw new ArgumentException("Accessed JObject values with invalid key value: {0}. Object property name expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key)));
+
+        return this[propertyName];
+      }
+      set
+      {
+        ValidationUtils.ArgumentNotNull(key, "o");
+
+        string propertyName = key as string;
+        if (propertyName == null)
+          throw new ArgumentException("Set JObject values with invalid key value: {0}. Object property name expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key)));
+
+        this[propertyName] = value;
+      }
+    }
+
+    /// <summary>
+    /// Gets or sets the <see cref="Newtonsoft.Json.Linq.JToken"/> with the specified property name.
+    /// </summary>
+    /// <value></value>
+    public JToken this[string propertyName]
+    {
+      get
+      {
+        ValidationUtils.ArgumentNotNull(propertyName, "propertyName");
+
+        JProperty property = Property(propertyName);
+
+        return (property != null) ? property.Value : null;
+      }
+      set
+      {
+        JProperty property = Property(propertyName);
+        if (property != null)
+        {
+          property.Value = value;
+        }
+        else
+        {
+#if !PocketPC && !SILVERLIGHT && !NET20
+          OnPropertyChanging(propertyName);
+#endif
+          Add(new JProperty(propertyName, value));
+          OnPropertyChanged(propertyName);
+        }
+      }
+    }
+
+    /// <summary>
+    /// Loads an <see cref="JObject"/> from a <see cref="JsonReader"/>. 
+    /// </summary>
+    /// <param name="reader">A <see cref="JsonReader"/> that will be read for the content of the <see cref="JObject"/>.</param>
+    /// <returns>A <see cref="JObject"/> that contains the JSON that was read from the specified <see cref="JsonReader"/>.</returns>
+    public static new JObject Load(JsonReader reader)
+    {
+      ValidationUtils.ArgumentNotNull(reader, "reader");
+
+      if (reader.TokenType == JsonToken.None)
+      {
+        if (!reader.Read())
+          throw new Exception("Error reading JObject from JsonReader.");
+      }
+
+      if (reader.TokenType != JsonToken.StartObject)
+        throw new Exception(
+          "Error reading JObject from JsonReader. Current JsonReader item is not an object: {0}".FormatWith(
+            CultureInfo.InvariantCulture, reader.TokenType));
+
+      JObject o = new JObject();
+      o.SetLineInfo(reader as IJsonLineInfo);
+      
+      o.ReadTokenFrom(reader);
+
+      return o;
+    }
+
+    /// <summary>
+    /// Load a <see cref="JObject"/> from a string that contains JSON.
+    /// </summary>
+    /// <param name="json">A <see cref="String"/> that contains JSON.</param>
+    /// <returns>A <see cref="JObject"/> populated from the string that contains JSON.</returns>
+    public static new JObject Parse(string json)
+    {
+      JsonReader jsonReader = new JsonTextReader(new StringReader(json));
+
+      return Load(jsonReader);
+    }
+
+    /// <summary>
+    /// Creates a <see cref="JObject"/> from an object.
+    /// </summary>
+    /// <param name="o">The object that will be used to create <see cref="JObject"/>.</param>
+    /// <returns>A <see cref="JObject"/> with the values of the specified object</returns>
+    public static new JObject FromObject(object o)
+    {
+      return FromObject(o, new JsonSerializer());
+    }
+
+    /// <summary>
+    /// Creates a <see cref="JArray"/> from an object.
+    /// </summary>
+    /// <param name="o">The object that will be used to create <see cref="JArray"/>.</param>
+    /// <param name="jsonSerializer">The <see cref="JsonSerializer"/> that will be used to read the object.</param>
+    /// <returns>A <see cref="JArray"/> with the values of the specified object</returns>
+    public static new JObject FromObject(object o, JsonSerializer jsonSerializer)
+    {
+      JToken token = FromObjectInternal(o, jsonSerializer);
+
+      if (token != null && token.Type != JTokenType.Object)
+        throw new ArgumentException("Object serialized to {0}. JObject instance expected.".FormatWith(CultureInfo.InvariantCulture, token.Type));
+
+      return (JObject)token;
+    }
+
+    /// <summary>
+    /// Writes this token to a <see cref="JsonWriter"/>.
+    /// </summary>
+    /// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param>
+    /// <param name="converters">A collection of <see cref="JsonConverter"/> which will be used when writing the token.</param>
+    public override void WriteTo(JsonWriter writer, params JsonConverter[] converters)
+    {
+      writer.WriteStartObject();
+
+      foreach (JProperty property in ChildrenInternal())
+      {
+        property.WriteTo(writer, converters);
+      }
+
+      writer.WriteEndObject();
+    }
+
+    #region IDictionary<string,JToken> Members
+    /// <summary>
+    /// Adds the specified property name.
+    /// </summary>
+    /// <param name="propertyName">Name of the property.</param>
+    /// <param name="value">The value.</param>
+    public void Add(string propertyName, JToken value)
+    {
+      Add(new JProperty(propertyName, value));
+    }
+
+    bool IDictionary<string, JToken>.ContainsKey(string key)
+    {
+      return (Property(key) != null);
+    }
+
+    ICollection<string> IDictionary<string, JToken>.Keys
+    {
+      get { throw new NotImplementedException(); }
+    }
+
+    /// <summary>
+    /// Removes the property with the specified name.
+    /// </summary>
+    /// <param name="propertyName">Name of the property.</param>
+    /// <returns>true if item was successfully removed; otherwise, false.</returns>
+    public bool Remove(string propertyName)
+    {
+      JProperty property = Property(propertyName);
+      if (property == null)
+        return false;
+
+      property.Remove();
+      return true;
+    }
+
+    /// <summary>
+    /// Tries the get value.
+    /// </summary>
+    /// <param name="propertyName">Name of the property.</param>
+    /// <param name="value">The value.</param>
+    /// <returns>true if a value was successfully retrieved; otherwise, false.</returns>
+    public bool TryGetValue(string propertyName, out JToken value)
+    {
+      JProperty property = Property(propertyName);
+      if (property == null)
+      {
+        value = null;
+        return false;
+      }
+
+      value = property.Value;
+      return true;
+    }
+
+    ICollection<JToken> IDictionary<string, JToken>.Values
+    {
+      get { throw new NotImplementedException(); }
+    }
+
+    #endregion
+
+    #region ICollection<KeyValuePair<string,JToken>> Members
+
+    void ICollection<KeyValuePair<string,JToken>>.Add(KeyValuePair<string, JToken> item)
+    {
+      Add(new JProperty(item.Key, item.Value));
+    }
+
+    void ICollection<KeyValuePair<string, JToken>>.Clear()
+    {
+      RemoveAll();
+    }
+
+    bool ICollection<KeyValuePair<string,JToken>>.Contains(KeyValuePair<string, JToken> item)
+    {
+      JProperty property = Property(item.Key);
+      if (property == null)
+        return false;
+
+      return (property.Value == item.Value);
+    }
+
+    void ICollection<KeyValuePair<string,JToken>>.CopyTo(KeyValuePair<string, JToken>[] array, int arrayIndex)
+    {
+      if (array == null)
+        throw new ArgumentNullException("array");
+      if (arrayIndex < 0)
+        throw new ArgumentOutOfRangeException("arrayIndex", "arrayIndex is less than 0.");
+      if (arrayIndex >= array.Length)
+        throw new ArgumentException("arrayIndex is equal to or greater than the length of array.");
+      if (Count > array.Length - arrayIndex)
+        throw new ArgumentException("The number of elements in the source JObject is greater than the available space from arrayIndex to the end of the destination array.");
+
+      int index = 0;
+      foreach (JProperty property in Properties())
+      {
+        array[arrayIndex + index] = new KeyValuePair<string, JToken>(property.Name, property.Value);
+        index++;
+      }
+    }
+
+    /// <summary>
+    /// Gets the number of elements contained in the <see cref="T:System.Collections.Generic.ICollection`1"/>.
+    /// </summary>
+    /// <value></value>
+    /// <returns>The number of elements contained in the <see cref="T:System.Collections.Generic.ICollection`1"/>.</returns>
+    public int Count
+    {
+      get { return Children().Count(); }
+    }
+
+    bool ICollection<KeyValuePair<string,JToken>>.IsReadOnly
+    {
+      get { return false; }
+    }
+
+    bool ICollection<KeyValuePair<string,JToken>>.Remove(KeyValuePair<string, JToken> item)
+    {
+      if (!((ICollection<KeyValuePair<string,JToken>>)this).Contains(item))
+        return false;
+
+      ((IDictionary<string, JToken>)this).Remove(item.Key);
+      return true;
+    }
+
+    #endregion
+
+    internal override int GetDeepHashCode()
+    {
+      return ContentsHashCode();
+    }
+
+    /// <summary>
+    /// Returns an enumerator that iterates through the collection.
+    /// </summary>
+    /// <returns>
+    /// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
+    /// </returns>
+    public IEnumerator<KeyValuePair<string, JToken>> GetEnumerator()
+    {
+      foreach (JProperty property in Properties())
+      {
+        yield return new KeyValuePair<string, JToken>(property.Name, property.Value);
+      }
+    }
+
+    /// <summary>
+    /// Raises the <see cref="PropertyChanged"/> event with the provided arguments.
+    /// </summary>
+    /// <param name="propertyName">Name of the property.</param>
+    protected virtual void OnPropertyChanged(string propertyName)
+    {
+      if (PropertyChanged != null)
+        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+    }
+
+#if !PocketPC && !SILVERLIGHT && !NET20
+    /// <summary>
+    /// Raises the <see cref="PropertyChanging"/> event with the provided arguments.
+    /// </summary>
+    /// <param name="propertyName">Name of the property.</param>
+    protected virtual void OnPropertyChanging(string propertyName)
+    {
+      if (PropertyChanging != null)
+        PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
+    }
+#endif
+
+#if !PocketPC && !SILVERLIGHT
+    // include custom type descriptor on JObject rather than use a provider because the properties are specific to a type
+    #region ICustomTypeDescriptor
+    /// <summary>
+    /// Returns the properties for this instance of a component.
+    /// </summary>
+    /// <returns>
+    /// A <see cref="T:System.ComponentModel.PropertyDescriptorCollection"/> that represents the properties for this component instance.
+    /// </returns>
+    PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties()
+    {
+      return ((ICustomTypeDescriptor) this).GetProperties(null);
+    }
+
+    private static Type GetTokenPropertyType(JToken token)
+    {
+      if (token is JValue)
+      {
+        JValue v = (JValue)token;
+        return (v.Value != null) ? v.Value.GetType() : typeof(object);
+      }
+
+      return token.GetType();
+    }
+
+    /// <summary>
+    /// Returns the properties for this instance of a component using the attribute array as a filter.
+    /// </summary>
+    /// <param name="attributes">An array of type <see cref="T:System.Attribute"/> that is used as a filter.</param>
+    /// <returns>
+    /// A <see cref="T:System.ComponentModel.PropertyDescriptorCollection"/> that represents the filtered properties for this component instance.
+    /// </returns>
+    PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes)
+    {
+      PropertyDescriptorCollection descriptors = new PropertyDescriptorCollection(null);
+
+      foreach (KeyValuePair<string, JToken> propertyValue in this)
+      {
+        descriptors.Add(new JPropertyDescriptor(propertyValue.Key, GetTokenPropertyType(propertyValue.Value)));
+      }
+
+      return descriptors;
+    }
+
+    /// <summary>
+    /// Returns a collection of custom attributes for this instance of a component.
+    /// </summary>
+    /// <returns>
+    /// An <see cref="T:System.ComponentModel.AttributeCollection"/> containing the attributes for this object.
+    /// </returns>
+    AttributeCollection ICustomTypeDescriptor.GetAttributes()
+    {
+      return AttributeCollection.Empty;
+    }
+
+    /// <summary>
+    /// Returns the class name of this instance of a component.
+    /// </summary>
+    /// <returns>
+    /// The class name of the object, or null if the class does not have a name.
+    /// </returns>
+    string ICustomTypeDescriptor.GetClassName()
+    {
+      return null;
+    }
+
+    /// <summary>
+    /// Returns the name of this instance of a component.
+    /// </summary>
+    /// <returns>
+    /// The name of the object, or null if the object does not have a name.
+    /// </returns>
+    string ICustomTypeDescriptor.GetComponentName()
+    {
+      return null;
+    }
+
+    /// <summary>
+    /// Returns a type converter for this instance of a component.
+    /// </summary>
+    /// <returns>
+    /// A <see cref="T:System.ComponentModel.TypeConverter"/> that is the converter for this object, or null if there is no <see cref="T:System.ComponentModel.TypeConverter"/> for this object.
+    /// </returns>
+    TypeConverter ICustomTypeDescriptor.GetConverter()
+    {
+      return new TypeConverter();
+    }
+
+    /// <summary>
+    /// Returns the default event for this instance of a component.
+    /// </summary>
+    /// <returns>
+    /// An <see cref="T:System.ComponentModel.EventDescriptor"/> that represents the default event for this object, or null if this object does not have events.
+    /// </returns>
+    EventDescriptor ICustomTypeDescriptor.GetDefaultEvent()
+    {
+      return null;
+    }
+
+    /// <summary>
+    /// Returns the default property for this instance of a component.
+    /// </summary>
+    /// <returns>
+    /// A <see cref="T:System.ComponentModel.PropertyDescriptor"/> that represents the default property for this object, or null if this object does not have properties.
+    /// </returns>
+    PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty()
+    {
+      return null;
+    }
+
+    /// <summary>
+    /// Returns an editor of the specified type for this instance of a component.
+    /// </summary>
+    /// <param name="editorBaseType">A <see cref="T:System.Type"/> that represents the editor for this object.</param>
+    /// <returns>
+    /// An <see cref="T:System.Object"/> of the specified type that is the editor for this object, or null if the editor cannot be found.
+    /// </returns>
+    object ICustomTypeDescriptor.GetEditor(Type editorBaseType)
+    {
+      return null;
+    }
+
+    /// <summary>
+    /// Returns the events for this instance of a component using the specified attribute array as a filter.
+    /// </summary>
+    /// <param name="attributes">An array of type <see cref="T:System.Attribute"/> that is used as a filter.</param>
+    /// <returns>
+    /// An <see cref="T:System.ComponentModel.EventDescriptorCollection"/> that represents the filtered events for this component instance.
+    /// </returns>
+    EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes)
+    {
+      return EventDescriptorCollection.Empty;
+    }
+
+    /// <summary>
+    /// Returns the events for this instance of a component.
+    /// </summary>
+    /// <returns>
+    /// An <see cref="T:System.ComponentModel.EventDescriptorCollection"/> that represents the events for this component instance.
+    /// </returns>
+    EventDescriptorCollection ICustomTypeDescriptor.GetEvents()
+    {
+      return EventDescriptorCollection.Empty;
+    }
+
+    /// <summary>
+    /// Returns an object that contains the property described by the specified property descriptor.
+    /// </summary>
+    /// <param name="pd">A <see cref="T:System.ComponentModel.PropertyDescriptor"/> that represents the property whose owner is to be found.</param>
+    /// <returns>
+    /// An <see cref="T:System.Object"/> that represents the owner of the specified property.
+    /// </returns>
+    object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd)
+    {
+      return null;
+    }
+    #endregion
+#endif
+
+#if !(NET35 || NET20 || WINDOWS_PHONE)
+    /// <summary>
+    /// Returns the <see cref="T:System.Dynamic.DynamicMetaObject"/> responsible for binding operations performed on this object.
+    /// </summary>
+    /// <param name="parameter">The expression tree representation of the runtime value.</param>
+    /// <returns>
+    /// The <see cref="T:System.Dynamic.DynamicMetaObject"/> to bind this object.
+    /// </returns>
+    protected override DynamicMetaObject GetMetaObject(Expression parameter)
+    {
+      return new DynamicProxyMetaObject<JObject>(parameter, this, new JObjectDynamicProxy(), true);
+    }
+
+    private class JObjectDynamicProxy : DynamicProxy<JObject>
+    {
+      public override bool TryGetMember(JObject instance, GetMemberBinder binder, out object result)
+      {
+        // result can be null
+        result = instance[binder.Name];
+        return true;
+      }
+
+      public override bool TrySetMember(JObject instance, SetMemberBinder binder, object value)
+      {
+        JToken v = value as JToken;
+
+        // this can throw an error if value isn't a valid for a JValue
+        if (v == null)
+          v = new JValue(value);
+
+        instance[binder.Name] = v;
+        return true;
+      }
+
+      public override IEnumerable<string> GetDynamicMemberNames(JObject instance)
+      {
+        return instance.Properties().Select(p => p.Name);
+      }
+    }
+#endif
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JPath.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JPath.cs
new file mode 100644 (file)
index 0000000..fe67f76
--- /dev/null
@@ -0,0 +1,170 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Linq
+{
+  internal class JPath
+  {
+    private readonly string _expression;
+    public List<object> Parts { get; private set; }
+
+    private int _currentIndex;
+
+    public JPath(string expression)
+    {
+      ValidationUtils.ArgumentNotNull(expression, "expression");
+      _expression = expression;
+      Parts = new List<object>();
+
+      ParseMain();
+    }
+
+    private void ParseMain()
+    {
+      int currentPartStartIndex = _currentIndex;
+      bool followingIndexer = false;
+
+      while (_currentIndex < _expression.Length)
+      {
+        char currentChar = _expression[_currentIndex];
+
+        switch (currentChar)
+        {
+          case '[':
+          case '(':
+            if (_currentIndex > currentPartStartIndex)
+            {
+              string member = _expression.Substring(currentPartStartIndex, _currentIndex - currentPartStartIndex);
+              Parts.Add(member);
+            }
+
+            ParseIndexer(currentChar);
+            currentPartStartIndex = _currentIndex + 1;
+            followingIndexer = true;
+            break;
+          case ']':
+          case ')':
+            throw new Exception("Unexpected character while parsing path: " + currentChar);
+          case '.':
+            if (_currentIndex > currentPartStartIndex)
+            {
+              string member = _expression.Substring(currentPartStartIndex, _currentIndex - currentPartStartIndex);
+              Parts.Add(member);
+            }
+            currentPartStartIndex = _currentIndex + 1;
+            followingIndexer = false;
+            break;
+          default:
+            if (followingIndexer)
+              throw new Exception("Unexpected character following indexer: " + currentChar);
+            break;
+        }
+
+        _currentIndex++;
+      }
+
+      if (_currentIndex > currentPartStartIndex)
+      {
+        string member = _expression.Substring(currentPartStartIndex, _currentIndex - currentPartStartIndex);
+        Parts.Add(member);
+      }
+    }
+
+    private void ParseIndexer(char indexerOpenChar)
+    {
+      _currentIndex++;
+
+      char indexerCloseChar = (indexerOpenChar == '[') ? ']' : ')';
+      int indexerStart = _currentIndex;
+      int indexerLength = 0;
+      bool indexerClosed = false;
+
+      while (_currentIndex < _expression.Length)
+      {
+        char currentCharacter = _expression[_currentIndex];
+        if (char.IsDigit(currentCharacter))
+        {
+          indexerLength++;
+        }
+        else if (currentCharacter == indexerCloseChar)
+        {
+          indexerClosed = true;
+          break;
+        }
+        else
+        {
+          throw new Exception("Unexpected character while parsing path indexer: " + currentCharacter);
+        }
+
+        _currentIndex++;
+      }
+
+      if (!indexerClosed)
+        throw new Exception("Path ended with open indexer. Expected " + indexerCloseChar);
+
+      if (indexerLength == 0)
+        throw new Exception("Empty path indexer.");
+
+      string indexer = _expression.Substring(indexerStart, indexerLength);
+      Parts.Add(Convert.ToInt32(indexer, CultureInfo.InvariantCulture));
+    }
+
+    internal JToken Evaluate(JToken root, bool errorWhenNoMatch)
+    {
+      JToken current = root;
+
+      foreach (object part in Parts)
+      {
+        string propertyName = part as string;
+        if (propertyName != null)
+        {
+          JObject o = current as JObject;
+          if (o != null)
+          {
+            current = o[propertyName];
+
+            if (current == null && errorWhenNoMatch)
+              throw new Exception("Property '{0}' does not exist on JObject.".FormatWith(CultureInfo.InvariantCulture, propertyName));
+          }
+          else
+          {
+            if (errorWhenNoMatch)
+              throw new Exception("Property '{0}' not valid on {1}.".FormatWith(CultureInfo.InvariantCulture, propertyName, current.GetType().Name));
+
+            return null;
+          }
+        }
+        else
+        {
+          int index = (int) part;
+
+          JArray a = current as JArray;
+
+          if (a != null)
+          {
+            if (a.Count <= index)
+            {
+              if (errorWhenNoMatch)
+                throw new IndexOutOfRangeException("Index {0} outside the bounds of JArray.".FormatWith(CultureInfo.InvariantCulture, index));
+              
+              return null;
+            }
+
+            current = a[index];
+          }
+          else
+          {
+            if (errorWhenNoMatch)
+              throw new Exception("Index {0} not valid on {1}.".FormatWith(CultureInfo.InvariantCulture, index, current.GetType().Name));
+
+            return null;
+          }
+        }
+      }
+
+      return current;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JProperty.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JProperty.cs
new file mode 100644 (file)
index 0000000..4b17f91
--- /dev/null
@@ -0,0 +1,268 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Utilities;
+using System.Diagnostics;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Linq
+{
+  /// <summary>
+  /// Represents a JSON property.
+  /// </summary>
+  public class JProperty : JContainer
+  {
+    private readonly string _name;
+
+    /// <summary>
+    /// Gets the property name.
+    /// </summary>
+    /// <value>The property name.</value>
+    public string Name
+    {
+      [DebuggerStepThrough]
+      get { return _name; }
+    }
+
+    /// <summary>
+    /// Gets or sets the property value.
+    /// </summary>
+    /// <value>The property value.</value>
+    public JToken Value
+    {
+      [DebuggerStepThrough]
+      get { return Content; }
+      set
+      {
+        CheckReentrancy();
+
+        JToken newValue = value ?? new JValue((object) null);
+
+        if (Content == null)
+        {
+          newValue = EnsureParentToken(newValue);
+
+          Content = newValue;
+          Content.Parent = this;
+          Content.Next = Content;
+        }
+        else
+        {
+          Content.Replace(newValue);
+        }
+      }
+    }
+
+    internal override void ReplaceItem(JToken existing, JToken replacement)
+    {
+      if (IsTokenUnchanged(existing, replacement))
+        return;
+
+      if (Parent != null)
+        ((JObject)Parent).InternalPropertyChanging(this);
+
+      base.ReplaceItem(existing, replacement);
+
+      if (Parent != null)
+        ((JObject)Parent).InternalPropertyChanged(this);
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JProperty"/> class from another <see cref="JProperty"/> object.
+    /// </summary>
+    /// <param name="other">A <see cref="JProperty"/> object to copy from.</param>
+    public JProperty(JProperty other)
+      : base(other)
+    {
+      _name = other.Name;
+    }
+
+    internal override void AddItem(bool isLast, JToken previous, JToken item)
+    {
+      if (Value != null)
+        throw new Exception("{0} cannot have multiple values.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty)));
+
+      Value = item;
+    }
+
+    internal override JToken GetItem(int index)
+    {
+      if (index != 0)
+        throw new ArgumentOutOfRangeException();
+
+      return Value;
+    }
+
+    internal override void SetItem(int index, JToken item)
+    {
+      if (index != 0)
+        throw new ArgumentOutOfRangeException();
+      
+      Value = item;
+    }
+
+    internal override bool RemoveItem(JToken item)
+    {
+      throw new Exception("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty)));
+    }
+
+    internal override void RemoveItemAt(int index)
+    {
+      throw new Exception("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty)));
+    }
+
+    internal override void InsertItem(int index, JToken item)
+    {
+      throw new Exception("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty)));
+    }
+
+    internal override bool ContainsItem(JToken item)
+    {
+      return (Value == item);
+    }
+
+    internal override void ClearItems()
+    {
+      throw new Exception("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty)));
+    }
+
+    /// <summary>
+    /// Returns a collection of the child tokens of this token, in document order.
+    /// </summary>
+    /// <returns>
+    /// An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> containing the child tokens of this <see cref="JToken"/>, in document order.
+    /// </returns>
+    public override JEnumerable<JToken> Children()
+    {
+      return new JEnumerable<JToken>(GetValueEnumerable());
+    }
+
+    private IEnumerable<JToken> GetValueEnumerable()
+    {
+      yield return Value;
+    }
+
+    internal override bool DeepEquals(JToken node)
+    {
+      JProperty t = node as JProperty;
+      return (t != null && _name == t.Name && ContentsEqual(t));
+    }
+
+    internal override JToken CloneToken()
+    {
+      return new JProperty(this);
+    }
+
+    /// <summary>
+    /// Gets the node type for this <see cref="JToken"/>.
+    /// </summary>
+    /// <value>The type.</value>
+    public override JTokenType Type
+    {
+      [DebuggerStepThrough]
+      get { return JTokenType.Property; }
+    }
+
+    internal JProperty(string name)
+    {
+      // called from JTokenWriter
+      ValidationUtils.ArgumentNotNull(name, "name");
+
+      _name = name;
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JProperty"/> class.
+    /// </summary>
+    /// <param name="name">The property name.</param>
+    /// <param name="content">The property content.</param>
+    public JProperty(string name, params object[] content)
+      : this(name, (object)content)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JProperty"/> class.
+    /// </summary>
+    /// <param name="name">The property name.</param>
+    /// <param name="content">The property content.</param>
+    public JProperty(string name, object content)
+    {
+      ValidationUtils.ArgumentNotNull(name, "name");
+
+      _name = name;
+
+      Value = IsMultiContent(content)
+        ? new JArray(content)
+        : CreateFromContent(content);
+    }
+
+    /// <summary>
+    /// Writes this token to a <see cref="JsonWriter"/>.
+    /// </summary>
+    /// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param>
+    /// <param name="converters">A collection of <see cref="JsonConverter"/> which will be used when writing the token.</param>
+    public override void WriteTo(JsonWriter writer, params JsonConverter[] converters)
+    {
+      writer.WritePropertyName(_name);
+      Value.WriteTo(writer, converters);
+    }
+
+    internal override int GetDeepHashCode()
+    {
+      return _name.GetHashCode() ^ ((Value != null) ? Value.GetDeepHashCode() : 0);
+    }
+
+    /// <summary>
+    /// Loads an <see cref="JProperty"/> from a <see cref="JsonReader"/>. 
+    /// </summary>
+    /// <param name="reader">A <see cref="JsonReader"/> that will be read for the content of the <see cref="JProperty"/>.</param>
+    /// <returns>A <see cref="JProperty"/> that contains the JSON that was read from the specified <see cref="JsonReader"/>.</returns>
+    public static new JProperty Load(JsonReader reader)
+    {
+      if (reader.TokenType == JsonToken.None)
+      {
+        if (!reader.Read())
+          throw new Exception("Error reading JProperty from JsonReader.");
+      }
+      if (reader.TokenType != JsonToken.PropertyName)
+        throw new Exception(
+          "Error reading JProperty from JsonReader. Current JsonReader item is not a property: {0}".FormatWith(
+            CultureInfo.InvariantCulture, reader.TokenType));
+
+      JProperty p = new JProperty((string)reader.Value);
+      p.SetLineInfo(reader as IJsonLineInfo);
+
+      p.ReadTokenFrom(reader);
+
+      return p;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JRaw.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JRaw.cs
new file mode 100644 (file)
index 0000000..401100a
--- /dev/null
@@ -0,0 +1,54 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Linq
+{
+  /// <summary>
+  /// Represents a raw JSON string.
+  /// </summary>
+  public class JRaw : JValue
+  {
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JRaw"/> class from another <see cref="JRaw"/> object.
+    /// </summary>
+    /// <param name="other">A <see cref="JRaw"/> object to copy from.</param>
+    public JRaw(JRaw other)
+      : base(other)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JRaw"/> class.
+    /// </summary>
+    /// <param name="rawJson">The raw json.</param>
+    public JRaw(object rawJson)
+      : base(rawJson, JTokenType.Raw)
+    {
+    }
+
+    /// <summary>
+    /// Creates an instance of <see cref="JRaw"/> with the content of the reader's current token.
+    /// </summary>
+    /// <param name="reader">The reader.</param>
+    /// <returns>An instance of <see cref="JRaw"/> with the content of the reader's current token.</returns>
+    public static JRaw Create(JsonReader reader)
+    {
+      using (StringWriter sw = new StringWriter(CultureInfo.InvariantCulture))
+      using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
+      {
+        jsonWriter.WriteToken(reader);
+
+        return new JRaw(sw.ToString());
+      }
+    }
+
+    internal override JToken CloneToken()
+    {
+      return new JRaw(this);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JToken.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JToken.cs
new file mode 100644 (file)
index 0000000..5a09ce5
--- /dev/null
@@ -0,0 +1,1347 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+#if !(NET35 || NET20 || WINDOWS_PHONE)
+using System.Dynamic;
+using System.Linq.Expressions;
+#endif
+using System.Linq;
+using System.IO;
+using Newtonsoft.Json.Utilities;
+using System.Diagnostics;
+using System.Globalization;
+using System.Collections;
+using System.ComponentModel;
+
+namespace Newtonsoft.Json.Linq
+{
+  /// <summary>
+  /// Represents an abstract JSON token.
+  /// </summary>
+  public abstract class JToken : IJEnumerable<JToken>, IJsonLineInfo
+#if !SILVERLIGHT
+, ICloneable
+#endif
+#if !(NET35 || NET20 || WINDOWS_PHONE)
+, IDynamicMetaObjectProvider
+#endif
+  {
+    private JContainer _parent;
+    internal JToken _next;
+    private static JTokenEqualityComparer _equalityComparer;
+
+    private int? _lineNumber;
+    private int? _linePosition;
+
+    /// <summary>
+    /// Gets a comparer that can compare two tokens for value equality.
+    /// </summary>
+    /// <value>A <see cref="JTokenEqualityComparer"/> that can compare two nodes for value equality.</value>
+    public static JTokenEqualityComparer EqualityComparer
+    {
+      get
+      {
+        if (_equalityComparer == null)
+          _equalityComparer = new JTokenEqualityComparer();
+
+        return _equalityComparer;
+      }
+    }
+
+    /// <summary>
+    /// Gets or sets the parent.
+    /// </summary>
+    /// <value>The parent.</value>
+    public JContainer Parent
+    {
+      [DebuggerStepThrough]
+      get { return _parent; }
+      internal set { _parent = value; }
+    }
+
+    /// <summary>
+    /// Gets the root <see cref="JToken"/> of this <see cref="JToken"/>.
+    /// </summary>
+    /// <value>The root <see cref="JToken"/> of this <see cref="JToken"/>.</value>
+    public JToken Root
+    {
+      get
+      {
+        JContainer parent = Parent;
+        if (parent == null)
+          return this;
+
+        while (parent.Parent != null)
+        {
+          parent = parent.Parent;
+        }
+
+        return parent;
+      }
+    }
+
+    internal abstract JToken CloneToken();
+    internal abstract bool DeepEquals(JToken node);
+
+    /// <summary>
+    /// Gets the node type for this <see cref="JToken"/>.
+    /// </summary>
+    /// <value>The type.</value>
+    public abstract JTokenType Type { get; }
+
+    /// <summary>
+    /// Gets a value indicating whether this token has childen tokens.
+    /// </summary>
+    /// <value>
+    ///        <c>true</c> if this token has child values; otherwise, <c>false</c>.
+    /// </value>
+    public abstract bool HasValues { get; }
+
+    /// <summary>
+    /// Compares the values of two tokens, including the values of all descendant tokens.
+    /// </summary>
+    /// <param name="t1">The first <see cref="JToken"/> to compare.</param>
+    /// <param name="t2">The second <see cref="JToken"/> to compare.</param>
+    /// <returns>true if the tokens are equal; otherwise false.</returns>
+    public static bool DeepEquals(JToken t1, JToken t2)
+    {
+      return (t1 == t2 || (t1 != null && t2 != null && t1.DeepEquals(t2)));
+    }
+
+    /// <summary>
+    /// Gets the next sibling token of this node.
+    /// </summary>
+    /// <value>The <see cref="JToken"/> that contains the next sibling token.</value>
+    public JToken Next
+    {
+      get
+      {
+        if (_parent != null && _next != _parent.First)
+          return _next;
+
+        return null;
+      }
+      internal set { _next = value; }
+    }
+
+    /// <summary>
+    /// Gets the previous sibling token of this node.
+    /// </summary>
+    /// <value>The <see cref="JToken"/> that contains the previous sibling token.</value>
+    public JToken Previous
+    {
+      get
+      {
+        if (_parent == null)
+          return null;
+
+        JToken parentNext = _parent.Content._next;
+        JToken parentNextBefore = null;
+        while (parentNext != this)
+        {
+          parentNextBefore = parentNext;
+          parentNext = parentNext.Next;
+        }
+        return parentNextBefore;
+      }
+    }
+
+    internal JToken()
+    {
+    }
+
+    /// <summary>
+    /// Adds the specified content immediately after this token.
+    /// </summary>
+    /// <param name="content">A content object that contains simple content or a collection of content objects to be added after this token.</param>
+    public void AddAfterSelf(object content)
+    {
+      if (_parent == null)
+        throw new InvalidOperationException("The parent is missing.");
+
+      _parent.AddInternal((Next == null), this, content);
+    }
+
+    /// <summary>
+    /// Adds the specified content immediately before this token.
+    /// </summary>
+    /// <param name="content">A content object that contains simple content or a collection of content objects to be added before this token.</param>
+    public void AddBeforeSelf(object content)
+    {
+      if (_parent == null)
+        throw new InvalidOperationException("The parent is missing.");
+
+      JToken previous = Previous;
+      if (previous == null)
+        previous = _parent.Last;
+
+      _parent.AddInternal(false, previous, content);
+    }
+
+    /// <summary>
+    /// Returns a collection of the ancestor tokens of this token.
+    /// </summary>
+    /// <returns>A collection of the ancestor tokens of this token.</returns>
+    public IEnumerable<JToken> Ancestors()
+    {
+      for (JToken parent = Parent; parent != null; parent = parent.Parent)
+      {
+        yield return parent;
+      }
+    }
+
+    /// <summary>
+    /// Returns a collection of the sibling tokens after this token, in document order.
+    /// </summary>
+    /// <returns>A collection of the sibling tokens after this tokens, in document order.</returns>
+    public IEnumerable<JToken> AfterSelf()
+    {
+      if (Parent == null)
+        yield break;
+
+      for (JToken o = Next; o != null; o = o.Next)
+        yield return o;
+    }
+
+    /// <summary>
+    /// Returns a collection of the sibling tokens before this token, in document order.
+    /// </summary>
+    /// <returns>A collection of the sibling tokens before this token, in document order.</returns>
+    public IEnumerable<JToken> BeforeSelf()
+    {
+      for (JToken o = Parent.First; o != this; o = o.Next)
+        yield return o;
+    }
+
+    /// <summary>
+    /// Gets the <see cref="JToken"/> with the specified key.
+    /// </summary>
+    /// <value>The <see cref="JToken"/> with the specified key.</value>
+    public virtual JToken this[object key]
+    {
+      get { throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); }
+      set { throw new InvalidOperationException("Cannot set child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); }
+    }
+
+    /// <summary>
+    /// Gets the <see cref="JToken"/> with the specified key converted to the specified type.
+    /// </summary>
+    /// <typeparam name="T">The type to convert the token to.</typeparam>
+    /// <param name="key">The token key.</param>
+    /// <returns>The converted token value.</returns>
+    public virtual T Value<T>(object key)
+    {
+      JToken token = this[key];
+
+      return Extensions.Convert<JToken, T>(token);
+    }
+
+    /// <summary>
+    /// Get the first child token of this token.
+    /// </summary>
+    /// <value>A <see cref="JToken"/> containing the first child token of the <see cref="JToken"/>.</value>
+    public virtual JToken First
+    {
+      get { throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); }
+    }
+
+    /// <summary>
+    /// Get the last child token of this token.
+    /// </summary>
+    /// <value>A <see cref="JToken"/> containing the last child token of the <see cref="JToken"/>.</value>
+    public virtual JToken Last
+    {
+      get { throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); }
+    }
+
+    /// <summary>
+    /// Returns a collection of the child tokens of this token, in document order.
+    /// </summary>
+    /// <returns>An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> containing the child tokens of this <see cref="JToken"/>, in document order.</returns>
+    public virtual JEnumerable<JToken> Children()
+    {
+      throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType()));
+    }
+
+    /// <summary>
+    /// Returns a collection of the child tokens of this token, in document order, filtered by the specified type.
+    /// </summary>
+    /// <typeparam name="T">The type to filter the child tokens on.</typeparam>
+    /// <returns>A <see cref="JEnumerable{T}"/> containing the child tokens of this <see cref="JToken"/>, in document order.</returns>
+    public JEnumerable<T> Children<T>() where T : JToken
+    {
+      return new JEnumerable<T>(Children().OfType<T>());
+    }
+
+    /// <summary>
+    /// Returns a collection of the child values of this token, in document order.
+    /// </summary>
+    /// <typeparam name="T">The type to convert the values to.</typeparam>
+    /// <returns>A <see cref="IEnumerable{T}"/> containing the child values of this <see cref="JToken"/>, in document order.</returns>
+    public virtual IEnumerable<T> Values<T>()
+    {
+      throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType()));
+    }
+
+    /// <summary>
+    /// Removes this token from its parent.
+    /// </summary>
+    public void Remove()
+    {
+      if (_parent == null)
+        throw new InvalidOperationException("The parent is missing.");
+
+      _parent.RemoveItem(this);
+    }
+
+    /// <summary>
+    /// Replaces this token with the specified token.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    public void Replace(JToken value)
+    {
+      if (_parent == null)
+        throw new InvalidOperationException("The parent is missing.");
+
+      _parent.ReplaceItem(this, value);
+    }
+
+    /// <summary>
+    /// Writes this token to a <see cref="JsonWriter"/>.
+    /// </summary>
+    /// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param>
+    /// <param name="converters">A collection of <see cref="JsonConverter"/> which will be used when writing the token.</param>
+    public abstract void WriteTo(JsonWriter writer, params JsonConverter[] converters);
+
+    /// <summary>
+    /// Returns the indented JSON for this token.
+    /// </summary>
+    /// <returns>
+    /// The indented JSON for this token.
+    /// </returns>
+    public override string ToString()
+    {
+      return ToString(Formatting.Indented);
+    }
+
+    /// <summary>
+    /// Returns the JSON for this token using the given formatting and converters.
+    /// </summary>
+    /// <param name="formatting">Indicates how the output is formatted.</param>
+    /// <param name="converters">A collection of <see cref="JsonConverter"/> which will be used when writing the token.</param>
+    /// <returns>The JSON for this token using the given formatting and converters.</returns>
+    public string ToString(Formatting formatting, params JsonConverter[] converters)
+    {
+      using (StringWriter sw = new StringWriter(CultureInfo.InvariantCulture))
+      {
+        JsonTextWriter jw = new JsonTextWriter(sw);
+        jw.Formatting = formatting;
+
+        WriteTo(jw, converters);
+
+        return sw.ToString();
+      }
+    }
+
+    private static JValue EnsureValue(JToken value)
+    {
+      if (value == null)
+        throw new ArgumentNullException("value");
+
+      if (value is JProperty)
+        value = ((JProperty)value).Value;
+
+      JValue v = value as JValue;
+
+      return v;
+    }
+
+    private static string GetType(JToken token)
+    {
+      ValidationUtils.ArgumentNotNull(token, "token");
+
+      if (token is JProperty)
+        token = ((JProperty)token).Value;
+
+      return token.Type.ToString();
+    }
+
+    private static bool IsNullable(JToken o)
+    {
+      return (o.Type == JTokenType.Undefined || o.Type == JTokenType.Null);
+    }
+
+    private static bool ValidateFloat(JToken o, bool nullable)
+    {
+      return (o.Type == JTokenType.Float || o.Type == JTokenType.Integer || (nullable && IsNullable(o)));
+    }
+
+    private static bool ValidateInteger(JToken o, bool nullable)
+    {
+      return (o.Type == JTokenType.Integer || (nullable && IsNullable(o)));
+    }
+
+    private static bool ValidateDate(JToken o, bool nullable)
+    {
+      return (o.Type == JTokenType.Date || (nullable && IsNullable(o)));
+    }
+
+    private static bool ValidateBoolean(JToken o, bool nullable)
+    {
+      return (o.Type == JTokenType.Boolean || (nullable && IsNullable(o)));
+    }
+
+    private static bool ValidateString(JToken o)
+    {
+      return (o.Type == JTokenType.String || o.Type == JTokenType.Comment || o.Type == JTokenType.Raw || IsNullable(o));
+    }
+
+    private static bool ValidateBytes(JToken o)
+    {
+      return (o.Type == JTokenType.Bytes || IsNullable(o));
+    }
+
+    #region Cast from operators
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Boolean"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator bool(JToken value)
+    {
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateBoolean(v, false))
+        throw new ArgumentException("Can not convert {0} to Boolean.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (bool)v.Value;
+    }
+
+#if !PocketPC && !NET20
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.DateTimeOffset"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator DateTimeOffset(JToken value)
+    {
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateDate(v, false))
+        throw new ArgumentException("Can not convert {0} to DateTimeOffset.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (DateTimeOffset)v.Value;
+    }
+#endif
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Boolean}"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator bool?(JToken value)
+    {
+      if (value == null)
+        return null;
+
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateBoolean(v, true))
+        throw new ArgumentException("Can not convert {0} to Boolean.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (bool?)v.Value;
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Int64"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator long(JToken value)
+    {
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateInteger(v, false))
+        throw new ArgumentException("Can not convert {0} to Int64.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (long)v.Value;
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{DateTime}"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator DateTime?(JToken value)
+    {
+      if (value == null)
+        return null;
+
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateDate(v, true))
+        throw new ArgumentException("Can not convert {0} to DateTime.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (DateTime?)v.Value;
+    }
+
+#if !PocketPC && !NET20
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{DateTimeOffset}"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator DateTimeOffset?(JToken value)
+    {
+      if (value == null)
+        return null;
+
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateDate(v, true))
+        throw new ArgumentException("Can not convert {0} to DateTimeOffset.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (DateTimeOffset?)v.Value;
+    }
+#endif
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Decimal}"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator decimal?(JToken value)
+    {
+      if (value == null)
+        return null;
+
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateFloat(v, true))
+        throw new ArgumentException("Can not convert {0} to Decimal.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (v.Value != null) ? (decimal?)Convert.ToDecimal(v.Value, CultureInfo.InvariantCulture) : null;
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Double}"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator double?(JToken value)
+    {
+      if (value == null)
+        return null;
+
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateFloat(v, true))
+        throw new ArgumentException("Can not convert {0} to Double.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (double?)v.Value;
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Int32"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator int(JToken value)
+    {
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateInteger(v, false))
+        throw new ArgumentException("Can not convert {0} to Int32.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return Convert.ToInt32(v.Value, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Int16"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator short(JToken value)
+    {
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateInteger(v, false))
+        throw new ArgumentException("Can not convert {0} to Int16.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return Convert.ToInt16(v.Value, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.UInt16"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    [CLSCompliant(false)]
+    public static explicit operator ushort(JToken value)
+    {
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateInteger(v, false))
+        throw new ArgumentException("Can not convert {0} to UInt16.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return Convert.ToUInt16(v.Value, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Int32}"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator int?(JToken value)
+    {
+      if (value == null)
+        return null;
+
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateInteger(v, true))
+        throw new ArgumentException("Can not convert {0} to Int32.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (v.Value != null) ? (int?)Convert.ToInt32(v.Value, CultureInfo.InvariantCulture) : null;
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Int16}"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator short?(JToken value)
+    {
+      if (value == null)
+        return null;
+
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateInteger(v, true))
+        throw new ArgumentException("Can not convert {0} to Int16.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (v.Value != null) ? (short?)Convert.ToInt16(v.Value, CultureInfo.InvariantCulture) : null;
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{UInt16}"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    [CLSCompliant(false)]
+    public static explicit operator ushort?(JToken value)
+    {
+      if (value == null)
+        return null;
+
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateInteger(v, true))
+        throw new ArgumentException("Can not convert {0} to UInt16.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (v.Value != null) ? (ushort?)Convert.ToInt16(v.Value, CultureInfo.InvariantCulture) : null;
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.DateTime"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator DateTime(JToken value)
+    {
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateDate(v, false))
+        throw new ArgumentException("Can not convert {0} to DateTime.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (DateTime)v.Value;
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Int64}"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator long?(JToken value)
+    {
+      if (value == null)
+        return null;
+
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateInteger(v, true))
+        throw new ArgumentException("Can not convert {0} to Int64.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (long?)v.Value;
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Single}"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator float?(JToken value)
+    {
+      if (value == null)
+        return null;
+
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateFloat(v, true))
+        throw new ArgumentException("Can not convert {0} to Single.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (v.Value != null) ? (float?)Convert.ToSingle(v.Value, CultureInfo.InvariantCulture) : null;
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Decimal"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator decimal(JToken value)
+    {
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateFloat(v, false))
+        throw new ArgumentException("Can not convert {0} to Decimal.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return Convert.ToDecimal(v.Value, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{UInt32}"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    [CLSCompliant(false)]
+    public static explicit operator uint?(JToken value)
+    {
+      if (value == null)
+        return null;
+
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateInteger(v, true))
+        throw new ArgumentException("Can not convert {0} to UInt32.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (uint?)v.Value;
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{UInt64}"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    [CLSCompliant(false)]
+    public static explicit operator ulong?(JToken value)
+    {
+      if (value == null)
+        return null;
+
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateInteger(v, true))
+        throw new ArgumentException("Can not convert {0} to UInt64.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (ulong?)v.Value;
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Double"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator double(JToken value)
+    {
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateFloat(v, false))
+        throw new ArgumentException("Can not convert {0} to Double.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (double)v.Value;
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.Single"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator float(JToken value)
+    {
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateFloat(v, false))
+        throw new ArgumentException("Can not convert {0} to Single.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return Convert.ToSingle(v.Value, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.String"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator string(JToken value)
+    {
+      if (value == null)
+        return null;
+
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateString(v))
+        throw new ArgumentException("Can not convert {0} to String.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (string)v.Value;
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.UInt32"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    [CLSCompliant(false)]
+    public static explicit operator uint(JToken value)
+    {
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateInteger(v, false))
+        throw new ArgumentException("Can not convert {0} to UInt32.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return Convert.ToUInt32(v.Value, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.UInt64"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    [CLSCompliant(false)]
+    public static explicit operator ulong(JToken value)
+    {
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateInteger(v, false))
+        throw new ArgumentException("Can not convert {0} to UInt64.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return Convert.ToUInt64(v.Value, CultureInfo.InvariantCulture);
+    }
+
+    /// <summary>
+    /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="T:System.Byte[]"/>.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>The result of the conversion.</returns>
+    public static explicit operator byte[](JToken value)
+    {
+      JValue v = EnsureValue(value);
+      if (v == null || !ValidateBytes(v))
+        throw new ArgumentException("Can not convert {0} to byte array.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
+
+      return (byte[])v.Value;
+    }
+    #endregion
+
+    #region Cast to operators
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Boolean"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(bool value)
+    {
+      return new JValue(value);
+    }
+
+#if !PocketPC && !NET20
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="DateTimeOffset"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(DateTimeOffset value)
+    {
+      return new JValue(value);
+    }
+#endif
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Nullable{Boolean}"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(bool? value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Nullable{Int64}"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(long value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Nullable{DateTime}"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(DateTime? value)
+    {
+      return new JValue(value);
+    }
+
+#if !PocketPC && !NET20
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Nullable{DateTimeOffset}"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(DateTimeOffset? value)
+    {
+      return new JValue(value);
+    }
+#endif
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Nullable{Decimal}"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(decimal? value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Nullable{Double}"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(double? value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Int16"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    [CLSCompliant(false)]
+    public static implicit operator JToken(short value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="UInt16"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    [CLSCompliant(false)]
+    public static implicit operator JToken(ushort value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Int32"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(int value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Nullable{Int32}"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(int? value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="DateTime"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(DateTime value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Nullable{Int64}"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(long? value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Nullable{Single}"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(float? value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Decimal"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(decimal value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Nullable{Int16}"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    [CLSCompliant(false)]
+    public static implicit operator JToken(short? value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Nullable{UInt16}"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    [CLSCompliant(false)]
+    public static implicit operator JToken(ushort? value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Nullable{UInt32}"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    [CLSCompliant(false)]
+    public static implicit operator JToken(uint? value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Nullable{UInt64}"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    [CLSCompliant(false)]
+    public static implicit operator JToken(ulong? value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Double"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(double value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="Single"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(float value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="String"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(string value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="UInt32"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    [CLSCompliant(false)]
+    public static implicit operator JToken(uint value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="UInt64"/> to <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    [CLSCompliant(false)]
+    public static implicit operator JToken(ulong value)
+    {
+      return new JValue(value);
+    }
+
+    /// <summary>
+    /// Performs an implicit conversion from <see cref="T:System.Byte[]"/> to <see cref="Newtonsoft.Json.Linq.JToken"/>.
+    /// </summary>
+    /// <param name="value">The value to create a <see cref="JValue"/> from.</param>
+    /// <returns>The <see cref="JValue"/> initialized with the specified value.</returns>
+    public static implicit operator JToken(byte[] value)
+    {
+      return new JValue(value);
+    }
+    #endregion
+
+    IEnumerator IEnumerable.GetEnumerator()
+    {
+      return ((IEnumerable<JToken>)this).GetEnumerator();
+    }
+
+    IEnumerator<JToken> IEnumerable<JToken>.GetEnumerator()
+    {
+      return Children().GetEnumerator();
+    }
+
+    internal abstract int GetDeepHashCode();
+
+    IJEnumerable<JToken> IJEnumerable<JToken>.this[object key]
+    {
+      get { return this[key]; }
+    }
+
+    /// <summary>
+    /// Creates an <see cref="JsonReader"/> for this token.
+    /// </summary>
+    /// <returns>An <see cref="JsonReader"/> that can be used to read this token and its descendants.</returns>
+    public JsonReader CreateReader()
+    {
+      return new JTokenReader(this);
+    }
+
+    internal static JToken FromObjectInternal(object o, JsonSerializer jsonSerializer)
+    {
+      ValidationUtils.ArgumentNotNull(o, "o");
+      ValidationUtils.ArgumentNotNull(jsonSerializer, "jsonSerializer");
+
+      JToken token;
+      using (JTokenWriter jsonWriter = new JTokenWriter())
+      {
+        jsonSerializer.Serialize(jsonWriter, o);
+        token = jsonWriter.Token;
+      }
+
+      return token;
+    }
+
+    /// <summary>
+    /// Creates a <see cref="JToken"/> from an object.
+    /// </summary>
+    /// <param name="o">The object that will be used to create <see cref="JToken"/>.</param>
+    /// <returns>A <see cref="JToken"/> with the value of the specified object</returns>
+    public static JToken FromObject(object o)
+    {
+      return FromObjectInternal(o, new JsonSerializer());
+    }
+
+    /// <summary>
+    /// Creates a <see cref="JToken"/> from an object using the specified <see cref="JsonSerializer"/>.
+    /// </summary>
+    /// <param name="o">The object that will be used to create <see cref="JToken"/>.</param>
+    /// <param name="jsonSerializer">The <see cref="JsonSerializer"/> that will be used when reading the object.</param>
+    /// <returns>A <see cref="JToken"/> with the value of the specified object</returns>
+    public static JToken FromObject(object o, JsonSerializer jsonSerializer)
+    {
+      return FromObjectInternal(o, jsonSerializer);
+    }
+
+    /// <summary>
+    /// Creates a <see cref="JToken"/> from a <see cref="JsonReader"/>.
+    /// </summary>
+    /// <param name="reader">An <see cref="JsonReader"/> positioned at the token to read into this <see cref="JToken"/>.</param>
+    /// <returns>
+    /// An <see cref="JToken"/> that contains the token and its descendant tokens
+    /// that were read from the reader. The runtime type of the token is determined
+    /// by the token type of the first token encountered in the reader.
+    /// </returns>
+    public static JToken ReadFrom(JsonReader reader)
+    {
+      ValidationUtils.ArgumentNotNull(reader, "reader");
+
+      if (reader.TokenType == JsonToken.None)
+      {
+        if (!reader.Read())
+          throw new Exception("Error reading JToken from JsonReader.");
+      }
+
+      if (reader.TokenType == JsonToken.StartObject)
+        return JObject.Load(reader);
+
+      if (reader.TokenType == JsonToken.StartArray)
+        return JArray.Load(reader);
+
+      if (reader.TokenType == JsonToken.PropertyName)
+        return JProperty.Load(reader);
+
+      if (reader.TokenType == JsonToken.StartConstructor)
+        return JConstructor.Load(reader);
+
+      // hack. change to look at TokenType rather than using value
+      if (!JsonReader.IsStartToken(reader.TokenType))
+        return new JValue(reader.Value);
+
+      // TODO: loading constructor and parameters?
+      throw new Exception("Error reading JToken from JsonReader. Unexpected token: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
+    }
+
+    /// <summary>
+    /// Load a <see cref="JToken"/> from a string that contains JSON.
+    /// </summary>
+    /// <param name="json">A <see cref="String"/> that contains JSON.</param>
+    /// <returns>A <see cref="JToken"/> populated from the string that contains JSON.</returns>
+    public static JToken Parse(string json)
+    {
+      JsonReader jsonReader = new JsonTextReader(new StringReader(json));
+
+      return Load(jsonReader);
+    }
+
+    /// <summary>
+    /// Creates a <see cref="JToken"/> from a <see cref="JsonReader"/>.
+    /// </summary>
+    /// <param name="reader">An <see cref="JsonReader"/> positioned at the token to read into this <see cref="JToken"/>.</param>
+    /// <returns>
+    /// An <see cref="JToken"/> that contains the token and its descendant tokens
+    /// that were read from the reader. The runtime type of the token is determined
+    /// by the token type of the first token encountered in the reader.
+    /// </returns>
+    public static JToken Load(JsonReader reader)
+    {
+      return ReadFrom(reader);
+    }
+
+    internal void SetLineInfo(IJsonLineInfo lineInfo)
+    {
+      if (lineInfo == null || !lineInfo.HasLineInfo())
+        return;
+
+      SetLineInfo(lineInfo.LineNumber, lineInfo.LinePosition);
+    }
+
+    internal void SetLineInfo(int lineNumber, int linePosition)
+    {
+      _lineNumber = lineNumber;
+      _linePosition = linePosition;
+    }
+
+    bool IJsonLineInfo.HasLineInfo()
+    {
+      return (_lineNumber != null && _linePosition != null);
+    }
+
+    int IJsonLineInfo.LineNumber
+    {
+      get { return _lineNumber ?? 0; }
+    }
+
+    int IJsonLineInfo.LinePosition
+    {
+      get { return _linePosition ?? 0; }
+    }
+
+    /// <summary>
+    /// Selects the token that matches the object path.
+    /// </summary>
+    /// <param name="path">
+    /// The object path from the current <see cref="JToken"/> to the <see cref="JToken"/>
+    /// to be returned. This must be a string of property names or array indexes separated
+    /// by periods, such as <code>Tables[0].DefaultView[0].Price</code> in C# or
+    /// <code>Tables(0).DefaultView(0).Price</code> in Visual Basic.
+    /// </param>
+    /// <returns>The <see cref="JToken"/> that matches the object path or a null reference if no matching token is found.</returns>
+    public JToken SelectToken(string path)
+    {
+      return SelectToken(path, false);
+    }
+
+    /// <summary>
+    /// Selects the token that matches the object path.
+    /// </summary>
+    /// <param name="path">
+    /// The object path from the current <see cref="JToken"/> to the <see cref="JToken"/>
+    /// to be returned. This must be a string of property names or array indexes separated
+    /// by periods, such as <code>Tables[0].DefaultView[0].Price</code> in C# or
+    /// <code>Tables(0).DefaultView(0).Price</code> in Visual Basic.
+    /// </param>
+    /// <param name="errorWhenNoMatch">A flag to indicate whether an error should be thrown if no token is found.</param>
+    /// <returns>The <see cref="JToken"/> that matches the object path.</returns>
+    public JToken SelectToken(string path, bool errorWhenNoMatch)
+    {
+      JPath p = new JPath(path);
+      return p.Evaluate(this, errorWhenNoMatch);
+    }
+
+#if !(NET35 || NET20 || WINDOWS_PHONE)
+    /// <summary>
+    /// Returns the <see cref="T:System.Dynamic.DynamicMetaObject"/> responsible for binding operations performed on this object.
+    /// </summary>
+    /// <param name="parameter">The expression tree representation of the runtime value.</param>
+    /// <returns>
+    /// The <see cref="T:System.Dynamic.DynamicMetaObject"/> to bind this object.
+    /// </returns>
+    protected virtual DynamicMetaObject GetMetaObject(Expression parameter)
+    {
+      return new DynamicProxyMetaObject<JToken>(parameter, this, new DynamicProxy<JToken>(), true);
+    }
+
+    /// <summary>
+    /// Returns the <see cref="T:System.Dynamic.DynamicMetaObject"/> responsible for binding operations performed on this object.
+    /// </summary>
+    /// <param name="parameter">The expression tree representation of the runtime value.</param>
+    /// <returns>
+    /// The <see cref="T:System.Dynamic.DynamicMetaObject"/> to bind this object.
+    /// </returns>
+    DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter)
+    {
+      return GetMetaObject(parameter);
+    }
+#endif
+
+#if !SILVERLIGHT
+    object ICloneable.Clone()
+    {
+      return DeepClone();
+    }
+#endif
+
+    /// <summary>
+    /// Creates a new instance of the <see cref="JToken"/>. All child tokens are recursively cloned.
+    /// </summary>
+    /// <returns>A new instance of the <see cref="JToken"/>.</returns>
+    public JToken DeepClone()
+    {
+      return CloneToken();
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JTokenEqualityComparer.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JTokenEqualityComparer.cs
new file mode 100644 (file)
index 0000000..93acd9a
--- /dev/null
@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Linq
+{
+  /// <summary>
+  /// Compares tokens to determine whether they are equal.
+  /// </summary>
+  public class JTokenEqualityComparer : IEqualityComparer<JToken>
+  {
+    /// <summary>
+    /// Determines whether the specified objects are equal.
+    /// </summary>
+    /// <param name="x">The first object of type <see cref="JToken"/> to compare.</param>
+    /// <param name="y">The second object of type <see cref="JToken"/> to compare.</param>
+    /// <returns>
+    /// true if the specified objects are equal; otherwise, false.
+    /// </returns>
+    public bool Equals(JToken x, JToken y)
+    {
+      return JToken.DeepEquals(x, y);
+    }
+
+    /// <summary>
+    /// Returns a hash code for the specified object.
+    /// </summary>
+    /// <param name="obj">The <see cref="T:System.Object"/> for which a hash code is to be returned.</param>
+    /// <returns>A hash code for the specified object.</returns>
+    /// <exception cref="T:System.ArgumentNullException">The type of <paramref name="obj"/> is a reference type and <paramref name="obj"/> is null.</exception>
+    public int GetHashCode(JToken obj)
+    {
+      if (obj == null)
+        return 0;
+
+      return obj.GetDeepHashCode();
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JTokenReader.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JTokenReader.cs
new file mode 100644 (file)
index 0000000..e09cdb8
--- /dev/null
@@ -0,0 +1,289 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Utilities;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Linq
+{
+  /// <summary>
+  /// Represents a reader that provides fast, non-cached, forward-only access to serialized Json data.
+  /// </summary>
+  public class JTokenReader : JsonReader, IJsonLineInfo
+  {
+    private readonly JToken _root;
+    private JToken _parent;
+    private JToken _current;
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JTokenReader"/> class.
+    /// </summary>
+    /// <param name="token">The token to read from.</param>
+    public JTokenReader(JToken token)
+    {
+      ValidationUtils.ArgumentNotNull(token, "token");
+
+      _root = token;
+      _current = token;
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="T:Byte[]"/>.
+    /// </summary>
+    /// <returns>
+    /// A <see cref="T:Byte[]"/> or a null reference if the next JSON token is null.
+    /// </returns>
+    public override byte[] ReadAsBytes()
+    {
+      Read();
+
+      // attempt to convert possible base 64 string to bytes
+      if (TokenType == JsonToken.String)
+      {
+        string s = (string) Value;
+        byte[] data = (s.Length == 0) ? new byte[0] : Convert.FromBase64String(s);
+        SetToken(JsonToken.Bytes, data);
+      }
+
+      if (TokenType == JsonToken.Null)
+        return null;
+      if (TokenType == JsonToken.Bytes)
+        return (byte[])Value;
+
+      throw new JsonReaderException("Error reading bytes. Expected bytes but got {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
+    }
+
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="Nullable{Decimal}"/>.
+    /// </summary>
+    /// <returns>A <see cref="Nullable{Decimal}"/>.</returns>
+    public override decimal? ReadAsDecimal()
+    {
+      Read();
+
+      if (TokenType == JsonToken.Null)
+        return null;
+      if (TokenType == JsonToken.Integer || TokenType == JsonToken.Float)
+      {
+        SetToken(JsonToken.Float, Convert.ToDecimal(Value, CultureInfo.InvariantCulture));
+        return (decimal) Value;
+      }
+
+      throw new JsonReaderException("Error reading decimal. Expected a number but got {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
+    }
+
+#if !NET20
+    /// <summary>
+    /// Reads the next JSON token from the stream as a <see cref="Nullable{DateTimeOffset}"/>.
+    /// </summary>
+    /// <returns>A <see cref="Nullable{DateTimeOffset}"/>.</returns>
+    public override DateTimeOffset? ReadAsDateTimeOffset()
+    {
+      Read();
+
+      if (TokenType == JsonToken.Null)
+        return null;
+      if (TokenType == JsonToken.Date)
+      {
+        SetToken(JsonToken.Date, new DateTimeOffset((DateTime)Value));
+        return (DateTimeOffset)Value;
+      }
+
+      throw new JsonReaderException("Error reading date. Expected bytes but got {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
+    }
+#endif
+
+    /// <summary>
+    /// Reads the next JSON token from the stream.
+    /// </summary>
+    /// <returns>
+    /// true if the next token was read successfully; false if there are no more tokens to read.
+    /// </returns>
+    public override bool Read()
+    {
+      if (CurrentState != State.Start)
+      {
+        JContainer container = _current as JContainer;
+        if (container != null && _parent != container)
+          return ReadInto(container);
+        else
+          return ReadOver(_current);
+      }
+
+      SetToken(_current);
+      return true;
+    }
+
+    private bool ReadOver(JToken t)
+    {
+      if (t == _root)
+        return ReadToEnd();
+
+      JToken next = t.Next;
+      if ((next == null || next == t) || t == t.Parent.Last)
+      {
+        if (t.Parent == null)
+          return ReadToEnd();
+
+        return SetEnd(t.Parent);
+      }
+      else
+      {
+        _current = next;
+        SetToken(_current);
+        return true;
+      }
+    }
+
+    private bool ReadToEnd()
+    {
+      //CurrentState = State.Finished;
+      return false;
+    }
+
+    private bool IsEndElement
+    {
+      get { return (_current == _parent); }
+    }
+
+    private JsonToken? GetEndToken(JContainer c)
+    {
+      switch (c.Type)
+      {
+        case JTokenType.Object:
+          return JsonToken.EndObject;
+        case JTokenType.Array:
+          return JsonToken.EndArray;
+        case JTokenType.Constructor:
+          return JsonToken.EndConstructor;
+        case JTokenType.Property:
+          return null;
+        default:
+          throw MiscellaneousUtils.CreateArgumentOutOfRangeException("Type", c.Type, "Unexpected JContainer type.");
+      }
+    }
+
+    private bool ReadInto(JContainer c)
+    {
+      JToken firstChild = c.First;
+      if (firstChild == null)
+      {
+        return SetEnd(c);
+      }
+      else
+      {
+        SetToken(firstChild);
+        _current = firstChild;
+        _parent = c;
+        return true;
+      }
+    }
+
+    private bool SetEnd(JContainer c)
+    {
+      JsonToken? endToken = GetEndToken(c);
+      if (endToken != null)
+      {
+        SetToken(endToken.Value);
+        _current = c;
+        _parent = c;
+        return true;
+      }
+      else
+      {
+        return ReadOver(c);
+      }
+    }
+
+    private void SetToken(JToken token)
+    {
+      switch (token.Type)
+      {
+        case JTokenType.Object:
+          SetToken(JsonToken.StartObject);
+          break;
+        case JTokenType.Array:
+          SetToken(JsonToken.StartArray);
+          break;
+        case JTokenType.Constructor:
+          SetToken(JsonToken.StartConstructor);
+          break;
+        case JTokenType.Property:
+          SetToken(JsonToken.PropertyName, ((JProperty)token).Name);
+          break;
+        case JTokenType.Comment:
+          SetToken(JsonToken.Comment, ((JValue)token).Value);
+          break;
+        case JTokenType.Integer:
+          SetToken(JsonToken.Integer, ((JValue)token).Value);
+          break;
+        case JTokenType.Float:
+          SetToken(JsonToken.Float, ((JValue)token).Value);
+          break;
+        case JTokenType.String:
+          SetToken(JsonToken.String, ((JValue)token).Value);
+          break;
+        case JTokenType.Boolean:
+          SetToken(JsonToken.Boolean, ((JValue)token).Value);
+          break;
+        case JTokenType.Null:
+          SetToken(JsonToken.Null, ((JValue)token).Value);
+          break;
+        case JTokenType.Undefined:
+          SetToken(JsonToken.Undefined, ((JValue)token).Value);
+          break;
+        case JTokenType.Date:
+          SetToken(JsonToken.Date, ((JValue)token).Value);
+          break;
+        case JTokenType.Raw:
+          SetToken(JsonToken.Raw, ((JValue)token).Value);
+          break;
+        case JTokenType.Bytes:
+          SetToken(JsonToken.Bytes, ((JValue)token).Value);
+          break;
+        default:
+          throw MiscellaneousUtils.CreateArgumentOutOfRangeException("Type", token.Type, "Unexpected JTokenType.");
+      }
+    }
+
+    bool IJsonLineInfo.HasLineInfo()
+    {
+      if (CurrentState == State.Start)
+        return false;
+
+      IJsonLineInfo info = IsEndElement ? null : _current;
+      return (info != null && info.HasLineInfo());
+    }
+
+    int IJsonLineInfo.LineNumber
+    {
+      get
+      {
+        if (CurrentState == State.Start)
+          return 0;
+
+        IJsonLineInfo info = IsEndElement ? null : _current;
+        if (info != null)
+          return info.LineNumber;
+        
+        return 0;
+      }
+    }
+
+    int IJsonLineInfo.LinePosition
+    {
+      get
+      {
+        if (CurrentState == State.Start)
+          return 0;
+
+        IJsonLineInfo info = IsEndElement ? null : _current;
+        if (info != null)
+          return info.LinePosition;
+
+        return 0;
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JTokenType.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JTokenType.cs
new file mode 100644 (file)
index 0000000..8150ed0
--- /dev/null
@@ -0,0 +1,94 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Linq
+{
+  /// <summary>
+  /// Specifies the type of token.
+  /// </summary>
+  public enum JTokenType
+  {
+    /// <summary>
+    /// No token type has been set.
+    /// </summary>
+    None,
+    /// <summary>
+    /// A JSON object.
+    /// </summary>
+    Object,
+    /// <summary>
+    /// A JSON array.
+    /// </summary>
+    Array,
+    /// <summary>
+    /// A JSON constructor.
+    /// </summary>
+    Constructor,
+    /// <summary>
+    /// A JSON object property.
+    /// </summary>
+    Property,
+    /// <summary>
+    /// A comment.
+    /// </summary>
+    Comment,
+    /// <summary>
+    /// An integer value.
+    /// </summary>
+    Integer,
+    /// <summary>
+    /// A float value.
+    /// </summary>
+    Float,
+    /// <summary>
+    /// A string value.
+    /// </summary>
+    String,
+    /// <summary>
+    /// A boolean value.
+    /// </summary>
+    Boolean,
+    /// <summary>
+    /// A null value.
+    /// </summary>
+    Null,
+    /// <summary>
+    /// An undefined value.
+    /// </summary>
+    Undefined,
+    /// <summary>
+    /// A date value.
+    /// </summary>
+    Date,
+    /// <summary>
+    /// A raw JSON value.
+    /// </summary>
+    Raw,
+    /// <summary>
+    /// A collection of bytes value.
+    /// </summary>
+    Bytes
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JTokenWriter.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JTokenWriter.cs
new file mode 100644 (file)
index 0000000..7044137
--- /dev/null
@@ -0,0 +1,373 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Linq
+{
+  /// <summary>
+  /// Represents a writer that provides a fast, non-cached, forward-only way of generating Json data.
+  /// </summary>
+  public class JTokenWriter : JsonWriter
+  {
+    private JContainer _token;
+    private JContainer _parent;
+    // used when writer is writing single value and the value has no containing parent
+    private JValue _value;
+
+    /// <summary>
+    /// Gets the token being writen.
+    /// </summary>
+    /// <value>The token being writen.</value>
+    public JToken Token
+    {
+      get
+      {
+        if (_token != null)
+          return _token;
+
+        return _value;
+      }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JTokenWriter"/> class writing to the given <see cref="JContainer"/>.
+    /// </summary>
+    /// <param name="container">The container being written to.</param>
+    public JTokenWriter(JContainer container)
+    {
+      ValidationUtils.ArgumentNotNull(container, "container");
+
+      _token = container;
+      _parent = container;
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JTokenWriter"/> class.
+    /// </summary>
+    public JTokenWriter()
+    {
+    }
+
+    /// <summary>
+    /// Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream.
+    /// </summary>
+    public override void Flush()
+    {
+    }
+
+    /// <summary>
+    /// Closes this stream and the underlying stream.
+    /// </summary>
+    public override void Close()
+    {
+      base.Close();
+    }
+
+    /// <summary>
+    /// Writes the beginning of a Json object.
+    /// </summary>
+    public override void WriteStartObject()
+    {
+      base.WriteStartObject();
+
+      AddParent(new JObject());
+    }
+
+    private void AddParent(JContainer container)
+    {
+      if (_parent == null)
+        _token = container;
+      else
+        _parent.Add(container);
+
+      _parent = container;
+    }
+
+    private void RemoveParent()
+    {
+      _parent = _parent.Parent;
+
+      if (_parent != null && _parent.Type == JTokenType.Property)
+        _parent = _parent.Parent;
+    }
+
+    /// <summary>
+    /// Writes the beginning of a Json array.
+    /// </summary>
+    public override void WriteStartArray()
+    {
+      base.WriteStartArray();
+
+      AddParent(new JArray());
+    }
+
+    /// <summary>
+    /// Writes the start of a constructor with the given name.
+    /// </summary>
+    /// <param name="name">The name of the constructor.</param>
+    public override void WriteStartConstructor(string name)
+    {
+      base.WriteStartConstructor(name);
+
+      AddParent(new JConstructor(name));
+    }
+
+    /// <summary>
+    /// Writes the end.
+    /// </summary>
+    /// <param name="token">The token.</param>
+    protected override void WriteEnd(JsonToken token)
+    {
+      RemoveParent();
+    }
+
+    /// <summary>
+    /// Writes the property name of a name/value pair on a Json object.
+    /// </summary>
+    /// <param name="name">The name of the property.</param>
+    public override void WritePropertyName(string name)
+    {
+      base.WritePropertyName(name);
+
+      AddParent(new JProperty(name));
+    }
+
+    private void AddValue(object value, JsonToken token)
+    {
+      AddValue(new JValue(value), token);
+    }
+
+    internal void AddValue(JValue value, JsonToken token)
+    {
+      if (_parent != null)
+      {
+        _parent.Add(value);
+
+        if (_parent.Type == JTokenType.Property)
+          _parent = _parent.Parent;
+      }
+      else
+      {
+        _value = value;
+      }
+    }
+
+    #region WriteValue methods
+    /// <summary>
+    /// Writes a null value.
+    /// </summary>
+    public override void WriteNull()
+    {
+      base.WriteNull();
+      AddValue(null, JsonToken.Null);
+    }
+
+    /// <summary>
+    /// Writes an undefined value.
+    /// </summary>
+    public override void WriteUndefined()
+    {
+      base.WriteUndefined();
+      AddValue(null, JsonToken.Undefined);
+    }
+
+    /// <summary>
+    /// Writes raw JSON.
+    /// </summary>
+    /// <param name="json">The raw JSON to write.</param>
+    public override void WriteRaw(string json)
+    {
+      base.WriteRaw(json);
+      AddValue(new JRaw(json), JsonToken.Raw);
+    }
+
+    /// <summary>
+    /// Writes out a comment <code>/*...*/</code> containing the specified text.
+    /// </summary>
+    /// <param name="text">Text to place inside the comment.</param>
+    public override void WriteComment(string text)
+    {
+      base.WriteComment(text);
+      AddValue(JValue.CreateComment(text), JsonToken.Comment);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="String"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="String"/> value to write.</param>
+    public override void WriteValue(string value)
+    {
+      base.WriteValue(value);
+      AddValue(value ?? string.Empty, JsonToken.String);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Int32"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Int32"/> value to write.</param>
+    public override void WriteValue(int value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="UInt32"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="UInt32"/> value to write.</param>
+    [CLSCompliant(false)]
+    public override void WriteValue(uint value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Int64"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Int64"/> value to write.</param>
+    public override void WriteValue(long value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="UInt64"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="UInt64"/> value to write.</param>
+    [CLSCompliant(false)]
+    public override void WriteValue(ulong value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Single"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Single"/> value to write.</param>
+    public override void WriteValue(float value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.Float);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Double"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Double"/> value to write.</param>
+    public override void WriteValue(double value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.Float);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Boolean"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Boolean"/> value to write.</param>
+    public override void WriteValue(bool value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.Boolean);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Int16"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Int16"/> value to write.</param>
+    public override void WriteValue(short value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="UInt16"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="UInt16"/> value to write.</param>
+    [CLSCompliant(false)]
+    public override void WriteValue(ushort value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Char"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Char"/> value to write.</param>
+    public override void WriteValue(char value)
+    {
+      base.WriteValue(value);
+      AddValue(value.ToString(), JsonToken.String);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Byte"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Byte"/> value to write.</param>
+    public override void WriteValue(byte value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="SByte"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="SByte"/> value to write.</param>
+    [CLSCompliant(false)]
+    public override void WriteValue(sbyte value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.Integer);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="Decimal"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="Decimal"/> value to write.</param>
+    public override void WriteValue(decimal value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.Float);
+    }
+
+    /// <summary>
+    /// Writes a <see cref="DateTime"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="DateTime"/> value to write.</param>
+    public override void WriteValue(DateTime value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.Date);
+    }
+
+#if !PocketPC && !NET20
+    /// <summary>
+    /// Writes a <see cref="DateTimeOffset"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="DateTimeOffset"/> value to write.</param>
+    public override void WriteValue(DateTimeOffset value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.Date);
+    }
+#endif
+
+    /// <summary>
+    /// Writes a <see cref="T:Byte[]"/> value.
+    /// </summary>
+    /// <param name="value">The <see cref="T:Byte[]"/> value to write.</param>
+    public override void WriteValue(byte[] value)
+    {
+      base.WriteValue(value);
+      AddValue(value, JsonToken.Bytes);
+    }
+    #endregion
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JValue.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Linq/JValue.cs
new file mode 100644 (file)
index 0000000..a1b4681
--- /dev/null
@@ -0,0 +1,738 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Utilities;
+using System.Globalization;
+using System.ComponentModel;
+#if !(NET35 || NET20 || WINDOWS_PHONE)
+using System.Dynamic;
+using System.Linq.Expressions;
+#endif
+
+namespace Newtonsoft.Json.Linq
+{
+  /// <summary>
+  /// Represents a value in JSON (string, integer, date, etc).
+  /// </summary>
+  public class JValue : JToken, IEquatable<JValue>, IFormattable, IComparable, IComparable<JValue>
+  {
+    private JTokenType _valueType;
+    private object _value;
+
+    internal JValue(object value, JTokenType type)
+    {
+      _value = value;
+      _valueType = type;
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JValue"/> class from another <see cref="JValue"/> object.
+    /// </summary>
+    /// <param name="other">A <see cref="JValue"/> object to copy from.</param>
+    public JValue(JValue other)
+      : this(other.Value, other.Type)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JValue"/> class with the given value.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    public JValue(long value)
+      : this(value, JTokenType.Integer)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JValue"/> class with the given value.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    [CLSCompliant(false)]
+    public JValue(ulong value)
+      : this(value, JTokenType.Integer)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JValue"/> class with the given value.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    public JValue(double value)
+      : this(value, JTokenType.Float)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JValue"/> class with the given value.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    public JValue(DateTime value)
+      : this(value, JTokenType.Date)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JValue"/> class with the given value.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    public JValue(bool value)
+      : this(value, JTokenType.Boolean)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JValue"/> class with the given value.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    public JValue(string value)
+      : this(value, JTokenType.String)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JValue"/> class with the given value.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    public JValue(object value)
+      : this(value, GetValueType(null, value))
+    {
+    }
+
+    internal override bool DeepEquals(JToken node)
+    {
+      JValue other = node as JValue;
+      if (other == null)
+        return false;
+
+      return ValuesEquals(this, other);
+    }
+
+    /// <summary>
+    /// Gets a value indicating whether this token has childen tokens.
+    /// </summary>
+    /// <value>
+    ///        <c>true</c> if this token has child values; otherwise, <c>false</c>.
+    /// </value>
+    public override bool HasValues
+    {
+      get { return false; }
+    }
+
+    private static int Compare(JTokenType valueType, object objA, object objB)
+    {
+      if (objA == null && objB == null)
+        return 0;
+      if (objA != null && objB == null)
+        return 1;
+      if (objA == null && objB != null)
+        return -1;
+
+      switch (valueType)
+      {
+        case JTokenType.Integer:
+          if (objA is ulong || objB is ulong || objA is decimal || objB is decimal)
+            return Convert.ToDecimal(objA, CultureInfo.InvariantCulture).CompareTo(Convert.ToDecimal(objB, CultureInfo.InvariantCulture));
+          else if (objA is float || objB is float || objA is double || objB is double)
+            return CompareFloat(objA, objB);
+          else
+            return Convert.ToInt64(objA, CultureInfo.InvariantCulture).CompareTo(Convert.ToInt64(objB, CultureInfo.InvariantCulture));
+        case JTokenType.Float:
+          return CompareFloat(objA, objB);
+        case JTokenType.Comment:
+        case JTokenType.String:
+        case JTokenType.Raw:
+          string s1 = Convert.ToString(objA, CultureInfo.InvariantCulture);
+          string s2 = Convert.ToString(objB, CultureInfo.InvariantCulture);
+
+          return s1.CompareTo(s2);
+        case JTokenType.Boolean:
+          bool b1 = Convert.ToBoolean(objA, CultureInfo.InvariantCulture);
+          bool b2 = Convert.ToBoolean(objB, CultureInfo.InvariantCulture);
+
+          return b1.CompareTo(b2);
+        case JTokenType.Date:
+#if !NET20
+          if (objA is DateTime)
+          {
+#endif
+            DateTime date1 = Convert.ToDateTime(objA, CultureInfo.InvariantCulture);
+            DateTime date2 = Convert.ToDateTime(objB, CultureInfo.InvariantCulture);
+
+            return date1.CompareTo(date2);
+#if !NET20
+          }
+          else
+          {
+            if (!(objB is DateTimeOffset))
+              throw new ArgumentException("Object must be of type DateTimeOffset.");
+
+            DateTimeOffset date1 = (DateTimeOffset)objA;
+            DateTimeOffset date2 = (DateTimeOffset)objB;
+
+            return date1.CompareTo(date2);
+          }
+#endif
+        case JTokenType.Bytes:
+          if (!(objB is byte[]))
+              throw new ArgumentException("Object must be of type byte[].");
+
+          byte[] bytes1 = objA as byte[];
+          byte[] bytes2 = objB as byte[];
+          if (bytes1 == null)
+            return -1;
+          if (bytes2 == null)
+            return 1;
+
+          return MiscellaneousUtils.ByteArrayCompare(bytes1, bytes2);
+        default:
+          throw MiscellaneousUtils.CreateArgumentOutOfRangeException("valueType", valueType, "Unexpected value type: {0}".FormatWith(CultureInfo.InvariantCulture, valueType));
+      }
+    }
+
+    private static int CompareFloat(object objA, object objB)
+    {
+      double d1 = Convert.ToDouble(objA, CultureInfo.InvariantCulture);
+      double d2 = Convert.ToDouble(objB, CultureInfo.InvariantCulture);
+
+      // take into account possible floating point errors
+      if (MathUtils.ApproxEquals(d1, d2))
+        return 0;
+
+      return d1.CompareTo(d2);
+    }
+
+#if !(NET35 || NET20 || WINDOWS_PHONE)
+    private static bool Operation(ExpressionType operation, object objA, object objB, out object result)
+    {
+      if (objA is string || objB is string)
+      {
+        if (operation == ExpressionType.Add || operation == ExpressionType.AddAssign)
+        {
+          result = ((objA != null) ? objA.ToString() : null) + ((objB != null) ? objB.ToString() : null);
+          return true;
+        }
+      }
+
+      if (objA is ulong || objB is ulong || objA is decimal || objB is decimal)
+      {
+        if (objA == null || objB == null)
+        {
+          result = null;
+          return true;
+        }
+
+        decimal d1 = Convert.ToDecimal(objA, CultureInfo.InvariantCulture);
+        decimal d2 = Convert.ToDecimal(objB, CultureInfo.InvariantCulture);
+
+        switch (operation)
+        {
+          case ExpressionType.Add:
+          case ExpressionType.AddAssign:
+            result = d1 + d2;
+            return true;
+          case ExpressionType.Subtract:
+          case ExpressionType.SubtractAssign:
+            result = d1 - d2;
+            return true;
+          case ExpressionType.Multiply:
+          case ExpressionType.MultiplyAssign:
+            result = d1 * d2;
+            return true;
+          case ExpressionType.Divide:
+          case ExpressionType.DivideAssign:
+            result = d1 / d2;
+            return true;
+        }
+      }
+      else if (objA is float || objB is float || objA is double || objB is double)
+      {
+        if (objA == null || objB == null)
+        {
+          result = null;
+          return true;
+        }
+
+        double d1 = Convert.ToDouble(objA, CultureInfo.InvariantCulture);
+        double d2 = Convert.ToDouble(objB, CultureInfo.InvariantCulture);
+
+        switch (operation)
+        {
+          case ExpressionType.Add:
+          case ExpressionType.AddAssign:
+            result = d1 + d2;
+            return true;
+          case ExpressionType.Subtract:
+          case ExpressionType.SubtractAssign:
+            result = d1 - d2;
+            return true;
+          case ExpressionType.Multiply:
+          case ExpressionType.MultiplyAssign:
+            result = d1 * d2;
+            return true;
+          case ExpressionType.Divide:
+          case ExpressionType.DivideAssign:
+            result = d1 / d2;
+            return true;
+        }
+      }
+      else if (objA is int || objA is uint || objA is long || objA is short || objA is ushort || objA is sbyte || objA is byte ||
+        objB is int || objB is uint || objB is long || objB is short || objB is ushort || objB is sbyte || objB is byte)
+      {
+        if (objA == null || objB == null)
+        {
+          result = null;
+          return true;
+        }
+
+        long l1 = Convert.ToInt64(objA, CultureInfo.InvariantCulture);
+        long l2 = Convert.ToInt64(objB, CultureInfo.InvariantCulture);
+
+        switch (operation)
+        {
+          case ExpressionType.Add:
+          case ExpressionType.AddAssign:
+            result = l1 + l2;
+            return true;
+          case ExpressionType.Subtract:
+          case ExpressionType.SubtractAssign:
+            result = l1 - l2;
+            return true;
+          case ExpressionType.Multiply:
+          case ExpressionType.MultiplyAssign:
+            result = l1 * l2;
+            return true;
+          case ExpressionType.Divide:
+          case ExpressionType.DivideAssign:
+            result = l1 / l2;
+            return true;
+        }
+      }
+
+      result = null;
+      return false;
+    }
+#endif
+
+    internal override JToken CloneToken()
+    {
+      return new JValue(this);
+    }
+
+    /// <summary>
+    /// Creates a <see cref="JValue"/> comment with the given value.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>A <see cref="JValue"/> comment with the given value.</returns>
+    public static JValue CreateComment(string value)
+    {
+      return new JValue(value, JTokenType.Comment);
+    }
+
+    /// <summary>
+    /// Creates a <see cref="JValue"/> string with the given value.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <returns>A <see cref="JValue"/> string with the given value.</returns>
+    public static JValue CreateString(string value)
+    {
+      return new JValue(value, JTokenType.String);
+    }
+
+    private static JTokenType GetValueType(JTokenType? current, object value)
+    {
+      if (value == null)
+        return JTokenType.Null;
+      else if (value == DBNull.Value)
+        return JTokenType.Null;
+      else if (value is string)
+        return GetStringValueType(current);
+      else if (value is long || value is int || value is short || value is sbyte
+        || value is ulong || value is uint || value is ushort || value is byte)
+        return JTokenType.Integer;
+      else if (value is Enum)
+        return JTokenType.Integer;
+      else if (value is double || value is float || value is decimal)
+        return JTokenType.Float;
+      else if (value is DateTime)
+        return JTokenType.Date;
+#if !PocketPC && !NET20
+      else if (value is DateTimeOffset)
+        return JTokenType.Date;
+#endif
+      else if (value is byte[])
+        return JTokenType.Bytes;
+      else if (value is bool)
+        return JTokenType.Boolean;
+
+      throw new ArgumentException("Could not determine JSON object type for type {0}.".FormatWith(CultureInfo.InvariantCulture, value.GetType()));
+    }
+
+    private static JTokenType GetStringValueType(JTokenType? current)
+    {
+      if (current == null)
+        return JTokenType.String;
+
+      switch (current.Value)
+      {
+        case JTokenType.Comment:
+        case JTokenType.String:
+        case JTokenType.Raw:
+          return current.Value;
+        default:
+          return JTokenType.String;
+      }
+    }
+
+    /// <summary>
+    /// Gets the node type for this <see cref="JToken"/>.
+    /// </summary>
+    /// <value>The type.</value>
+    public override JTokenType Type
+    {
+      get { return _valueType; }
+    }
+
+    /// <summary>
+    /// Gets or sets the underlying token value.
+    /// </summary>
+    /// <value>The underlying token value.</value>
+    public object Value
+    {
+      get { return _value; }
+      set
+      {
+        Type currentType = (_value != null) ? _value.GetType() : null;
+        Type newType = (value != null) ? value.GetType() : null;
+
+        if (currentType != newType)
+          _valueType = GetValueType(_valueType, value);
+
+        _value = value;
+      }
+    }
+
+    /// <summary>
+    /// Writes this token to a <see cref="JsonWriter"/>.
+    /// </summary>
+    /// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param>
+    /// <param name="converters">A collection of <see cref="JsonConverter"/> which will be used when writing the token.</param>
+    public override void WriteTo(JsonWriter writer, params JsonConverter[] converters)
+    {
+      switch (_valueType)
+      {
+        case JTokenType.Comment:
+          writer.WriteComment(_value.ToString());
+          return;
+        case JTokenType.Raw:
+          writer.WriteRawValue((_value != null) ? _value.ToString() : null);
+          return;
+        case JTokenType.Null:
+          writer.WriteNull();
+          return;
+        case JTokenType.Undefined:
+          writer.WriteUndefined();
+          return;
+      }
+
+      JsonConverter matchingConverter;
+      if (_value != null && ((matchingConverter = JsonSerializer.GetMatchingConverter(converters, _value.GetType())) != null))
+      {
+        matchingConverter.WriteJson(writer, _value, new JsonSerializer());
+        return;
+      }
+
+      switch (_valueType)
+      {
+        case JTokenType.Integer:
+          writer.WriteValue(Convert.ToInt64(_value, CultureInfo.InvariantCulture));
+          return;
+        case JTokenType.Float:
+          writer.WriteValue(Convert.ToDouble(_value, CultureInfo.InvariantCulture));
+          return;
+        case JTokenType.String:
+          writer.WriteValue((_value != null) ? _value.ToString() : null);
+          return;
+        case JTokenType.Boolean:
+          writer.WriteValue(Convert.ToBoolean(_value, CultureInfo.InvariantCulture));
+          return;
+        case JTokenType.Date:
+#if !PocketPC && !NET20
+          if (_value is DateTimeOffset)
+            writer.WriteValue((DateTimeOffset)_value);
+          else
+#endif
+            writer.WriteValue(Convert.ToDateTime(_value, CultureInfo.InvariantCulture)); ;
+          return;
+        case JTokenType.Bytes:
+          writer.WriteValue((byte[])_value);
+          return;
+      }
+
+      throw MiscellaneousUtils.CreateArgumentOutOfRangeException("TokenType", _valueType, "Unexpected token type.");
+    }
+
+    internal override int GetDeepHashCode()
+    {
+      int valueHashCode = (_value != null) ? _value.GetHashCode() : 0;
+
+      return _valueType.GetHashCode() ^ valueHashCode;
+    }
+
+    private static bool ValuesEquals(JValue v1, JValue v2)
+    {
+      return (v1 == v2 || (v1._valueType == v2._valueType && Compare(v1._valueType, v1._value, v2._value) == 0));
+    }
+
+    /// <summary>
+    /// Indicates whether the current object is equal to another object of the same type.
+    /// </summary>
+    /// <returns>
+    /// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.
+    /// </returns>
+    /// <param name="other">An object to compare with this object.</param>
+    public bool Equals(JValue other)
+    {
+      if (other == null)
+        return false;
+
+      return ValuesEquals(this, other);
+    }
+
+    /// <summary>
+    /// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>.
+    /// </summary>
+    /// <param name="obj">The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>.</param>
+    /// <returns>
+    /// true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false.
+    /// </returns>
+    /// <exception cref="T:System.NullReferenceException">
+    /// The <paramref name="obj"/> parameter is null.
+    /// </exception>
+    public override bool Equals(object obj)
+    {
+      if (obj == null)
+        return false;
+
+      JValue otherValue = obj as JValue;
+      if (otherValue != null)
+        return Equals(otherValue);
+
+      return base.Equals(obj);
+    }
+
+    /// <summary>
+    /// Serves as a hash function for a particular type.
+    /// </summary>
+    /// <returns>
+    /// A hash code for the current <see cref="T:System.Object"/>.
+    /// </returns>
+    public override int GetHashCode()
+    {
+      if (_value == null)
+        return 0;
+
+      return _value.GetHashCode();
+    }
+
+    /// <summary>
+    /// Returns a <see cref="System.String"/> that represents this instance.
+    /// </summary>
+    /// <returns>
+    /// A <see cref="System.String"/> that represents this instance.
+    /// </returns>
+    public override string ToString()
+    {
+      if (_value == null)
+        return string.Empty;
+
+      return _value.ToString();
+    }
+
+    /// <summary>
+    /// Returns a <see cref="System.String"/> that represents this instance.
+    /// </summary>
+    /// <param name="format">The format.</param>
+    /// <returns>
+    /// A <see cref="System.String"/> that represents this instance.
+    /// </returns>
+    public string ToString(string format)
+    {
+      return ToString(format, CultureInfo.CurrentCulture);
+    }
+
+    /// <summary>
+    /// Returns a <see cref="System.String"/> that represents this instance.
+    /// </summary>
+    /// <param name="formatProvider">The format provider.</param>
+    /// <returns>
+    /// A <see cref="System.String"/> that represents this instance.
+    /// </returns>
+    public string ToString(IFormatProvider formatProvider)
+    {
+      return ToString(null, formatProvider);
+    }
+
+    /// <summary>
+    /// Returns a <see cref="System.String"/> that represents this instance.
+    /// </summary>
+    /// <param name="format">The format.</param>
+    /// <param name="formatProvider">The format provider.</param>
+    /// <returns>
+    /// A <see cref="System.String"/> that represents this instance.
+    /// </returns>
+    public string ToString(string format, IFormatProvider formatProvider)
+    {
+      if (_value == null)
+        return string.Empty;
+
+      IFormattable formattable = _value as IFormattable;
+      if (formattable != null)
+        return formattable.ToString(format, formatProvider);
+      else
+        return _value.ToString();
+    }
+
+#if !(NET35 || NET20 || WINDOWS_PHONE)
+    /// <summary>
+    /// Returns the <see cref="T:System.Dynamic.DynamicMetaObject"/> responsible for binding operations performed on this object.
+    /// </summary>
+    /// <param name="parameter">The expression tree representation of the runtime value.</param>
+    /// <returns>
+    /// The <see cref="T:System.Dynamic.DynamicMetaObject"/> to bind this object.
+    /// </returns>
+    protected override DynamicMetaObject GetMetaObject(Expression parameter)
+    {
+      return new DynamicProxyMetaObject<JValue>(parameter, this, new JValueDynamicProxy(), true);
+    }
+
+    private class JValueDynamicProxy : DynamicProxy<JValue>
+    {
+      public override bool TryConvert(JValue instance, ConvertBinder binder, out object result)
+      {
+        if (binder.Type == typeof(JValue))
+        {
+          result = instance;
+          return true;
+        }
+
+        object value = instance.Value;
+
+        if (value == null)
+        {
+          result = null;
+          return ReflectionUtils.IsNullable(binder.Type);
+        }
+
+        result = ConvertUtils.Convert(instance.Value, CultureInfo.InvariantCulture, binder.Type);
+        return true;
+      }
+
+      public override bool TryBinaryOperation(JValue instance, BinaryOperationBinder binder, object arg, out object result)
+      {
+        object compareValue = (arg is JValue) ? ((JValue) arg).Value : arg;
+
+        switch (binder.Operation)
+        {
+          case ExpressionType.Equal:
+            result = (Compare(instance.Type, instance.Value, compareValue) == 0);
+            return true;
+          case ExpressionType.NotEqual:
+            result = (Compare(instance.Type, instance.Value, compareValue) != 0);
+            return true;
+          case ExpressionType.GreaterThan:
+            result = (Compare(instance.Type, instance.Value, compareValue) > 0);
+            return true;
+          case ExpressionType.GreaterThanOrEqual:
+            result = (Compare(instance.Type, instance.Value, compareValue) >= 0);
+            return true;
+          case ExpressionType.LessThan:
+            result = (Compare(instance.Type, instance.Value, compareValue) < 0);
+            return true;
+          case ExpressionType.LessThanOrEqual:
+            result = (Compare(instance.Type, instance.Value, compareValue) <= 0);
+            return true;
+          case ExpressionType.Add:
+          case ExpressionType.AddAssign:
+          case ExpressionType.Subtract:
+          case ExpressionType.SubtractAssign:
+          case ExpressionType.Multiply:
+          case ExpressionType.MultiplyAssign:
+          case ExpressionType.Divide:
+          case ExpressionType.DivideAssign:
+            if (Operation(binder.Operation, instance.Value, compareValue, out result))
+            {
+              result = new JValue(result);
+              return true;
+            }
+            break;
+        }
+
+        result = null;
+        return false;
+      }
+    }
+#endif
+
+    int IComparable.CompareTo(object obj)
+    {
+      if (obj == null)
+        return 1;
+
+      object otherValue = (obj is JValue) ? ((JValue) obj).Value : obj;
+
+      return Compare(_valueType, _value, otherValue);
+    }
+
+    /// <summary>
+    /// Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance precedes, follows, or occurs in the same position in the sort order as the other object.
+    /// </summary>
+    /// <param name="obj">An object to compare with this instance.</param>
+    /// <returns>
+    /// A 32-bit signed integer that indicates the relative order of the objects being compared. The return value has these meanings:
+    /// Value
+    /// Meaning
+    /// Less than zero
+    /// This instance is less than <paramref name="obj"/>.
+    /// Zero
+    /// This instance is equal to <paramref name="obj"/>.
+    /// Greater than zero
+    /// This instance is greater than <paramref name="obj"/>.
+    /// </returns>
+    /// <exception cref="T:System.ArgumentException">
+    ///        <paramref name="obj"/> is not the same type as this instance.
+    /// </exception>
+    public int CompareTo(JValue obj)
+    {
+      if (obj == null)
+        return 1;
+
+      return Compare(_valueType, _value, obj._value);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/MemberSerialization.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/MemberSerialization.cs
new file mode 100644 (file)
index 0000000..00aeb2c
--- /dev/null
@@ -0,0 +1,47 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Specifies the member serialization options for the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public enum MemberSerialization
+  {
+    /// <summary>
+    /// All members are serialized by default. Members can be excluded using the <see cref="JsonIgnoreAttribute"/>.
+    /// </summary>
+    OptOut,
+    /// <summary>
+    /// Only members must be marked with the <see cref="JsonPropertyAttribute"/> are serialized.
+    /// </summary>
+    OptIn
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/MissingMemberHandling.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/MissingMemberHandling.cs
new file mode 100644 (file)
index 0000000..d61e1e6
--- /dev/null
@@ -0,0 +1,46 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Specifies missing member handling options for the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public enum MissingMemberHandling
+  {
+    /// <summary>
+    /// Ignore a missing member and do not attempt to deserialize it.
+    /// </summary>
+    Ignore = 0,
+    /// <summary>
+    /// Throw a <see cref="JsonSerializationException"/> when a missing member is encountered during deserialization.
+    /// </summary>
+    Error = 1
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj
new file mode 100644 (file)
index 0000000..fd6fb43
--- /dev/null
@@ -0,0 +1,252 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Newtonsoft.Json</RootNamespace>
+    <AssemblyName>Newtonsoft.Json.Net20</AssemblyName>
+    <SignAssembly>false</SignAssembly>
+    <AssemblyOriginatorKeyFile>
+    </AssemblyOriginatorKeyFile>
+    <SccProjectName>
+    </SccProjectName>
+    <SccLocalPath>
+    </SccLocalPath>
+    <SccAuxPath>
+    </SccAuxPath>
+    <SccProvider>
+    </SccProvider>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\Net20\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;NET20</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>bin\Debug\Net20\Newtonsoft.Json.Net20.xml</DocumentationFile>
+    <RunCodeAnalysis>true</RunCodeAnalysis>
+    <CodeAnalysisRules>
+    </CodeAnalysisRules>
+    <CodeAnalysisRuleSet>Newtonsoft.Json.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\Net20\</OutputPath>
+    <DefineConstants>TRACE;NET20</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>bin\Release\Net20\Newtonsoft.Json.Net20.xml</DocumentationFile>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="LinqBridge, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c2b14eb747628076, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\Lib\LinqBridge.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Bson\BsonBinaryType.cs" />
+    <Compile Include="Bson\BsonBinaryWriter.cs" />
+    <Compile Include="Bson\BsonObjectId.cs" />
+    <Compile Include="Bson\BsonReader.cs" />
+    <Compile Include="Bson\BsonToken.cs" />
+    <Compile Include="Bson\BsonType.cs" />
+    <Compile Include="Bson\BsonWriter.cs" />
+    <Compile Include="ConstructorHandling.cs" />
+    <Compile Include="Converters\BinaryConverter.cs" />
+    <Compile Include="Converters\BsonObjectIdConverter.cs" />
+    <Compile Include="Converters\CustomCreationConverter.cs" />
+    <Compile Include="Converters\DataSetConverter.cs" />
+    <Compile Include="Converters\DataTableConverter.cs" />
+    <Compile Include="Converters\DateTimeConverterBase.cs" />
+    <Compile Include="Converters\EntityKeyMemberConverter.cs" />
+    <Compile Include="Converters\KeyValuePairConverter.cs" />
+    <Compile Include="Converters\RegexConverter.cs" />
+    <Compile Include="Converters\StringEnumConverter.cs" />
+    <Compile Include="JsonConstructorAttribute.cs" />
+    <Compile Include="Linq\ComponentModel\JPropertyDescriptor.cs" />
+    <Compile Include="Linq\JPath.cs" />
+    <Compile Include="Linq\JRaw.cs" />
+    <Compile Include="Required.cs" />
+    <Compile Include="Serialization\DefaultReferenceResolver.cs" />
+    <Compile Include="PreserveReferencesHandling.cs" />
+    <Compile Include="IJsonLineInfo.cs" />
+    <Compile Include="JsonArrayAttribute.cs" />
+    <Compile Include="JsonContainerAttribute.cs" />
+    <Compile Include="DefaultValueHandling.cs" />
+    <Compile Include="JsonConverterAttribute.cs" />
+    <Compile Include="JsonObjectAttribute.cs" />
+    <Compile Include="JsonSerializerSettings.cs" />
+    <Compile Include="JsonValidatingReader.cs" />
+    <Compile Include="Linq\IJEnumerable.cs" />
+    <Compile Include="Linq\JTokenEqualityComparer.cs" />
+    <Compile Include="MemberSerialization.cs" />
+    <Compile Include="ObjectCreationHandling.cs" />
+    <Compile Include="Converters\IsoDateTimeConverter.cs" />
+    <Compile Include="Converters\JavaScriptDateTimeConverter.cs" />
+    <Compile Include="Converters\JsonDateTimeSerializationMode.cs" />
+    <Compile Include="Converters\XmlNodeConverter.cs" />
+    <Compile Include="JsonTextReader.cs" />
+    <Compile Include="JsonPropertyAttribute.cs" />
+    <Compile Include="JsonIgnoreAttribute.cs" />
+    <Compile Include="JsonTextWriter.cs" />
+    <Compile Include="JsonWriterException.cs" />
+    <Compile Include="JsonReaderException.cs" />
+    <Compile Include="JsonConverter.cs" />
+    <Compile Include="JsonConverterCollection.cs" />
+    <Compile Include="JsonReader.cs" />
+    <Compile Include="JsonConvert.cs" />
+    <Compile Include="JsonSerializationException.cs" />
+    <Compile Include="JsonSerializer.cs" />
+    <Compile Include="Linq\Extensions.cs" />
+    <Compile Include="Linq\JConstructor.cs" />
+    <Compile Include="Linq\JContainer.cs" />
+    <Compile Include="Linq\JEnumerable.cs" />
+    <Compile Include="Linq\JObject.cs" />
+    <Compile Include="Linq\JArray.cs" />
+    <Compile Include="Linq\JTokenReader.cs" />
+    <Compile Include="Linq\JTokenWriter.cs" />
+    <Compile Include="Linq\JToken.cs" />
+    <Compile Include="Linq\JProperty.cs" />
+    <Compile Include="Linq\JTokenType.cs" />
+    <Compile Include="Linq\JValue.cs" />
+    <Compile Include="Schema\Extensions.cs" />
+    <Compile Include="Schema\JsonSchemaException.cs" />
+    <Compile Include="Schema\JsonSchemaModel.cs" />
+    <Compile Include="Schema\JsonSchemaModelBuilder.cs" />
+    <Compile Include="Schema\JsonSchemaNodeCollection.cs" />
+    <Compile Include="Schema\JsonSchemaNode.cs" />
+    <Compile Include="Schema\JsonSchemaResolver.cs" />
+    <Compile Include="Schema\JsonSchemaWriter.cs" />
+    <Compile Include="Schema\UndefinedSchemaIdHandling.cs" />
+    <Compile Include="Schema\ValidationEventArgs.cs" />
+    <Compile Include="Schema\ValidationEventHandler.cs" />
+    <Compile Include="Serialization\CamelCasePropertyNamesContractResolver.cs" />
+    <Compile Include="Serialization\DefaultContractResolver.cs" />
+    <Compile Include="Serialization\DefaultSerializationBinder.cs" />
+    <Compile Include="Serialization\DynamicValueProvider.cs" />
+    <Compile Include="Serialization\ErrorContext.cs" />
+    <Compile Include="Serialization\ErrorEventArgs.cs" />
+    <Compile Include="Serialization\IContractResolver.cs" />
+    <Compile Include="Serialization\IValueProvider.cs" />
+    <Compile Include="Serialization\JsonArrayContract.cs" />
+    <Compile Include="Serialization\JsonContract.cs" />
+    <Compile Include="Serialization\JsonDictionaryContract.cs" />
+    <Compile Include="Serialization\JsonFormatterConverter.cs" />
+    <Compile Include="Serialization\JsonISerializableContract.cs" />
+    <Compile Include="Serialization\JsonLinqContract.cs" />
+    <Compile Include="Serialization\JsonPrimitiveContract.cs" />
+    <Compile Include="Serialization\JsonProperty.cs" />
+    <Compile Include="Serialization\JsonPropertyCollection.cs" />
+    <Compile Include="MissingMemberHandling.cs" />
+    <Compile Include="NullValueHandling.cs" />
+    <Compile Include="ReferenceLoopHandling.cs" />
+    <Compile Include="Schema\JsonSchema.cs" />
+    <Compile Include="Schema\JsonSchemaBuilder.cs" />
+    <Compile Include="Schema\JsonSchemaConstants.cs" />
+    <Compile Include="Schema\JsonSchemaGenerator.cs" />
+    <Compile Include="Serialization\IReferenceResolver.cs" />
+    <Compile Include="Schema\JsonSchemaType.cs" />
+    <Compile Include="Serialization\JsonObjectContract.cs" />
+    <Compile Include="Serialization\JsonSerializerInternalBase.cs" />
+    <Compile Include="Serialization\JsonSerializerInternalReader.cs" />
+    <Compile Include="Serialization\JsonSerializerInternalWriter.cs" />
+    <Compile Include="Serialization\JsonSerializerProxy.cs" />
+    <Compile Include="Serialization\JsonStringContract.cs" />
+    <Compile Include="Serialization\JsonTypeReflector.cs" />
+    <Compile Include="Serialization\CachedAttributeGetter.cs" />
+    <Compile Include="Serialization\LateBoundMetadataTypeAttribute.cs" />
+    <Compile Include="Serialization\ObjectConstructor.cs" />
+    <Compile Include="Serialization\OnErrorAttribute.cs" />
+    <Compile Include="Serialization\ReflectionValueProvider.cs" />
+    <Compile Include="Utilities\Base64Encoder.cs" />
+    <Compile Include="Utilities\DynamicReflectionDelegateFactory.cs" />
+    <Compile Include="Utilities\DynamicWrapper.cs" />
+    <Compile Include="Utilities\ILGeneratorExtensions.cs" />
+    <Compile Include="Utilities\LateBoundReflectionDelegateFactory.cs" />
+    <Compile Include="Utilities\MethodCall.cs" />
+    <Compile Include="Utilities\ReflectionDelegateFactory.cs" />
+    <Compile Include="Utilities\ThreadSafeStore.cs" />
+    <Compile Include="TypeNameHandling.cs" />
+    <Compile Include="Utilities\BidirectionalDictionary.cs" />
+    <Compile Include="Utilities\ConvertUtils.cs" />
+    <Compile Include="Utilities\CollectionWrapper.cs" />
+    <Compile Include="Utilities\DateTimeUtils.cs" />
+    <Compile Include="Utilities\DictionaryWrapper.cs" />
+    <Compile Include="Utilities\EnumUtils.cs" />
+    <Compile Include="Utilities\EnumValue.cs" />
+    <Compile Include="Utilities\EnumValues.cs" />
+    <Compile Include="Utilities\JavaScriptUtils.cs" />
+    <Compile Include="JsonToken.cs" />
+    <Compile Include="JsonWriter.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Utilities\StringBuffer.cs" />
+    <Compile Include="Utilities\CollectionUtils.cs" />
+    <Compile Include="Utilities\ListWrapper.cs" />
+    <Compile Include="Utilities\MathUtils.cs" />
+    <Compile Include="Utilities\MiscellaneousUtils.cs" />
+    <Compile Include="Utilities\ReflectionUtils.cs" />
+    <Compile Include="Utilities\StringUtils.cs" />
+    <Compile Include="Utilities\ValidationUtils.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 2.0 %28x86%29</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.0 %28x86%29</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+</Project>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Newtonsoft.Json.Net35.csproj b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Newtonsoft.Json.Net35.csproj
new file mode 100644 (file)
index 0000000..b61ef8a
--- /dev/null
@@ -0,0 +1,267 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Newtonsoft.Json.Net35</RootNamespace>
+    <AssemblyName>Newtonsoft.Json.Net35</AssemblyName>
+    <SignAssembly>false</SignAssembly>
+    <AssemblyOriginatorKeyFile>
+    </AssemblyOriginatorKeyFile>
+    <SccProjectName>
+    </SccProjectName>
+    <SccLocalPath>
+    </SccLocalPath>
+    <SccAuxPath>
+    </SccAuxPath>
+    <SccProvider>
+    </SccProvider>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\Net35\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;CODE_ANALYSIS;NET35</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>bin\Debug\Net35\Newtonsoft.Json.Net35.xml</DocumentationFile>
+    <RunCodeAnalysis>true</RunCodeAnalysis>
+    <CodeAnalysisRules>
+    </CodeAnalysisRules>
+    <CodeAnalysisRuleSet>Newtonsoft.Json.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\Net35\</OutputPath>
+    <DefineConstants>TRACE;NET35</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>bin\Release\Net35\Newtonsoft.Json.Net35.xml</DocumentationFile>
+    <CodeAnalysisRuleSet>..\..\..\..\trunk\Src\Newtonsoft.Json\Newtonsoft.Json.ruleset</CodeAnalysisRuleSet>
+    <RunCodeAnalysis>false</RunCodeAnalysis>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Runtime.Serialization">
+      <RequiredTargetFramework>3.0</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Xml" />
+    <Reference Include="System.Xml.Linq">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Bson\BsonBinaryType.cs" />
+    <Compile Include="Bson\BsonBinaryWriter.cs" />
+    <Compile Include="Bson\BsonReader.cs" />
+    <Compile Include="Bson\BsonToken.cs" />
+    <Compile Include="Bson\BsonType.cs" />
+    <Compile Include="Bson\BsonWriter.cs" />
+    <Compile Include="Bson\BsonObjectId.cs" />
+    <Compile Include="Converters\BinaryConverter.cs" />
+    <Compile Include="Converters\DataSetConverter.cs" />
+    <Compile Include="Converters\DataTableConverter.cs" />
+    <Compile Include="Converters\CustomCreationConverter.cs" />
+    <Compile Include="Converters\DateTimeConverterBase.cs" />
+    <Compile Include="Converters\EntityKeyMemberConverter.cs" />
+    <Compile Include="Converters\ExpandoObjectConverter.cs" />
+    <Compile Include="Converters\KeyValuePairConverter.cs" />
+    <Compile Include="Converters\BsonObjectIdConverter.cs" />
+    <Compile Include="Converters\RegexConverter.cs" />
+    <Compile Include="Converters\StringEnumConverter.cs" />
+    <Compile Include="ConstructorHandling.cs" />
+    <Compile Include="JsonConstructorAttribute.cs" />
+    <Compile Include="Utilities\DynamicProxy.cs" />
+    <Compile Include="Linq\JPath.cs" />
+    <Compile Include="Linq\JRaw.cs" />
+    <Compile Include="Required.cs" />
+    <Compile Include="Serialization\JsonDynamicContract.cs" />
+    <Compile Include="Serialization\JsonFormatterConverter.cs" />
+    <Compile Include="Serialization\JsonISerializableContract.cs" />
+    <Compile Include="Serialization\JsonLinqContract.cs" />
+    <Compile Include="Serialization\JsonPrimitiveContract.cs" />
+    <Compile Include="Serialization\DynamicValueProvider.cs" />
+    <Compile Include="Serialization\ErrorEventArgs.cs" />
+    <Compile Include="Linq\ComponentModel\JPropertyDescriptor.cs" />
+    <Compile Include="Serialization\DefaultReferenceResolver.cs" />
+    <Compile Include="PreserveReferencesHandling.cs" />
+    <Compile Include="IJsonLineInfo.cs" />
+    <Compile Include="JsonArrayAttribute.cs" />
+    <Compile Include="JsonContainerAttribute.cs" />
+    <Compile Include="DefaultValueHandling.cs" />
+    <Compile Include="JsonConverterAttribute.cs" />
+    <Compile Include="JsonObjectAttribute.cs" />
+    <Compile Include="JsonSerializerSettings.cs" />
+    <Compile Include="JsonValidatingReader.cs" />
+    <Compile Include="Linq\IJEnumerable.cs" />
+    <Compile Include="Linq\JTokenEqualityComparer.cs" />
+    <Compile Include="MemberSerialization.cs" />
+    <Compile Include="ObjectCreationHandling.cs" />
+    <Compile Include="Converters\IsoDateTimeConverter.cs" />
+    <Compile Include="Converters\JavaScriptDateTimeConverter.cs" />
+    <Compile Include="Converters\JsonDateTimeSerializationMode.cs" />
+    <Compile Include="Converters\XmlNodeConverter.cs" />
+    <Compile Include="JsonTextReader.cs" />
+    <Compile Include="JsonPropertyAttribute.cs" />
+    <Compile Include="JsonIgnoreAttribute.cs" />
+    <Compile Include="JsonTextWriter.cs" />
+    <Compile Include="JsonWriterException.cs" />
+    <Compile Include="JsonReaderException.cs" />
+    <Compile Include="JsonConverter.cs" />
+    <Compile Include="JsonConverterCollection.cs" />
+    <Compile Include="JsonReader.cs" />
+    <Compile Include="JsonConvert.cs" />
+    <Compile Include="JsonSerializationException.cs" />
+    <Compile Include="JsonSerializer.cs" />
+    <Compile Include="Linq\Extensions.cs" />
+    <Compile Include="Linq\JConstructor.cs" />
+    <Compile Include="Linq\JContainer.cs" />
+    <Compile Include="Linq\JEnumerable.cs" />
+    <Compile Include="Linq\JObject.cs" />
+    <Compile Include="Linq\JArray.cs" />
+    <Compile Include="Linq\JTokenReader.cs" />
+    <Compile Include="Linq\JTokenWriter.cs" />
+    <Compile Include="Linq\JToken.cs" />
+    <Compile Include="Linq\JProperty.cs" />
+    <Compile Include="Linq\JTokenType.cs" />
+    <Compile Include="Linq\JValue.cs" />
+    <Compile Include="Schema\Extensions.cs" />
+    <Compile Include="Schema\JsonSchemaException.cs" />
+    <Compile Include="Schema\JsonSchemaModel.cs" />
+    <Compile Include="Schema\JsonSchemaModelBuilder.cs" />
+    <Compile Include="Schema\JsonSchemaNodeCollection.cs" />
+    <Compile Include="Schema\JsonSchemaNode.cs" />
+    <Compile Include="Schema\JsonSchemaResolver.cs" />
+    <Compile Include="Schema\JsonSchemaWriter.cs" />
+    <Compile Include="Schema\UndefinedSchemaIdHandling.cs" />
+    <Compile Include="Schema\ValidationEventArgs.cs" />
+    <Compile Include="Schema\ValidationEventHandler.cs" />
+    <Compile Include="Serialization\CamelCasePropertyNamesContractResolver.cs" />
+    <Compile Include="Serialization\DefaultContractResolver.cs" />
+    <Compile Include="Serialization\DefaultSerializationBinder.cs" />
+    <Compile Include="Serialization\ErrorContext.cs" />
+    <Compile Include="Serialization\IContractResolver.cs" />
+    <Compile Include="Serialization\IValueProvider.cs" />
+    <Compile Include="Serialization\JsonArrayContract.cs" />
+    <Compile Include="Serialization\JsonContract.cs" />
+    <Compile Include="Serialization\JsonDictionaryContract.cs" />
+    <Compile Include="Serialization\JsonProperty.cs" />
+    <Compile Include="Serialization\JsonPropertyCollection.cs" />
+    <Compile Include="MissingMemberHandling.cs" />
+    <Compile Include="NullValueHandling.cs" />
+    <Compile Include="ReferenceLoopHandling.cs" />
+    <Compile Include="Schema\JsonSchema.cs" />
+    <Compile Include="Schema\JsonSchemaBuilder.cs" />
+    <Compile Include="Schema\JsonSchemaConstants.cs" />
+    <Compile Include="Schema\JsonSchemaGenerator.cs" />
+    <Compile Include="Serialization\IReferenceResolver.cs" />
+    <Compile Include="Schema\JsonSchemaType.cs" />
+    <Compile Include="Serialization\JsonObjectContract.cs" />
+    <Compile Include="Serialization\JsonSerializerInternalBase.cs" />
+    <Compile Include="Serialization\JsonSerializerInternalReader.cs" />
+    <Compile Include="Serialization\JsonSerializerInternalWriter.cs" />
+    <Compile Include="Serialization\JsonSerializerProxy.cs" />
+    <Compile Include="Serialization\JsonStringContract.cs" />
+    <Compile Include="Serialization\JsonTypeReflector.cs" />
+    <Compile Include="Serialization\CachedAttributeGetter.cs" />
+    <Compile Include="Serialization\LateBoundMetadataTypeAttribute.cs" />
+    <Compile Include="Serialization\ReflectionValueProvider.cs" />
+    <Compile Include="Serialization\OnErrorAttribute.cs" />
+    <Compile Include="Utilities\Base64Encoder.cs" />
+    <Compile Include="Utilities\DynamicProxyMetaObject.cs" />
+    <Compile Include="Utilities\DynamicUtils.cs" />
+    <Compile Include="Utilities\DynamicWrapper.cs" />
+    <Compile Include="Utilities\DynamicReflectionDelegateFactory.cs" />
+    <Compile Include="Serialization\ObjectConstructor.cs" />
+    <Compile Include="Utilities\ILGeneratorExtensions.cs" />
+    <Compile Include="Utilities\ReflectionDelegateFactory.cs" />
+    <Compile Include="Utilities\LateBoundReflectionDelegateFactory.cs" />
+    <Compile Include="Utilities\MethodCall.cs" />
+    <Compile Include="Utilities\ThreadSafeStore.cs" />
+    <Compile Include="TypeNameHandling.cs" />
+    <Compile Include="Utilities\BidirectionalDictionary.cs" />
+    <Compile Include="Utilities\ConvertUtils.cs" />
+    <Compile Include="Utilities\CollectionWrapper.cs" />
+    <Compile Include="Utilities\DateTimeUtils.cs" />
+    <Compile Include="Utilities\DictionaryWrapper.cs" />
+    <Compile Include="Utilities\EnumUtils.cs" />
+    <Compile Include="Utilities\EnumValue.cs" />
+    <Compile Include="Utilities\EnumValues.cs" />
+    <Compile Include="Utilities\JavaScriptUtils.cs" />
+    <Compile Include="JsonToken.cs" />
+    <Compile Include="JsonWriter.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Utilities\StringBuffer.cs" />
+    <Compile Include="Utilities\CollectionUtils.cs" />
+    <Compile Include="Utilities\ListWrapper.cs" />
+    <Compile Include="Utilities\MathUtils.cs" />
+    <Compile Include="Utilities\MiscellaneousUtils.cs" />
+    <Compile Include="Utilities\ReflectionUtils.cs" />
+    <Compile Include="Utilities\StringUtils.cs" />
+    <Compile Include="Utilities\ValidationUtils.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 2.0 %28x86%29</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.0 %28x86%29</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="Dynamic.snk" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+</Project>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj
new file mode 100644 (file)
index 0000000..6c5379d
--- /dev/null
@@ -0,0 +1,267 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup Condition="'$(MSBuildToolsVersion)' == '3.5'">
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+  </PropertyGroup>
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{DC3C6F3D-2CA1-4278-9B79-63770FB3EA2D}</ProjectGuid>
+    <ProjectTypeGuids>{A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Newtonsoft.Json</RootNamespace>
+    <AssemblyName>Newtonsoft.Json.Silverlight</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <SilverlightApplication>false</SilverlightApplication>
+    <ValidateXaml>true</ValidateXaml>
+    <ThrowErrorsInValidation>false</ThrowErrorsInValidation>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+    <TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier>
+    <SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+    <TargetFrameworkProfile />
+    <SignManifests>false</SignManifests>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>Bin\Debug\Silverlight\</OutputPath>
+    <DefineConstants>DEBUG;TRACE;SILVERLIGHT</DefineConstants>
+    <NoStdLib>true</NoStdLib>
+    <NoConfig>true</NoConfig>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>Bin\Debug\Silverlight\Newtonsoft.Json.Silverlight.xml</DocumentationFile>
+    <CodeAnalysisRuleSet>Newtonsoft.Json.ruleset</CodeAnalysisRuleSet>
+    <RunCodeAnalysis>true</RunCodeAnalysis>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>Bin\Release\Silverlight\</OutputPath>
+    <DefineConstants>TRACE;SILVERLIGHT</DefineConstants>
+    <NoStdLib>true</NoStdLib>
+    <NoConfig>true</NoConfig>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>Bin\Release\Silverlight\Newtonsoft.Json.Silverlight.xml</DocumentationFile>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System.Runtime.Serialization" />
+    <Reference Include="System.Windows" />
+    <Reference Include="mscorlib" />
+    <Reference Include="system" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml" />
+    <Reference Include="System.Net" />
+    <Reference Include="System.Windows.Browser" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Bson\BsonBinaryType.cs" />
+    <Compile Include="Bson\BsonBinaryWriter.cs" />
+    <Compile Include="Bson\BsonObjectId.cs" />
+    <Compile Include="Bson\BsonReader.cs" />
+    <Compile Include="Bson\BsonToken.cs" />
+    <Compile Include="Bson\BsonType.cs" />
+    <Compile Include="Bson\BsonWriter.cs" />
+    <Compile Include="ConstructorHandling.cs" />
+    <Compile Include="Converters\BinaryConverter.cs" />
+    <Compile Include="Converters\BsonObjectIdConverter.cs" />
+    <Compile Include="Converters\CustomCreationConverter.cs" />
+    <Compile Include="Converters\DataSetConverter.cs" />
+    <Compile Include="Converters\DataTableConverter.cs" />
+    <Compile Include="Converters\DateTimeConverterBase.cs" />
+    <Compile Include="Converters\EntityKeyMemberConverter.cs" />
+    <Compile Include="Converters\ExpandoObjectConverter.cs" />
+    <Compile Include="Converters\IsoDateTimeConverter.cs" />
+    <Compile Include="Converters\JavaScriptDateTimeConverter.cs" />
+    <Compile Include="Converters\JsonDateTimeSerializationMode.cs" />
+    <Compile Include="Converters\KeyValuePairConverter.cs" />
+    <Compile Include="Converters\RegexConverter.cs" />
+    <Compile Include="Converters\StringEnumConverter.cs" />
+    <Compile Include="Converters\XmlNodeConverter.cs" />
+    <Compile Include="FormatterAssemblyStyle.cs" />
+    <Compile Include="DefaultValueHandling.cs" />
+    <Compile Include="IJsonLineInfo.cs" />
+    <Compile Include="JsonArrayAttribute.cs" />
+    <Compile Include="JsonConstructorAttribute.cs" />
+    <Compile Include="JsonContainerAttribute.cs" />
+    <Compile Include="JsonConvert.cs" />
+    <Compile Include="JsonConverter.cs" />
+    <Compile Include="JsonConverterAttribute.cs" />
+    <Compile Include="JsonConverterCollection.cs" />
+    <Compile Include="JsonIgnoreAttribute.cs" />
+    <Compile Include="JsonObjectAttribute.cs" />
+    <Compile Include="JsonPropertyAttribute.cs" />
+    <Compile Include="JsonReader.cs" />
+    <Compile Include="JsonReaderException.cs" />
+    <Compile Include="JsonSerializationException.cs" />
+    <Compile Include="JsonSerializer.cs" />
+    <Compile Include="JsonSerializerSettings.cs" />
+    <Compile Include="JsonTextReader.cs" />
+    <Compile Include="JsonTextWriter.cs" />
+    <Compile Include="JsonToken.cs" />
+    <Compile Include="JsonValidatingReader.cs" />
+    <Compile Include="JsonWriter.cs" />
+    <Compile Include="JsonWriterException.cs" />
+    <Compile Include="Linq\ComponentModel\JPropertyDescriptor.cs" />
+    <Compile Include="Linq\Extensions.cs" />
+    <Compile Include="Linq\IJEnumerable.cs" />
+    <Compile Include="Linq\JArray.cs" />
+    <Compile Include="Linq\JConstructor.cs" />
+    <Compile Include="Linq\JContainer.cs" />
+    <Compile Include="Linq\JEnumerable.cs" />
+    <Compile Include="Linq\JObject.cs" />
+    <Compile Include="Linq\JPath.cs" />
+    <Compile Include="Linq\JProperty.cs" />
+    <Compile Include="Linq\JRaw.cs" />
+    <Compile Include="Linq\JToken.cs" />
+    <Compile Include="Linq\JTokenEqualityComparer.cs" />
+    <Compile Include="Linq\JTokenReader.cs" />
+    <Compile Include="Linq\JTokenType.cs" />
+    <Compile Include="Linq\JTokenWriter.cs" />
+    <Compile Include="Linq\JValue.cs" />
+    <Compile Include="MemberSerialization.cs" />
+    <Compile Include="MissingMemberHandling.cs" />
+    <Compile Include="NullValueHandling.cs" />
+    <Compile Include="ObjectCreationHandling.cs" />
+    <Compile Include="PreserveReferencesHandling.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="ReferenceLoopHandling.cs" />
+    <Compile Include="Required.cs" />
+    <Compile Include="SerializationBinder.cs" />
+    <Compile Include="Serialization\CachedAttributeGetter.cs" />
+    <Compile Include="Serialization\CamelCasePropertyNamesContractResolver.cs" />
+    <Compile Include="Serialization\DefaultContractResolver.cs" />
+    <Compile Include="Serialization\DefaultReferenceResolver.cs" />
+    <Compile Include="Serialization\DefaultSerializationBinder.cs" />
+    <Compile Include="Serialization\DynamicValueProvider.cs" />
+    <Compile Include="Serialization\ErrorContext.cs" />
+    <Compile Include="Serialization\ErrorEventArgs.cs" />
+    <Compile Include="Serialization\IContractResolver.cs" />
+    <Compile Include="Serialization\IReferenceResolver.cs" />
+    <Compile Include="Serialization\IValueProvider.cs" />
+    <Compile Include="Serialization\JsonArrayContract.cs" />
+    <Compile Include="Serialization\JsonContract.cs" />
+    <Compile Include="Serialization\JsonDictionaryContract.cs" />
+    <Compile Include="Serialization\JsonDynamicContract.cs" />
+    <Compile Include="Serialization\JsonFormatterConverter.cs" />
+    <Compile Include="Serialization\JsonISerializableContract.cs" />
+    <Compile Include="Serialization\JsonLinqContract.cs" />
+    <Compile Include="Serialization\JsonObjectContract.cs" />
+    <Compile Include="Serialization\JsonPrimitiveContract.cs" />
+    <Compile Include="Serialization\JsonProperty.cs" />
+    <Compile Include="Serialization\JsonPropertyCollection.cs" />
+    <Compile Include="Serialization\JsonSerializerInternalBase.cs" />
+    <Compile Include="Serialization\JsonSerializerProxy.cs" />
+    <Compile Include="Serialization\JsonSerializerInternalReader.cs" />
+    <Compile Include="Serialization\JsonSerializerInternalWriter.cs" />
+    <Compile Include="Serialization\JsonStringContract.cs" />
+    <Compile Include="Serialization\LateBoundMetadataTypeAttribute.cs" />
+    <Compile Include="Serialization\ObjectConstructor.cs" />
+    <Compile Include="Serialization\OnErrorAttribute.cs" />
+    <Compile Include="Serialization\ReflectionValueProvider.cs" />
+    <Compile Include="StreamingContext.cs" />
+    <Compile Include="TypeNameHandling.cs" />
+    <Compile Include="Utilities\Base64Encoder.cs" />
+    <Compile Include="Utilities\BidirectionalDictionary.cs" />
+    <Compile Include="Utilities\CollectionUtils.cs" />
+    <Compile Include="Utilities\CollectionWrapper.cs" />
+    <Compile Include="Utilities\ConvertUtils.cs" />
+    <Compile Include="Utilities\DateTimeUtils.cs" />
+    <Compile Include="Utilities\DictionaryWrapper.cs" />
+    <Compile Include="Utilities\DynamicProxy.cs" />
+    <Compile Include="Utilities\DynamicProxyMetaObject.cs" />
+    <Compile Include="Utilities\DynamicReflectionDelegateFactory.cs" />
+    <Compile Include="Utilities\DynamicUtils.cs" />
+    <Compile Include="Utilities\DynamicWrapper.cs" />
+    <Compile Include="Utilities\EnumUtils.cs" />
+    <Compile Include="Utilities\EnumValue.cs" />
+    <Compile Include="Utilities\EnumValues.cs" />
+    <Compile Include="Utilities\ILGeneratorExtensions.cs" />
+    <Compile Include="Utilities\JavaScriptUtils.cs" />
+    <Compile Include="Utilities\LateBoundReflectionDelegateFactory.cs" />
+    <Compile Include="Utilities\ListWrapper.cs" />
+    <Compile Include="Utilities\MathUtils.cs" />
+    <Compile Include="Utilities\MethodCall.cs" />
+    <Compile Include="Utilities\MiscellaneousUtils.cs" />
+    <Compile Include="Utilities\ReflectionDelegateFactory.cs" />
+    <Compile Include="Utilities\ReflectionUtils.cs" />
+    <Compile Include="Utilities\StringBuffer.cs" />
+    <Compile Include="Utilities\StringUtils.cs" />
+    <Compile Include="Utilities\ThreadSafeStore.cs" />
+    <Compile Include="Utilities\ValidationUtils.cs" />
+    <Compile Include="Schema\Extensions.cs" />
+    <Compile Include="Schema\JsonSchemaException.cs" />
+    <Compile Include="Schema\JsonSchemaModel.cs" />
+    <Compile Include="Schema\JsonSchemaModelBuilder.cs" />
+    <Compile Include="Schema\JsonSchemaNodeCollection.cs" />
+    <Compile Include="Schema\JsonSchemaNode.cs" />
+    <Compile Include="Schema\JsonSchemaWriter.cs" />
+    <Compile Include="Schema\UndefinedSchemaIdHandling.cs" />
+    <Compile Include="Schema\ValidationEventArgs.cs" />
+    <Compile Include="Schema\ValidationEventHandler.cs" />
+    <Compile Include="Schema\JsonSchema.cs" />
+    <Compile Include="Schema\JsonSchemaBuilder.cs" />
+    <Compile Include="Schema\JsonSchemaConstants.cs" />
+    <Compile Include="Schema\JsonSchemaGenerator.cs" />
+    <Compile Include="Schema\JsonSchemaResolver.cs" />
+    <Compile Include="Schema\JsonSchemaType.cs" />
+    <Compile Include="Serialization\JsonTypeReflector.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 3.1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+  <ProjectExtensions>
+    <VisualStudio>
+      <FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}">
+        <SilverlightProjectProperties />
+      </FlavorProperties>
+    </VisualStudio>
+  </ProjectExtensions>
+</Project>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Newtonsoft.Json.WindowsPhone.csproj b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Newtonsoft.Json.WindowsPhone.csproj
new file mode 100644 (file)
index 0000000..939848d
--- /dev/null
@@ -0,0 +1,215 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>10.0.20506</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{7A7F70AB-5C07-47ED-BDD2-ECC14DBACA5E}</ProjectGuid>
+    <ProjectTypeGuids>{C089C8C0-30E0-4E22-80C0-CE093F111A43};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Newtonsoft.Json.WindowsPhone</RootNamespace>
+    <AssemblyName>Newtonsoft.Json.WindowsPhone</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>
+    <TargetFrameworkProfile>WindowsPhone</TargetFrameworkProfile>
+    <TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier>
+    <SilverlightApplication>false</SilverlightApplication>
+    <ValidateXaml>true</ValidateXaml>
+    <ThrowErrorsInValidation>true</ThrowErrorsInValidation>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>Bin\Debug\WindowsPhone\</OutputPath>
+    <DefineConstants>DEBUG;TRACE;SILVERLIGHT;WINDOWS_PHONE</DefineConstants>
+    <NoStdLib>true</NoStdLib>
+    <NoConfig>true</NoConfig>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>
+    </DocumentationFile>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>Bin\Release\WindowsPhone\</OutputPath>
+    <DefineConstants>TRACE;SILVERLIGHT;WINDOWS_PHONE</DefineConstants>
+    <NoStdLib>true</NoStdLib>
+    <NoConfig>true</NoConfig>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>Bin\Release\WindowsPhone\Newtonsoft.Json.WindowsPhone.xml</DocumentationFile>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System.Runtime.Serialization" />
+    <Reference Include="System.Windows" />
+    <Reference Include="system" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml" />
+    <Reference Include="System.Net" />
+    <Reference Include="System.Xml.Linq" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Bson\BsonBinaryType.cs" />
+    <Compile Include="Bson\BsonBinaryWriter.cs" />
+    <Compile Include="Bson\BsonObjectId.cs" />
+    <Compile Include="Bson\BsonReader.cs" />
+    <Compile Include="Bson\BsonToken.cs" />
+    <Compile Include="Bson\BsonType.cs" />
+    <Compile Include="Bson\BsonWriter.cs" />
+    <Compile Include="ConstructorHandling.cs" />
+    <Compile Include="Converters\BinaryConverter.cs" />
+    <Compile Include="Converters\BsonObjectIdConverter.cs" />
+    <Compile Include="Converters\CustomCreationConverter.cs" />
+    <Compile Include="Converters\DataSetConverter.cs" />
+    <Compile Include="Converters\DataTableConverter.cs" />
+    <Compile Include="Converters\DateTimeConverterBase.cs" />
+    <Compile Include="Converters\EntityKeyMemberConverter.cs" />
+    <Compile Include="Converters\ExpandoObjectConverter.cs" />
+    <Compile Include="Converters\IsoDateTimeConverter.cs" />
+    <Compile Include="Converters\JavaScriptDateTimeConverter.cs" />
+    <Compile Include="Converters\JsonDateTimeSerializationMode.cs" />
+    <Compile Include="Converters\KeyValuePairConverter.cs" />
+    <Compile Include="Converters\RegexConverter.cs" />
+    <Compile Include="Converters\StringEnumConverter.cs" />
+    <Compile Include="Converters\XmlNodeConverter.cs" />
+    <Compile Include="FormatterAssemblyStyle.cs" />
+    <Compile Include="DefaultValueHandling.cs" />
+    <Compile Include="IJsonLineInfo.cs" />
+    <Compile Include="JsonArrayAttribute.cs" />
+    <Compile Include="JsonConstructorAttribute.cs" />
+    <Compile Include="JsonContainerAttribute.cs" />
+    <Compile Include="JsonConvert.cs" />
+    <Compile Include="JsonConverter.cs" />
+    <Compile Include="JsonConverterAttribute.cs" />
+    <Compile Include="JsonConverterCollection.cs" />
+    <Compile Include="JsonIgnoreAttribute.cs" />
+    <Compile Include="JsonObjectAttribute.cs" />
+    <Compile Include="JsonPropertyAttribute.cs" />
+    <Compile Include="JsonReader.cs" />
+    <Compile Include="JsonReaderException.cs" />
+    <Compile Include="JsonSerializationException.cs" />
+    <Compile Include="JsonSerializer.cs" />
+    <Compile Include="JsonSerializerSettings.cs" />
+    <Compile Include="JsonTextReader.cs" />
+    <Compile Include="JsonTextWriter.cs" />
+    <Compile Include="JsonToken.cs" />
+    <Compile Include="JsonValidatingReader.cs" />
+    <Compile Include="JsonWriter.cs" />
+    <Compile Include="JsonWriterException.cs" />
+    <Compile Include="Linq\ComponentModel\JPropertyDescriptor.cs" />
+    <Compile Include="Linq\Extensions.cs" />
+    <Compile Include="Linq\IJEnumerable.cs" />
+    <Compile Include="Linq\JArray.cs" />
+    <Compile Include="Linq\JConstructor.cs" />
+    <Compile Include="Linq\JContainer.cs" />
+    <Compile Include="Linq\JEnumerable.cs" />
+    <Compile Include="Linq\JObject.cs" />
+    <Compile Include="Linq\JPath.cs" />
+    <Compile Include="Linq\JProperty.cs" />
+    <Compile Include="Linq\JRaw.cs" />
+    <Compile Include="Linq\JToken.cs" />
+    <Compile Include="Linq\JTokenEqualityComparer.cs" />
+    <Compile Include="Linq\JTokenReader.cs" />
+    <Compile Include="Linq\JTokenType.cs" />
+    <Compile Include="Linq\JTokenWriter.cs" />
+    <Compile Include="Linq\JValue.cs" />
+    <Compile Include="MemberSerialization.cs" />
+    <Compile Include="MissingMemberHandling.cs" />
+    <Compile Include="NullValueHandling.cs" />
+    <Compile Include="ObjectCreationHandling.cs" />
+    <Compile Include="PreserveReferencesHandling.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="ReferenceLoopHandling.cs" />
+    <Compile Include="Required.cs" />
+    <Compile Include="SerializationBinder.cs" />
+    <Compile Include="Serialization\CachedAttributeGetter.cs" />
+    <Compile Include="Serialization\CamelCasePropertyNamesContractResolver.cs" />
+    <Compile Include="Serialization\DefaultContractResolver.cs" />
+    <Compile Include="Serialization\DefaultReferenceResolver.cs" />
+    <Compile Include="Serialization\DefaultSerializationBinder.cs" />
+    <Compile Include="Serialization\DynamicValueProvider.cs" />
+    <Compile Include="Serialization\ErrorContext.cs" />
+    <Compile Include="Serialization\ErrorEventArgs.cs" />
+    <Compile Include="Serialization\IContractResolver.cs" />
+    <Compile Include="Serialization\IReferenceResolver.cs" />
+    <Compile Include="Serialization\IValueProvider.cs" />
+    <Compile Include="Serialization\JsonArrayContract.cs" />
+    <Compile Include="Serialization\JsonContract.cs" />
+    <Compile Include="Serialization\JsonDictionaryContract.cs" />
+    <Compile Include="Serialization\JsonDynamicContract.cs" />
+    <Compile Include="Serialization\JsonFormatterConverter.cs" />
+    <Compile Include="Serialization\JsonISerializableContract.cs" />
+    <Compile Include="Serialization\JsonLinqContract.cs" />
+    <Compile Include="Serialization\JsonObjectContract.cs" />
+    <Compile Include="Serialization\JsonPrimitiveContract.cs" />
+    <Compile Include="Serialization\JsonProperty.cs" />
+    <Compile Include="Serialization\JsonPropertyCollection.cs" />
+    <Compile Include="Serialization\JsonSerializerInternalBase.cs" />
+    <Compile Include="Serialization\JsonSerializerProxy.cs" />
+    <Compile Include="Serialization\JsonSerializerInternalReader.cs" />
+    <Compile Include="Serialization\JsonSerializerInternalWriter.cs" />
+    <Compile Include="Serialization\JsonStringContract.cs" />
+    <Compile Include="Serialization\LateBoundMetadataTypeAttribute.cs" />
+    <Compile Include="Serialization\ObjectConstructor.cs" />
+    <Compile Include="Serialization\OnErrorAttribute.cs" />
+    <Compile Include="Serialization\ReflectionValueProvider.cs" />
+    <Compile Include="StreamingContext.cs" />
+    <Compile Include="TypeNameHandling.cs" />
+    <Compile Include="Utilities\Base64Encoder.cs" />
+    <Compile Include="Utilities\BidirectionalDictionary.cs" />
+    <Compile Include="Utilities\CollectionUtils.cs" />
+    <Compile Include="Utilities\CollectionWrapper.cs" />
+    <Compile Include="Utilities\ConvertUtils.cs" />
+    <Compile Include="Utilities\DateTimeUtils.cs" />
+    <Compile Include="Utilities\DictionaryWrapper.cs" />
+    <Compile Include="Utilities\DynamicReflectionDelegateFactory.cs" />
+    <Compile Include="Utilities\DynamicWrapper.cs" />
+    <Compile Include="Utilities\EnumUtils.cs" />
+    <Compile Include="Utilities\EnumValue.cs" />
+    <Compile Include="Utilities\EnumValues.cs" />
+    <Compile Include="Utilities\ILGeneratorExtensions.cs" />
+    <Compile Include="Utilities\JavaScriptUtils.cs" />
+    <Compile Include="Utilities\LateBoundReflectionDelegateFactory.cs" />
+    <Compile Include="Utilities\ListWrapper.cs" />
+    <Compile Include="Utilities\MathUtils.cs" />
+    <Compile Include="Utilities\MethodCall.cs" />
+    <Compile Include="Utilities\MiscellaneousUtils.cs" />
+    <Compile Include="Utilities\ReflectionDelegateFactory.cs" />
+    <Compile Include="Utilities\ReflectionUtils.cs" />
+    <Compile Include="Utilities\StringBuffer.cs" />
+    <Compile Include="Utilities\StringUtils.cs" />
+    <Compile Include="Utilities\ThreadSafeStore.cs" />
+    <Compile Include="Utilities\ValidationUtils.cs" />
+    <Compile Include="Schema\Extensions.cs" />
+    <Compile Include="Schema\JsonSchemaException.cs" />
+    <Compile Include="Schema\JsonSchemaModel.cs" />
+    <Compile Include="Schema\JsonSchemaModelBuilder.cs" />
+    <Compile Include="Schema\JsonSchemaNodeCollection.cs" />
+    <Compile Include="Schema\JsonSchemaNode.cs" />
+    <Compile Include="Schema\JsonSchemaWriter.cs" />
+    <Compile Include="Schema\UndefinedSchemaIdHandling.cs" />
+    <Compile Include="Schema\ValidationEventArgs.cs" />
+    <Compile Include="Schema\ValidationEventHandler.cs" />
+    <Compile Include="Schema\JsonSchema.cs" />
+    <Compile Include="Schema\JsonSchemaBuilder.cs" />
+    <Compile Include="Schema\JsonSchemaConstants.cs" />
+    <Compile Include="Schema\JsonSchemaGenerator.cs" />
+    <Compile Include="Schema\JsonSchemaResolver.cs" />
+    <Compile Include="Schema\JsonSchemaType.cs" />
+    <Compile Include="Serialization\JsonTypeReflector.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.$(TargetFrameworkProfile).Overrides.targets" />
+  <Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.CSharp.targets" />
+  <ProjectExtensions />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Newtonsoft.Json.csproj b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Newtonsoft.Json.csproj
new file mode 100644 (file)
index 0000000..a69324b
--- /dev/null
@@ -0,0 +1,266 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Newtonsoft.Json</RootNamespace>
+    <AssemblyName>Newtonsoft.Json</AssemblyName>
+    <SignAssembly>false</SignAssembly>
+    <AssemblyOriginatorKeyFile>
+    </AssemblyOriginatorKeyFile>
+    <SccProjectName>
+    </SccProjectName>
+    <SccLocalPath>
+    </SccLocalPath>
+    <SccAuxPath>
+    </SccAuxPath>
+    <SccProvider>
+    </SccProvider>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\Net\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>bin\Debug\Net\Newtonsoft.Json.xml</DocumentationFile>
+    <RunCodeAnalysis>true</RunCodeAnalysis>
+    <CodeAnalysisRules>
+    </CodeAnalysisRules>
+    <CodeAnalysisRuleSet>Newtonsoft.Json.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\Net\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>bin\Release\Net\Newtonsoft.Json.xml</DocumentationFile>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Runtime.Serialization">
+      <RequiredTargetFramework>3.0</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Xml" />
+    <Reference Include="System.Xml.Linq">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Bson\BsonBinaryType.cs" />
+    <Compile Include="Bson\BsonBinaryWriter.cs" />
+    <Compile Include="Bson\BsonReader.cs" />
+    <Compile Include="Bson\BsonToken.cs" />
+    <Compile Include="Bson\BsonType.cs" />
+    <Compile Include="Bson\BsonWriter.cs" />
+    <Compile Include="Bson\BsonObjectId.cs" />
+    <Compile Include="Converters\BinaryConverter.cs" />
+    <Compile Include="Converters\DataSetConverter.cs" />
+    <Compile Include="Converters\DataTableConverter.cs" />
+    <Compile Include="Converters\CustomCreationConverter.cs" />
+    <Compile Include="Converters\DateTimeConverterBase.cs" />
+    <Compile Include="Converters\EntityKeyMemberConverter.cs" />
+    <Compile Include="Converters\ExpandoObjectConverter.cs" />
+    <Compile Include="Converters\KeyValuePairConverter.cs" />
+    <Compile Include="Converters\BsonObjectIdConverter.cs" />
+    <Compile Include="Converters\RegexConverter.cs" />
+    <Compile Include="Converters\StringEnumConverter.cs" />
+    <Compile Include="ConstructorHandling.cs" />
+    <Compile Include="JsonConstructorAttribute.cs" />
+    <Compile Include="Utilities\DynamicProxy.cs" />
+    <Compile Include="Linq\JPath.cs" />
+    <Compile Include="Linq\JRaw.cs" />
+    <Compile Include="Required.cs" />
+    <Compile Include="Serialization\JsonDynamicContract.cs" />
+    <Compile Include="Serialization\JsonFormatterConverter.cs" />
+    <Compile Include="Serialization\JsonISerializableContract.cs" />
+    <Compile Include="Serialization\JsonLinqContract.cs" />
+    <Compile Include="Serialization\JsonPrimitiveContract.cs" />
+    <Compile Include="Serialization\DynamicValueProvider.cs" />
+    <Compile Include="Serialization\ErrorEventArgs.cs" />
+    <Compile Include="Linq\ComponentModel\JPropertyDescriptor.cs" />
+    <Compile Include="Serialization\DefaultReferenceResolver.cs" />
+    <Compile Include="PreserveReferencesHandling.cs" />
+    <Compile Include="IJsonLineInfo.cs" />
+    <Compile Include="JsonArrayAttribute.cs" />
+    <Compile Include="JsonContainerAttribute.cs" />
+    <Compile Include="DefaultValueHandling.cs" />
+    <Compile Include="JsonConverterAttribute.cs" />
+    <Compile Include="JsonObjectAttribute.cs" />
+    <Compile Include="JsonSerializerSettings.cs" />
+    <Compile Include="JsonValidatingReader.cs" />
+    <Compile Include="Linq\IJEnumerable.cs" />
+    <Compile Include="Linq\JTokenEqualityComparer.cs" />
+    <Compile Include="MemberSerialization.cs" />
+    <Compile Include="ObjectCreationHandling.cs" />
+    <Compile Include="Converters\IsoDateTimeConverter.cs" />
+    <Compile Include="Converters\JavaScriptDateTimeConverter.cs" />
+    <Compile Include="Converters\JsonDateTimeSerializationMode.cs" />
+    <Compile Include="Converters\XmlNodeConverter.cs" />
+    <Compile Include="JsonTextReader.cs" />
+    <Compile Include="JsonPropertyAttribute.cs" />
+    <Compile Include="JsonIgnoreAttribute.cs" />
+    <Compile Include="JsonTextWriter.cs" />
+    <Compile Include="JsonWriterException.cs" />
+    <Compile Include="JsonReaderException.cs" />
+    <Compile Include="JsonConverter.cs" />
+    <Compile Include="JsonConverterCollection.cs" />
+    <Compile Include="JsonReader.cs" />
+    <Compile Include="JsonConvert.cs" />
+    <Compile Include="JsonSerializationException.cs" />
+    <Compile Include="JsonSerializer.cs" />
+    <Compile Include="Linq\Extensions.cs" />
+    <Compile Include="Linq\JConstructor.cs" />
+    <Compile Include="Linq\JContainer.cs" />
+    <Compile Include="Linq\JEnumerable.cs" />
+    <Compile Include="Linq\JObject.cs" />
+    <Compile Include="Linq\JArray.cs" />
+    <Compile Include="Linq\JTokenReader.cs" />
+    <Compile Include="Linq\JTokenWriter.cs" />
+    <Compile Include="Linq\JToken.cs" />
+    <Compile Include="Linq\JProperty.cs" />
+    <Compile Include="Linq\JTokenType.cs" />
+    <Compile Include="Linq\JValue.cs" />
+    <Compile Include="Schema\Extensions.cs" />
+    <Compile Include="Schema\JsonSchemaException.cs" />
+    <Compile Include="Schema\JsonSchemaModel.cs" />
+    <Compile Include="Schema\JsonSchemaModelBuilder.cs" />
+    <Compile Include="Schema\JsonSchemaNodeCollection.cs" />
+    <Compile Include="Schema\JsonSchemaNode.cs" />
+    <Compile Include="Schema\JsonSchemaResolver.cs" />
+    <Compile Include="Schema\JsonSchemaWriter.cs" />
+    <Compile Include="Schema\UndefinedSchemaIdHandling.cs" />
+    <Compile Include="Schema\ValidationEventArgs.cs" />
+    <Compile Include="Schema\ValidationEventHandler.cs" />
+    <Compile Include="Serialization\CamelCasePropertyNamesContractResolver.cs" />
+    <Compile Include="Serialization\DefaultContractResolver.cs" />
+    <Compile Include="Serialization\DefaultSerializationBinder.cs" />
+    <Compile Include="Serialization\ErrorContext.cs" />
+    <Compile Include="Serialization\IContractResolver.cs" />
+    <Compile Include="Serialization\IValueProvider.cs" />
+    <Compile Include="Serialization\JsonArrayContract.cs" />
+    <Compile Include="Serialization\JsonContract.cs" />
+    <Compile Include="Serialization\JsonDictionaryContract.cs" />
+    <Compile Include="Serialization\JsonProperty.cs" />
+    <Compile Include="Serialization\JsonPropertyCollection.cs" />
+    <Compile Include="MissingMemberHandling.cs" />
+    <Compile Include="NullValueHandling.cs" />
+    <Compile Include="ReferenceLoopHandling.cs" />
+    <Compile Include="Schema\JsonSchema.cs" />
+    <Compile Include="Schema\JsonSchemaBuilder.cs" />
+    <Compile Include="Schema\JsonSchemaConstants.cs" />
+    <Compile Include="Schema\JsonSchemaGenerator.cs" />
+    <Compile Include="Serialization\IReferenceResolver.cs" />
+    <Compile Include="Schema\JsonSchemaType.cs" />
+    <Compile Include="Serialization\JsonObjectContract.cs" />
+    <Compile Include="Serialization\JsonSerializerInternalBase.cs" />
+    <Compile Include="Serialization\JsonSerializerInternalReader.cs" />
+    <Compile Include="Serialization\JsonSerializerInternalWriter.cs" />
+    <Compile Include="Serialization\JsonSerializerProxy.cs" />
+    <Compile Include="Serialization\JsonStringContract.cs" />
+    <Compile Include="Serialization\JsonTypeReflector.cs" />
+    <Compile Include="Serialization\CachedAttributeGetter.cs" />
+    <Compile Include="Serialization\LateBoundMetadataTypeAttribute.cs" />
+    <Compile Include="Serialization\ReflectionValueProvider.cs" />
+    <Compile Include="Serialization\OnErrorAttribute.cs" />
+    <Compile Include="Utilities\Base64Encoder.cs" />
+    <Compile Include="Utilities\DynamicProxyMetaObject.cs" />
+    <Compile Include="Utilities\DynamicUtils.cs" />
+    <Compile Include="Utilities\DynamicWrapper.cs" />
+    <Compile Include="Utilities\DynamicReflectionDelegateFactory.cs" />
+    <Compile Include="Serialization\ObjectConstructor.cs" />
+    <Compile Include="Utilities\ILGeneratorExtensions.cs" />
+    <Compile Include="Utilities\ReflectionDelegateFactory.cs" />
+    <Compile Include="Utilities\LateBoundReflectionDelegateFactory.cs" />
+    <Compile Include="Utilities\MethodCall.cs" />
+    <Compile Include="Utilities\ThreadSafeStore.cs" />
+    <Compile Include="TypeNameHandling.cs" />
+    <Compile Include="Utilities\BidirectionalDictionary.cs" />
+    <Compile Include="Utilities\ConvertUtils.cs" />
+    <Compile Include="Utilities\CollectionWrapper.cs" />
+    <Compile Include="Utilities\DateTimeUtils.cs" />
+    <Compile Include="Utilities\DictionaryWrapper.cs" />
+    <Compile Include="Utilities\EnumUtils.cs" />
+    <Compile Include="Utilities\EnumValue.cs" />
+    <Compile Include="Utilities\EnumValues.cs" />
+    <Compile Include="Utilities\JavaScriptUtils.cs" />
+    <Compile Include="JsonToken.cs" />
+    <Compile Include="JsonWriter.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Utilities\StringBuffer.cs" />
+    <Compile Include="Utilities\CollectionUtils.cs" />
+    <Compile Include="Utilities\ListWrapper.cs" />
+    <Compile Include="Utilities\MathUtils.cs" />
+    <Compile Include="Utilities\MiscellaneousUtils.cs" />
+    <Compile Include="Utilities\ReflectionUtils.cs" />
+    <Compile Include="Utilities\StringUtils.cs" />
+    <Compile Include="Utilities\ValidationUtils.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 2.0 %28x86%29</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.0 %28x86%29</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="Dynamic.snk" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+</Project>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Newtonsoft.Json.ruleset b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Newtonsoft.Json.ruleset
new file mode 100644 (file)
index 0000000..d80dec1
--- /dev/null
@@ -0,0 +1,234 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RuleSet Name="Newtonsoft.Json.ruleset" ToolsVersion="10.0">
+  <IncludeAll Action="Warning" />
+  <Rules AnalyzerId="Microsoft.Analyzers.ManagedCodeAnalysis" RuleNamespace="Microsoft.Rules.Managed">
+    <Rule Id="CA1000" Action="None" />
+    <Rule Id="CA1001" Action="None" />
+    <Rule Id="CA1002" Action="None" />
+    <Rule Id="CA1003" Action="None" />
+    <Rule Id="CA1004" Action="None" />
+    <Rule Id="CA1005" Action="None" />
+    <Rule Id="CA1006" Action="None" />
+    <Rule Id="CA1007" Action="None" />
+    <Rule Id="CA1008" Action="None" />
+    <Rule Id="CA1009" Action="None" />
+    <Rule Id="CA1010" Action="None" />
+    <Rule Id="CA1011" Action="None" />
+    <Rule Id="CA1012" Action="None" />
+    <Rule Id="CA1013" Action="None" />
+    <Rule Id="CA1014" Action="None" />
+    <Rule Id="CA1016" Action="None" />
+    <Rule Id="CA1017" Action="None" />
+    <Rule Id="CA1018" Action="None" />
+    <Rule Id="CA1019" Action="None" />
+    <Rule Id="CA1020" Action="None" />
+    <Rule Id="CA1021" Action="None" />
+    <Rule Id="CA1023" Action="None" />
+    <Rule Id="CA1024" Action="None" />
+    <Rule Id="CA1025" Action="None" />
+    <Rule Id="CA1026" Action="None" />
+    <Rule Id="CA1027" Action="None" />
+    <Rule Id="CA1028" Action="None" />
+    <Rule Id="CA1030" Action="None" />
+    <Rule Id="CA1031" Action="None" />
+    <Rule Id="CA1032" Action="None" />
+    <Rule Id="CA1033" Action="None" />
+    <Rule Id="CA1034" Action="None" />
+    <Rule Id="CA1035" Action="None" />
+    <Rule Id="CA1036" Action="None" />
+    <Rule Id="CA1038" Action="None" />
+    <Rule Id="CA1039" Action="None" />
+    <Rule Id="CA1040" Action="None" />
+    <Rule Id="CA1041" Action="None" />
+    <Rule Id="CA1043" Action="None" />
+    <Rule Id="CA1044" Action="None" />
+    <Rule Id="CA1045" Action="None" />
+    <Rule Id="CA1046" Action="None" />
+    <Rule Id="CA1047" Action="None" />
+    <Rule Id="CA1048" Action="None" />
+    <Rule Id="CA1049" Action="None" />
+    <Rule Id="CA1050" Action="None" />
+    <Rule Id="CA1051" Action="None" />
+    <Rule Id="CA1052" Action="None" />
+    <Rule Id="CA1053" Action="None" />
+    <Rule Id="CA1054" Action="None" />
+    <Rule Id="CA1055" Action="None" />
+    <Rule Id="CA1056" Action="None" />
+    <Rule Id="CA1057" Action="None" />
+    <Rule Id="CA1058" Action="None" />
+    <Rule Id="CA1059" Action="None" />
+    <Rule Id="CA1060" Action="None" />
+    <Rule Id="CA1061" Action="None" />
+    <Rule Id="CA1062" Action="None" />
+    <Rule Id="CA1063" Action="None" />
+    <Rule Id="CA1064" Action="None" />
+    <Rule Id="CA1065" Action="None" />
+    <Rule Id="CA1300" Action="None" />
+    <Rule Id="CA1301" Action="None" />
+    <Rule Id="CA1302" Action="None" />
+    <Rule Id="CA1303" Action="None" />
+    <Rule Id="CA1306" Action="None" />
+    <Rule Id="CA1307" Action="None" />
+    <Rule Id="CA1308" Action="None" />
+    <Rule Id="CA1309" Action="None" />
+    <Rule Id="CA1400" Action="None" />
+    <Rule Id="CA1401" Action="None" />
+    <Rule Id="CA1402" Action="None" />
+    <Rule Id="CA1403" Action="None" />
+    <Rule Id="CA1404" Action="None" />
+    <Rule Id="CA1405" Action="None" />
+    <Rule Id="CA1406" Action="None" />
+    <Rule Id="CA1407" Action="None" />
+    <Rule Id="CA1408" Action="None" />
+    <Rule Id="CA1409" Action="None" />
+    <Rule Id="CA1410" Action="None" />
+    <Rule Id="CA1411" Action="None" />
+    <Rule Id="CA1412" Action="None" />
+    <Rule Id="CA1413" Action="None" />
+    <Rule Id="CA1414" Action="None" />
+    <Rule Id="CA1415" Action="None" />
+    <Rule Id="CA1500" Action="None" />
+    <Rule Id="CA1501" Action="None" />
+    <Rule Id="CA1502" Action="None" />
+    <Rule Id="CA1504" Action="None" />
+    <Rule Id="CA1505" Action="None" />
+    <Rule Id="CA1506" Action="None" />
+    <Rule Id="CA1600" Action="None" />
+    <Rule Id="CA1601" Action="None" />
+    <Rule Id="CA1700" Action="None" />
+    <Rule Id="CA1701" Action="None" />
+    <Rule Id="CA1702" Action="None" />
+    <Rule Id="CA1703" Action="None" />
+    <Rule Id="CA1704" Action="None" />
+    <Rule Id="CA1707" Action="None" />
+    <Rule Id="CA1708" Action="None" />
+    <Rule Id="CA1709" Action="None" />
+    <Rule Id="CA1710" Action="None" />
+    <Rule Id="CA1711" Action="None" />
+    <Rule Id="CA1712" Action="None" />
+    <Rule Id="CA1713" Action="None" />
+    <Rule Id="CA1714" Action="None" />
+    <Rule Id="CA1715" Action="None" />
+    <Rule Id="CA1716" Action="None" />
+    <Rule Id="CA1717" Action="None" />
+    <Rule Id="CA1719" Action="None" />
+    <Rule Id="CA1720" Action="None" />
+    <Rule Id="CA1721" Action="None" />
+    <Rule Id="CA1722" Action="None" />
+    <Rule Id="CA1724" Action="None" />
+    <Rule Id="CA1725" Action="None" />
+    <Rule Id="CA1726" Action="None" />
+    <Rule Id="CA1800" Action="None" />
+    <Rule Id="CA1801" Action="None" />
+    <Rule Id="CA1802" Action="None" />
+    <Rule Id="CA1804" Action="None" />
+    <Rule Id="CA1806" Action="None" />
+    <Rule Id="CA1809" Action="None" />
+    <Rule Id="CA1810" Action="None" />
+    <Rule Id="CA1811" Action="None" />
+    <Rule Id="CA1812" Action="None" />
+    <Rule Id="CA1813" Action="None" />
+    <Rule Id="CA1814" Action="None" />
+    <Rule Id="CA1815" Action="None" />
+    <Rule Id="CA1816" Action="None" />
+    <Rule Id="CA1819" Action="None" />
+    <Rule Id="CA1820" Action="None" />
+    <Rule Id="CA1821" Action="None" />
+    <Rule Id="CA1822" Action="None" />
+    <Rule Id="CA1823" Action="None" />
+    <Rule Id="CA1824" Action="None" />
+    <Rule Id="CA1900" Action="None" />
+    <Rule Id="CA1901" Action="None" />
+    <Rule Id="CA1903" Action="Error" />
+    <Rule Id="CA2000" Action="None" />
+    <Rule Id="CA2001" Action="None" />
+    <Rule Id="CA2002" Action="None" />
+    <Rule Id="CA2003" Action="None" />
+    <Rule Id="CA2004" Action="None" />
+    <Rule Id="CA2006" Action="None" />
+    <Rule Id="CA2100" Action="None" />
+    <Rule Id="CA2101" Action="None" />
+    <Rule Id="CA2102" Action="None" />
+    <Rule Id="CA2103" Action="None" />
+    <Rule Id="CA2104" Action="None" />
+    <Rule Id="CA2105" Action="None" />
+    <Rule Id="CA2106" Action="None" />
+    <Rule Id="CA2107" Action="None" />
+    <Rule Id="CA2108" Action="None" />
+    <Rule Id="CA2109" Action="None" />
+    <Rule Id="CA2111" Action="None" />
+    <Rule Id="CA2112" Action="None" />
+    <Rule Id="CA2114" Action="None" />
+    <Rule Id="CA2115" Action="None" />
+    <Rule Id="CA2116" Action="None" />
+    <Rule Id="CA2117" Action="None" />
+    <Rule Id="CA2118" Action="None" />
+    <Rule Id="CA2119" Action="None" />
+    <Rule Id="CA2120" Action="None" />
+    <Rule Id="CA2121" Action="None" />
+    <Rule Id="CA2122" Action="None" />
+    <Rule Id="CA2123" Action="None" />
+    <Rule Id="CA2124" Action="None" />
+    <Rule Id="CA2126" Action="None" />
+    <Rule Id="CA2130" Action="None" />
+    <Rule Id="CA2131" Action="None" />
+    <Rule Id="CA2132" Action="None" />
+    <Rule Id="CA2133" Action="None" />
+    <Rule Id="CA2134" Action="None" />
+    <Rule Id="CA2135" Action="None" />
+    <Rule Id="CA2136" Action="None" />
+    <Rule Id="CA2137" Action="None" />
+    <Rule Id="CA2138" Action="None" />
+    <Rule Id="CA2139" Action="None" />
+    <Rule Id="CA2140" Action="None" />
+    <Rule Id="CA2141" Action="None" />
+    <Rule Id="CA2142" Action="None" />
+    <Rule Id="CA2143" Action="None" />
+    <Rule Id="CA2144" Action="None" />
+    <Rule Id="CA2145" Action="None" />
+    <Rule Id="CA2146" Action="None" />
+    <Rule Id="CA2147" Action="None" />
+    <Rule Id="CA2149" Action="None" />
+    <Rule Id="CA2200" Action="None" />
+    <Rule Id="CA2201" Action="None" />
+    <Rule Id="CA2202" Action="None" />
+    <Rule Id="CA2204" Action="None" />
+    <Rule Id="CA2205" Action="None" />
+    <Rule Id="CA2207" Action="None" />
+    <Rule Id="CA2208" Action="None" />
+    <Rule Id="CA2210" Action="None" />
+    <Rule Id="CA2211" Action="None" />
+    <Rule Id="CA2212" Action="None" />
+    <Rule Id="CA2213" Action="None" />
+    <Rule Id="CA2214" Action="None" />
+    <Rule Id="CA2215" Action="None" />
+    <Rule Id="CA2216" Action="None" />
+    <Rule Id="CA2217" Action="None" />
+    <Rule Id="CA2218" Action="None" />
+    <Rule Id="CA2219" Action="None" />
+    <Rule Id="CA2220" Action="None" />
+    <Rule Id="CA2221" Action="None" />
+    <Rule Id="CA2222" Action="None" />
+    <Rule Id="CA2223" Action="None" />
+    <Rule Id="CA2224" Action="None" />
+    <Rule Id="CA2225" Action="None" />
+    <Rule Id="CA2226" Action="None" />
+    <Rule Id="CA2227" Action="None" />
+    <Rule Id="CA2228" Action="None" />
+    <Rule Id="CA2229" Action="None" />
+    <Rule Id="CA2230" Action="None" />
+    <Rule Id="CA2231" Action="None" />
+    <Rule Id="CA2232" Action="None" />
+    <Rule Id="CA2233" Action="None" />
+    <Rule Id="CA2234" Action="None" />
+    <Rule Id="CA2235" Action="None" />
+    <Rule Id="CA2236" Action="None" />
+    <Rule Id="CA2237" Action="None" />
+    <Rule Id="CA2238" Action="None" />
+    <Rule Id="CA2239" Action="None" />
+    <Rule Id="CA2240" Action="None" />
+    <Rule Id="CA2241" Action="None" />
+    <Rule Id="CA2242" Action="None" />
+    <Rule Id="CA2243" Action="None" />
+  </Rules>
+</RuleSet>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/NullValueHandling.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/NullValueHandling.cs
new file mode 100644 (file)
index 0000000..09fb8c6
--- /dev/null
@@ -0,0 +1,47 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Specifies null value handling options for the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public enum NullValueHandling
+  {
+    /// <summary>
+    /// Include null values when serializing and deserializing objects.
+    /// </summary>
+    Include = 0,
+    /// <summary>
+    /// Ignore null values when serializing and deserializing objects.
+    /// </summary>
+    Ignore = 1
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/ObjectCreationHandling.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/ObjectCreationHandling.cs
new file mode 100644 (file)
index 0000000..dc22666
--- /dev/null
@@ -0,0 +1,51 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Specifies how object creation is handled by the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public enum ObjectCreationHandling
+  {
+    /// <summary>
+    /// Reuse existing objects, create new objects when needed.
+    /// </summary>
+    Auto = 0,
+    /// <summary>
+    /// Only reuse existing objects.
+    /// </summary>
+    Reuse = 1,
+    /// <summary>
+    /// Always create new objects.
+    /// </summary>
+    Replace = 2
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/PreserveReferencesHandling.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/PreserveReferencesHandling.cs
new file mode 100644 (file)
index 0000000..f74d15c
--- /dev/null
@@ -0,0 +1,55 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Specifies reference handling options for the <see cref="JsonSerializer"/>.
+  /// </summary>
+  [Flags]
+  public enum PreserveReferencesHandling
+  {
+    /// <summary>
+    /// Do not preserve references when serializing types.
+    /// </summary>
+    None = 0,
+    /// <summary>
+    /// Preserve references when serializing into a JSON object structure.
+    /// </summary>
+    Objects = 1,
+    /// <summary>
+    /// Preserve references when serializing into a JSON array structure.
+    /// </summary>
+    Arrays = 2,
+    /// <summary>
+    /// Preserve references when serializing.
+    /// </summary>
+    All = Objects | Arrays
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs
new file mode 100644 (file)
index 0000000..14c7126
--- /dev/null
@@ -0,0 +1,116 @@
+#region License
+// Copyright 2006 James Newton-King
+// http://www.newtonsoft.com
+//
+// This work is licensed under the Creative Commons Attribution 2.5 License
+// http://creativecommons.org/licenses/by/2.5/
+//
+// You are free:
+//    * to copy, distribute, display, and perform the work
+//    * to make derivative works
+//    * to make commercial use of the work
+//
+// Under the following conditions:
+//    * You must attribute the work in the manner specified by the author or licensor:
+//          - If you find this component useful a link to http://www.newtonsoft.com would be appreciated.
+//    * For any reuse or distribution, you must make clear to others the license terms of this work.
+//    * Any of these conditions can be waived if you get permission from the copyright holder.
+#endregion
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Security;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+#if WINDOWS_PHONE
+[assembly: AssemblyTitle("Newtonsoft Json.NET Windows Phone")]
+#elif SILVERLIGHT
+[assembly: AssemblyTitle("Newtonsoft Json.NET Silverlight")]
+#elif PocketPC
+[assembly: AssemblyTitle("Newtonsoft Json.NET Compact")]
+#elif NET20
+[assembly: AssemblyTitle("Newtonsoft Json.NET .NET 2.0")]
+[assembly: AllowPartiallyTrustedCallers]
+#elif NET35
+[assembly: AssemblyTitle("Newtonsoft Json.NET .NET 3.5")]
+[assembly: AllowPartiallyTrustedCallers]
+#else
+[assembly: AssemblyTitle("Newtonsoft Json.NET")]
+[assembly: AllowPartiallyTrustedCallers]
+#endif
+
+#if !SIGNED
+
+#if WINDOWS_PHONE
+[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests.WindowsPhone")]
+#elif SILVERLIGHT
+[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests.Silverlight")]
+#elif PocketPC
+[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests.Compact")]
+#elif NET20
+[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests.Net20")]
+#elif NET35
+[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests.Net35")]
+#else
+[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests")]
+#endif
+
+#else
+
+#if WINDOWS_PHONE
+[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests.WindowsPhone, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")]
+#elif SILVERLIGHT
+[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests.Silverlight, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")]
+#elif PocketPC
+[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests.Compact, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")]
+#elif NET20
+[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests.Net20, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")]
+#elif NET35
+[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests.Net35, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")]
+#else
+[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")]
+#endif
+
+#endif
+
+
+[assembly: InternalsVisibleTo("Newtonsoft.Json.Dynamic, PublicKey=0024000004800000940000000602000000240000525341310004000001000100cbd8d53b9d7de30f1f1278f636ec462cf9c254991291e66ebb157a885638a517887633b898ccbcf0d5c5ff7be85a6abe9e765d0ac7cd33c68dac67e7e64530e8222101109f154ab14a941c490ac155cd1d4fcba0fabb49016b4ef28593b015cab5937da31172f03f67d09edda404b88a60023f062ae71d0b2e4438b74cc11dc9")]
+
+
+
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Newtonsoft")]
+[assembly: AssemblyProduct("Newtonsoft Json.NET")]
+[assembly: AssemblyCopyright("Copyright © Newtonsoft 2008")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM componenets.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("9ca358aa-317b-4925-8ada-4a29e943a363")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("4.0.2.0")]
+#if !PocketPC
+[assembly: AssemblyFileVersion("4.0.2.13623")]
+#endif
+
+[assembly: CLSCompliant(true)]
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/ReferenceLoopHandling.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/ReferenceLoopHandling.cs
new file mode 100644 (file)
index 0000000..01d03b1
--- /dev/null
@@ -0,0 +1,50 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Specifies reference loop handling options for the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public enum ReferenceLoopHandling
+  {
+    /// <summary>
+    /// Throw a <see cref="JsonSerializationException"/> when a loop is encountered.
+    /// </summary>
+    Error = 0,
+    /// <summary>
+    /// Ignore loop references and do not serialize.
+    /// </summary>
+    Ignore = 1,
+    /// <summary>
+    /// Serialize loop references.
+    /// </summary>
+    Serialize = 2
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Required.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Required.cs
new file mode 100644 (file)
index 0000000..1db6bfa
--- /dev/null
@@ -0,0 +1,21 @@
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Indicating whether a property is required.
+  /// </summary>
+  public enum Required
+  {
+    /// <summary>
+    /// The property is not required. The default state.
+    /// </summary>
+    Default,
+    /// <summary>
+    /// The property must be defined in JSON but can be a null value.
+    /// </summary>
+    AllowNull,
+    /// <summary>
+    /// The property must be defined in JSON and cannot be a null value.
+    /// </summary>
+    Always
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/Extensions.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/Extensions.cs
new file mode 100644 (file)
index 0000000..4784b43
--- /dev/null
@@ -0,0 +1,88 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Schema
+{
+  /// <summary>
+  /// Contains the JSON schema extension methods.
+  /// </summary>
+  public static class Extensions
+  {
+    /// <summary>
+    /// Determines whether the <see cref="JToken"/> is valid.
+    /// </summary>
+    /// <param name="source">The source <see cref="JToken"/> to test.</param>
+    /// <param name="schema">The schema to test with.</param>
+    /// <returns>
+    ///        <c>true</c> if the specified <see cref="JToken"/> is valid; otherwise, <c>false</c>.
+    /// </returns>
+    public static bool IsValid(this JToken source, JsonSchema schema)
+    {
+      bool valid = true;
+      source.Validate(schema, (sender, args) => { valid = false; });
+      return valid;
+    }
+
+    /// <summary>
+    /// Validates the specified <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="source">The source <see cref="JToken"/> to test.</param>
+    /// <param name="schema">The schema to test with.</param>
+    public static void Validate(this JToken source, JsonSchema schema)
+    {
+      source.Validate(schema, null);
+    }
+
+    /// <summary>
+    /// Validates the specified <see cref="JToken"/>.
+    /// </summary>
+    /// <param name="source">The source <see cref="JToken"/> to test.</param>
+    /// <param name="schema">The schema to test with.</param>
+    /// <param name="validationEventHandler">The validation event handler.</param>
+    public static void Validate(this JToken source, JsonSchema schema, ValidationEventHandler validationEventHandler)
+    {
+      ValidationUtils.ArgumentNotNull(source, "source");
+      ValidationUtils.ArgumentNotNull(schema, "schema");
+
+      using (JsonValidatingReader reader = new JsonValidatingReader(source.CreateReader()))
+      {
+        reader.Schema = schema;
+        if (validationEventHandler != null)
+          reader.ValidationEventHandler += validationEventHandler;
+
+        while (reader.Read())
+        {
+        }
+      }
+    }
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchema.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchema.cs
new file mode 100644 (file)
index 0000000..d016538
--- /dev/null
@@ -0,0 +1,299 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.IO;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Utilities;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Schema
+{
+  /// <summary>
+  /// An in-memory representation of a JSON Schema.
+  /// </summary>
+  public class JsonSchema
+  {
+    /// <summary>
+    /// Gets or sets the id.
+    /// </summary>
+    public string Id { get; set; }
+    /// <summary>
+    /// Gets or sets the title.
+    /// </summary>
+    public string Title { get; set; }
+    /// <summary>
+    /// Gets or sets whether the object is required.
+    /// </summary>
+    public bool? Required { get; set; }
+    /// <summary>
+    /// Gets or sets whether the object is read only.
+    /// </summary>
+    public bool? ReadOnly { get; set; }
+    /// <summary>
+    /// Gets or sets whether the object is visible to users.
+    /// </summary>
+    public bool? Hidden { get; set; }
+    /// <summary>
+    /// Gets or sets whether the object is transient.
+    /// </summary>
+    public bool? Transient { get; set; }
+    /// <summary>
+    /// Gets or sets the description of the object.
+    /// </summary>
+    public string Description { get; set; }
+    /// <summary>
+    /// Gets or sets the types of values allowed by the object.
+    /// </summary>
+    /// <value>The type.</value>
+    public JsonSchemaType? Type { get; set; }
+    /// <summary>
+    /// Gets or sets the pattern.
+    /// </summary>
+    /// <value>The pattern.</value>
+    public string Pattern { get; set; }
+    /// <summary>
+    /// Gets or sets the minimum length.
+    /// </summary>
+    /// <value>The minimum length.</value>
+    public int? MinimumLength { get; set; }
+    /// <summary>
+    /// Gets or sets the maximum length.
+    /// </summary>
+    /// <value>The maximum length.</value>
+    public int? MaximumLength { get; set; }
+    /// <summary>
+    /// Gets or sets a number that the value should be divisble by.
+    /// </summary>
+    /// <value>A number that the value should be divisble by.</value>
+    public double? DivisibleBy { get; set; }
+    /// <summary>
+    /// Gets or sets the minimum.
+    /// </summary>
+    /// <value>The minimum.</value>
+    public double? Minimum { get; set; }
+    /// <summary>
+    /// Gets or sets the maximum.
+    /// </summary>
+    /// <value>The maximum.</value>
+    public double? Maximum { get; set; }
+    /// <summary>
+    /// Gets or sets a flag indicating whether the value can not equal the number defined by the "minimum" attribute.
+    /// </summary>
+    /// <value>A flag indicating whether the value can not equal the number defined by the "minimum" attribute.</value>
+    public bool? ExclusiveMinimum { get; set; }
+    /// <summary>
+    /// Gets or sets a flag indicating whether the value can not equal the number defined by the "maximum" attribute.
+    /// </summary>
+    /// <value>A flag indicating whether the value can not equal the number defined by the "maximum" attribute.</value>
+    public bool? ExclusiveMaximum { get; set; }
+    /// <summary>
+    /// Gets or sets the minimum number of items.
+    /// </summary>
+    /// <value>The minimum number of items.</value>
+    public int? MinimumItems { get; set; }
+    /// <summary>
+    /// Gets or sets the maximum number of items.
+    /// </summary>
+    /// <value>The maximum number of items.</value>
+    public int? MaximumItems { get; set; }
+    /// <summary>
+    /// Gets or sets the <see cref="JsonSchema"/> of items.
+    /// </summary>
+    /// <value>The <see cref="JsonSchema"/> of items.</value>
+    public IList<JsonSchema> Items { get; set; }
+    /// <summary>
+    /// Gets or sets the <see cref="JsonSchema"/> of properties.
+    /// </summary>
+    /// <value>The <see cref="JsonSchema"/> of properties.</value>
+    public IDictionary<string, JsonSchema> Properties { get; set; }
+    /// <summary>
+    /// Gets or sets the <see cref="JsonSchema"/> of additional properties.
+    /// </summary>
+    /// <value>The <see cref="JsonSchema"/> of additional properties.</value>
+    public JsonSchema AdditionalProperties { get; set; }
+    /// <summary>
+    /// Gets or sets the pattern properties.
+    /// </summary>
+    /// <value>The pattern properties.</value>
+    public IDictionary<string, JsonSchema> PatternProperties { get; set; }
+    /// <summary>
+    /// Gets or sets a value indicating whether additional properties are allowed.
+    /// </summary>
+    /// <value>
+    ///        <c>true</c> if additional properties are allowed; otherwise, <c>false</c>.
+    /// </value>
+    public bool AllowAdditionalProperties { get; set; }
+    /// <summary>
+    /// Gets or sets the required property if this property is present.
+    /// </summary>
+    /// <value>The required property if this property is present.</value>
+    public string Requires { get; set; }
+    /// <summary>
+    /// Gets or sets the identity.
+    /// </summary>
+    /// <value>The identity.</value>
+    public IList<string> Identity { get; set; }
+    /// <summary>
+    /// Gets or sets the a collection of valid enum values allowed.
+    /// </summary>
+    /// <value>A collection of valid enum values allowed.</value>
+    public IList<JToken> Enum { get; set; }
+    /// <summary>
+    /// Gets or sets a collection of options.
+    /// </summary>
+    /// <value>A collection of options.</value>
+    public IDictionary<JToken, string> Options { get; set; }
+    /// <summary>
+    /// Gets or sets disallowed types.
+    /// </summary>
+    /// <value>The disallow types.</value>
+    public JsonSchemaType? Disallow { get; set; }
+    /// <summary>
+    /// Gets or sets the default value.
+    /// </summary>
+    /// <value>The default value.</value>
+    public JToken Default { get; set; }
+    /// <summary>
+    /// Gets or sets the extend <see cref="JsonSchema"/>.
+    /// </summary>
+    /// <value>The extended <see cref="JsonSchema"/>.</value>
+    public JsonSchema Extends { get; set; }
+    /// <summary>
+    /// Gets or sets the format.
+    /// </summary>
+    /// <value>The format.</value>
+    public string Format { get; set; }
+
+    private readonly string _internalId = Guid.NewGuid().ToString("N");
+
+    internal string InternalId
+    {
+      get { return _internalId; }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonSchema"/> class.
+    /// </summary>
+    public JsonSchema()
+    {
+      AllowAdditionalProperties = true;
+    }
+
+    /// <summary>
+    /// Reads a <see cref="JsonSchema"/> from the specified <see cref="JsonReader"/>.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> containing the JSON Schema to read.</param>
+    /// <returns>The <see cref="JsonSchema"/> object representing the JSON Schema.</returns>
+    public static JsonSchema Read(JsonReader reader)
+    {
+      return Read(reader, new JsonSchemaResolver());
+    }
+
+    /// <summary>
+    /// Reads a <see cref="JsonSchema"/> from the specified <see cref="JsonReader"/>.
+    /// </summary>
+    /// <param name="reader">The <see cref="JsonReader"/> containing the JSON Schema to read.</param>
+    /// <param name="resolver">The <see cref="JsonSchemaResolver"/> to use when resolving schema references.</param>
+    /// <returns>The <see cref="JsonSchema"/> object representing the JSON Schema.</returns>
+    public static JsonSchema Read(JsonReader reader, JsonSchemaResolver resolver)
+    {
+      ValidationUtils.ArgumentNotNull(reader, "reader");
+      ValidationUtils.ArgumentNotNull(resolver, "resolver");
+
+      JsonSchemaBuilder builder = new JsonSchemaBuilder(resolver);
+      return builder.Parse(reader);
+    }
+
+    /// <summary>
+    /// Load a <see cref="JsonSchema"/> from a string that contains schema JSON.
+    /// </summary>
+    /// <param name="json">A <see cref="String"/> that contains JSON.</param>
+    /// <returns>A <see cref="JsonSchema"/> populated from the string that contains JSON.</returns>
+    public static JsonSchema Parse(string json)
+    {
+      return Parse(json, new JsonSchemaResolver());
+    }
+
+    /// <summary>
+    /// Parses the specified json.
+    /// </summary>
+    /// <param name="json">The json.</param>
+    /// <param name="resolver">The resolver.</param>
+    /// <returns>A <see cref="JsonSchema"/> populated from the string that contains JSON.</returns>
+    public static JsonSchema Parse(string json, JsonSchemaResolver resolver)
+    {
+      ValidationUtils.ArgumentNotNull(json, "json");
+
+      JsonReader reader = new JsonTextReader(new StringReader(json));
+
+      return Read(reader, resolver);
+    }
+
+    /// <summary>
+    /// Writes this schema to a <see cref="JsonWriter"/>.
+    /// </summary>
+    /// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param>
+    public void WriteTo(JsonWriter writer)
+    {
+      WriteTo(writer, new JsonSchemaResolver());
+    }
+
+    /// <summary>
+    /// Writes this schema to a <see cref="JsonWriter"/> using the specified <see cref="JsonSchemaResolver"/>.
+    /// </summary>
+    /// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param>
+    /// <param name="resolver">The resolver used.</param>
+    public void WriteTo(JsonWriter writer, JsonSchemaResolver resolver)
+    {
+      ValidationUtils.ArgumentNotNull(writer, "writer");
+      ValidationUtils.ArgumentNotNull(resolver, "resolver");
+
+      JsonSchemaWriter schemaWriter = new JsonSchemaWriter(writer, resolver);
+      schemaWriter.WriteSchema(this);
+    }
+
+    /// <summary>
+    /// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
+    /// </summary>
+    /// <returns>
+    /// A <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
+    /// </returns>
+    public override string ToString()
+    {
+      StringWriter writer = new StringWriter(CultureInfo.InvariantCulture);
+      JsonTextWriter jsonWriter = new JsonTextWriter(writer);
+      jsonWriter.Formatting = Formatting.Indented;
+
+      WriteTo(jsonWriter);
+
+      return writer.ToString();
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaBuilder.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaBuilder.cs
new file mode 100644 (file)
index 0000000..702ec1e
--- /dev/null
@@ -0,0 +1,423 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Globalization;
+using Newtonsoft.Json.Utilities;
+using Newtonsoft.Json.Linq;
+
+namespace Newtonsoft.Json.Schema
+{
+  internal class JsonSchemaBuilder
+  {
+    private JsonReader _reader;
+    private readonly IList<JsonSchema> _stack;
+    private readonly JsonSchemaResolver _resolver;
+    private JsonSchema _currentSchema;
+
+    private void Push(JsonSchema value)
+    {
+      _currentSchema = value;
+      _stack.Add(value);
+      _resolver.LoadedSchemas.Add(value);
+    }
+
+    private JsonSchema Pop()
+    {
+      JsonSchema poppedSchema = _currentSchema;
+      _stack.RemoveAt(_stack.Count - 1);
+      _currentSchema = _stack.LastOrDefault();
+
+      return poppedSchema;
+    }
+
+    private JsonSchema CurrentSchema
+    {
+      get { return _currentSchema; }
+    }
+
+    public JsonSchemaBuilder(JsonSchemaResolver resolver)
+    {
+      _stack = new List<JsonSchema>();
+      _resolver = resolver;
+    }
+
+    internal JsonSchema Parse(JsonReader reader)
+    {
+      _reader = reader;
+
+      if (reader.TokenType == JsonToken.None)
+        _reader.Read();
+
+      return BuildSchema();
+    }
+
+    private JsonSchema BuildSchema()
+    {
+      if (_reader.TokenType != JsonToken.StartObject)
+        throw new Exception("Expected StartObject while parsing schema object, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType));
+
+      _reader.Read();
+      // empty schema object
+      if (_reader.TokenType == JsonToken.EndObject)
+      {
+        Push(new JsonSchema());
+        return Pop();
+      }
+
+      string propertyName = Convert.ToString(_reader.Value, CultureInfo.InvariantCulture);
+      _reader.Read();
+      
+      // schema reference
+      if (propertyName == JsonSchemaConstants.ReferencePropertyName)
+      {
+        string id = (string)_reader.Value;
+        _reader.Read();
+        JsonSchema referencedSchema = _resolver.GetSchema(id);
+        if (referencedSchema == null)
+          throw new Exception("Could not resolve schema reference for Id '{0}'.".FormatWith(CultureInfo.InvariantCulture, id));
+
+        return referencedSchema;
+      }
+
+      // regular ol' schema object
+      Push(new JsonSchema());
+
+      ProcessSchemaProperty(propertyName);
+
+      while (_reader.Read() && _reader.TokenType != JsonToken.EndObject)
+      {
+        propertyName = Convert.ToString(_reader.Value, CultureInfo.InvariantCulture);
+        _reader.Read();
+
+        ProcessSchemaProperty(propertyName);
+      }
+
+      return Pop();
+    }
+
+    private void ProcessSchemaProperty(string propertyName)
+    {
+      switch (propertyName)
+      {
+        case JsonSchemaConstants.TypePropertyName:
+          CurrentSchema.Type = ProcessType();
+          break;
+        case JsonSchemaConstants.IdPropertyName:
+          CurrentSchema.Id = (string) _reader.Value;
+          break;
+        case JsonSchemaConstants.TitlePropertyName:
+          CurrentSchema.Title = (string) _reader.Value;
+          break;
+        case JsonSchemaConstants.DescriptionPropertyName:
+          CurrentSchema.Description = (string)_reader.Value;
+          break;
+        case JsonSchemaConstants.PropertiesPropertyName:
+          ProcessProperties();
+          break;
+        case JsonSchemaConstants.ItemsPropertyName:
+          ProcessItems();
+          break;
+        case JsonSchemaConstants.AdditionalPropertiesPropertyName:
+          ProcessAdditionalProperties();
+          break;
+        case JsonSchemaConstants.PatternPropertiesPropertyName:
+          ProcessPatternProperties();
+          break;
+        case JsonSchemaConstants.RequiredPropertyName:
+          CurrentSchema.Required = (bool)_reader.Value;
+          break;
+        case JsonSchemaConstants.RequiresPropertyName:
+          CurrentSchema.Requires = (string) _reader.Value;
+          break;
+        case JsonSchemaConstants.IdentityPropertyName:
+          ProcessIdentity();
+          break;
+        case JsonSchemaConstants.MinimumPropertyName:
+          CurrentSchema.Minimum = Convert.ToDouble(_reader.Value, CultureInfo.InvariantCulture);
+          break;
+        case JsonSchemaConstants.MaximumPropertyName:
+          CurrentSchema.Maximum = Convert.ToDouble(_reader.Value, CultureInfo.InvariantCulture);
+          break;
+        case JsonSchemaConstants.ExclusiveMinimumPropertyName:
+          CurrentSchema.ExclusiveMinimum = (bool)_reader.Value;
+          break;
+        case JsonSchemaConstants.ExclusiveMaximumPropertyName:
+          CurrentSchema.ExclusiveMaximum = (bool)_reader.Value;
+          break;
+        case JsonSchemaConstants.MaximumLengthPropertyName:
+          CurrentSchema.MaximumLength = Convert.ToInt32(_reader.Value, CultureInfo.InvariantCulture);
+          break;
+        case JsonSchemaConstants.MinimumLengthPropertyName:
+          CurrentSchema.MinimumLength = Convert.ToInt32(_reader.Value, CultureInfo.InvariantCulture);
+          break;
+        case JsonSchemaConstants.MaximumItemsPropertyName:
+          CurrentSchema.MaximumItems = Convert.ToInt32(_reader.Value, CultureInfo.InvariantCulture);
+          break;
+        case JsonSchemaConstants.MinimumItemsPropertyName:
+          CurrentSchema.MinimumItems = Convert.ToInt32(_reader.Value, CultureInfo.InvariantCulture);
+          break;
+        case JsonSchemaConstants.DivisibleByPropertyName:
+          CurrentSchema.DivisibleBy = Convert.ToDouble(_reader.Value, CultureInfo.InvariantCulture);
+          break;
+        case JsonSchemaConstants.DisallowPropertyName:
+          CurrentSchema.Disallow = ProcessType();
+          break;
+        case JsonSchemaConstants.DefaultPropertyName:
+          ProcessDefault();
+          break;
+        case JsonSchemaConstants.HiddenPropertyName:
+          CurrentSchema.Hidden = (bool) _reader.Value;
+          break;
+        case JsonSchemaConstants.ReadOnlyPropertyName:
+          CurrentSchema.ReadOnly = (bool) _reader.Value;
+          break;
+        case JsonSchemaConstants.FormatPropertyName:
+          CurrentSchema.Format = (string) _reader.Value;
+          break;
+        case JsonSchemaConstants.PatternPropertyName:
+          CurrentSchema.Pattern = (string) _reader.Value;
+          break;
+        case JsonSchemaConstants.OptionsPropertyName:
+          ProcessOptions();
+          break;
+        case JsonSchemaConstants.EnumPropertyName:
+          ProcessEnum();
+          break;
+        case JsonSchemaConstants.ExtendsPropertyName:
+          ProcessExtends();
+          break;
+        default:
+          _reader.Skip();
+          break;
+      }
+    }
+
+    private void ProcessExtends()
+    {
+      CurrentSchema.Extends = BuildSchema();
+    }
+
+    private void ProcessEnum()
+    {
+      if (_reader.TokenType != JsonToken.StartArray)
+        throw new Exception("Expected StartArray token while parsing enum values, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType));
+
+      CurrentSchema.Enum = new List<JToken>();
+
+      while (_reader.Read() && _reader.TokenType != JsonToken.EndArray)
+      {
+        JToken value = JToken.ReadFrom(_reader);
+        CurrentSchema.Enum.Add(value);
+      }
+    }
+
+    private void ProcessOptions()
+    {
+      CurrentSchema.Options = new Dictionary<JToken, string>(new JTokenEqualityComparer());
+
+      switch (_reader.TokenType)
+      {
+        case JsonToken.StartArray:
+          while (_reader.Read() && _reader.TokenType != JsonToken.EndArray)
+          {
+            if (_reader.TokenType != JsonToken.StartObject)
+              throw new Exception("Expect object token, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType));
+
+            string label = null;
+            JToken value = null;
+
+            while (_reader.Read() && _reader.TokenType != JsonToken.EndObject)
+            {
+              string propertyName = Convert.ToString(_reader.Value, CultureInfo.InvariantCulture);
+              _reader.Read();
+
+              switch (propertyName)
+              {
+                case JsonSchemaConstants.OptionValuePropertyName:
+                  value = JToken.ReadFrom(_reader);
+                  break;
+                case JsonSchemaConstants.OptionLabelPropertyName:
+                  label = (string) _reader.Value;
+                  break;
+                default:
+                  throw new Exception("Unexpected property in JSON schema option: {0}.".FormatWith(CultureInfo.InvariantCulture, propertyName));
+              }
+            }
+
+            if (value == null)
+              throw new Exception("No value specified for JSON schema option.");
+
+            if (CurrentSchema.Options.ContainsKey(value))
+              throw new Exception("Duplicate value in JSON schema option collection: {0}".FormatWith(CultureInfo.InvariantCulture, value));
+
+            CurrentSchema.Options.Add(value, label);
+          }
+          break;
+        default:
+          throw new Exception("Expected array token, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType));
+      }
+    }
+
+    private void ProcessDefault()
+    {
+      CurrentSchema.Default = JToken.ReadFrom(_reader);
+    }
+
+    private void ProcessIdentity()
+    {
+      CurrentSchema.Identity = new List<string>();
+
+      switch (_reader.TokenType)
+      {
+        case JsonToken.String:
+          CurrentSchema.Identity.Add(_reader.Value.ToString());
+          break;
+        case JsonToken.StartArray:
+          while (_reader.Read() && _reader.TokenType != JsonToken.EndArray)
+          {
+            if (_reader.TokenType != JsonToken.String)
+              throw new Exception("Exception JSON property name string token, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType));
+
+            CurrentSchema.Identity.Add(_reader.Value.ToString());
+          }
+          break;
+        default:
+          throw new Exception("Expected array or JSON property name string token, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType));
+      }
+    }
+
+    private void ProcessAdditionalProperties()
+    {
+      if (_reader.TokenType == JsonToken.Boolean)
+        CurrentSchema.AllowAdditionalProperties = (bool)_reader.Value;
+      else
+        CurrentSchema.AdditionalProperties = BuildSchema();
+    }
+
+    private void ProcessPatternProperties()
+    {
+      Dictionary<string, JsonSchema> patternProperties = new Dictionary<string, JsonSchema>();
+
+      if (_reader.TokenType != JsonToken.StartObject)
+        throw new Exception("Expected start object token.");
+
+      while (_reader.Read() && _reader.TokenType != JsonToken.EndObject)
+      {
+        string propertyName = Convert.ToString(_reader.Value, CultureInfo.InvariantCulture);
+        _reader.Read();
+
+        if (patternProperties.ContainsKey(propertyName))
+          throw new Exception("Property {0} has already been defined in schema.".FormatWith(CultureInfo.InvariantCulture, propertyName));
+
+        patternProperties.Add(propertyName, BuildSchema());
+      }
+
+      CurrentSchema.PatternProperties = patternProperties;
+    }
+
+    private void ProcessItems()
+    {
+      CurrentSchema.Items = new List<JsonSchema>();
+
+      switch (_reader.TokenType)
+      {
+        case JsonToken.StartObject:
+          CurrentSchema.Items.Add(BuildSchema());
+          break;
+        case JsonToken.StartArray:
+          while (_reader.Read() && _reader.TokenType != JsonToken.EndArray)
+          {
+            CurrentSchema.Items.Add(BuildSchema());
+          }
+          break;
+        default:
+          throw new Exception("Expected array or JSON schema object token, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType));
+      }
+    }
+
+    private void ProcessProperties()
+    {
+      IDictionary<string, JsonSchema> properties = new Dictionary<string, JsonSchema>();
+
+      if (_reader.TokenType != JsonToken.StartObject)
+        throw new Exception("Expected StartObject token while parsing schema properties, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType));
+
+      while (_reader.Read() && _reader.TokenType != JsonToken.EndObject)
+      {
+        string propertyName = Convert.ToString(_reader.Value, CultureInfo.InvariantCulture);
+        _reader.Read();
+
+        if (properties.ContainsKey(propertyName))
+          throw new Exception("Property {0} has already been defined in schema.".FormatWith(CultureInfo.InvariantCulture, propertyName));
+
+        properties.Add(propertyName, BuildSchema());
+      }
+
+      CurrentSchema.Properties = properties;
+    }
+
+    private JsonSchemaType? ProcessType()
+    {
+      switch (_reader.TokenType)
+      {
+        case JsonToken.String:
+          return MapType(_reader.Value.ToString());
+        case JsonToken.StartArray:
+          // ensure type is in blank state before ORing values
+          JsonSchemaType? type = JsonSchemaType.None;
+
+          while (_reader.Read() && _reader.TokenType != JsonToken.EndArray)
+          {
+            if (_reader.TokenType != JsonToken.String)
+              throw new Exception("Exception JSON schema type string token, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType));
+
+            type = type | MapType(_reader.Value.ToString());
+          }
+
+          return type;
+        default:
+          throw new Exception("Expected array or JSON schema type string token, got {0}.".FormatWith(CultureInfo.InvariantCulture, _reader.TokenType));
+      }
+    }
+
+    internal static JsonSchemaType MapType(string type)
+    {
+      JsonSchemaType mappedType;
+      if (!JsonSchemaConstants.JsonSchemaTypeMapping.TryGetValue(type, out mappedType))
+        throw new Exception("Invalid JSON schema type: {0}".FormatWith(CultureInfo.InvariantCulture, type));
+
+      return mappedType;
+    }
+
+    internal static string MapType(JsonSchemaType type)
+    {
+      return JsonSchemaConstants.JsonSchemaTypeMapping.Single(kv => kv.Value == type).Key;
+    }
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaConstants.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaConstants.cs
new file mode 100644 (file)
index 0000000..b9f58ff
--- /dev/null
@@ -0,0 +1,83 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Schema
+{
+  internal static class JsonSchemaConstants
+  {
+    public const string TypePropertyName = "type";
+    public const string PropertiesPropertyName = "properties";
+    public const string ItemsPropertyName = "items";
+    public const string RequiredPropertyName = "required";
+    public const string PatternPropertiesPropertyName = "patternProperties";
+    public const string AdditionalPropertiesPropertyName = "additionalProperties";
+    public const string RequiresPropertyName = "requires";
+    public const string IdentityPropertyName = "identity";
+    public const string MinimumPropertyName = "minimum";
+    public const string MaximumPropertyName = "maximum";
+    public const string ExclusiveMinimumPropertyName = "exclusiveMinimum";
+    public const string ExclusiveMaximumPropertyName = "exclusiveMaximum";
+    public const string MinimumItemsPropertyName = "minItems";
+    public const string MaximumItemsPropertyName = "maxItems";
+    public const string PatternPropertyName = "pattern";
+    public const string MaximumLengthPropertyName = "maxLength";
+    public const string MinimumLengthPropertyName = "minLength";
+    public const string EnumPropertyName = "enum";
+    public const string OptionsPropertyName = "options";
+    public const string ReadOnlyPropertyName = "readonly";
+    public const string TitlePropertyName = "title";
+    public const string DescriptionPropertyName = "description";
+    public const string FormatPropertyName = "format";
+    public const string DefaultPropertyName = "default";
+    public const string TransientPropertyName = "transient";
+    public const string DivisibleByPropertyName = "divisibleBy";
+    public const string HiddenPropertyName = "hidden";
+    public const string DisallowPropertyName = "disallow";
+    public const string ExtendsPropertyName = "extends";
+    public const string IdPropertyName = "id";
+
+    public const string OptionValuePropertyName = "value";
+    public const string OptionLabelPropertyName = "label";
+
+    public const string ReferencePropertyName = "$ref";
+
+    public static readonly IDictionary<string, JsonSchemaType> JsonSchemaTypeMapping = new Dictionary<string, JsonSchemaType>()
+    {
+      {"string", JsonSchemaType.String},
+      {"object", JsonSchemaType.Object},
+      {"integer", JsonSchemaType.Integer},
+      {"number", JsonSchemaType.Float},
+      {"null", JsonSchemaType.Null},
+      {"boolean", JsonSchemaType.Boolean},
+      {"array", JsonSchemaType.Array},
+      {"any", JsonSchemaType.Any}
+    };
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaException.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaException.cs
new file mode 100644 (file)
index 0000000..8a3872f
--- /dev/null
@@ -0,0 +1,83 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json.Schema
+{
+  /// <summary>
+  /// Returns detailed information about the schema exception.
+  /// </summary>
+  public class JsonSchemaException : Exception
+  {
+    /// <summary>
+    /// Gets the line number indicating where the error occurred.
+    /// </summary>
+    /// <value>The line number indicating where the error occurred.</value>
+    public int LineNumber { get; private set; }
+
+
+    /// <summary>
+    /// Gets the line position indicating where the error occurred.
+    /// </summary>
+    /// <value>The line position indicating where the error occurred.</value>
+    public int LinePosition { get; private set; }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonSchemaException"/> class.
+    /// </summary>
+    public JsonSchemaException()
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonSchemaException"/> class
+    /// with a specified error message.
+    /// </summary>
+    /// <param name="message">The error message that explains the reason for the exception.</param>
+    public JsonSchemaException(string message)
+      : base(message)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonSchemaException"/> class
+    /// with a specified error message and a reference to the inner exception that is the cause of this exception.
+    /// </summary>
+    /// <param name="message">The error message that explains the reason for the exception.</param>
+    /// <param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
+    public JsonSchemaException(string message, Exception innerException)
+      : base(message, innerException)
+    {
+    }
+
+    internal JsonSchemaException(string message, Exception innerException, int lineNumber, int linePosition)
+      : base(message, innerException)
+    {
+      LineNumber = lineNumber;
+      LinePosition = linePosition;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaGenerator.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaGenerator.cs
new file mode 100644 (file)
index 0000000..3ead320
--- /dev/null
@@ -0,0 +1,442 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Linq;
+using System.Globalization;
+using System.ComponentModel;
+using System.Collections.Generic;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Utilities;
+using Newtonsoft.Json.Serialization;
+
+namespace Newtonsoft.Json.Schema
+{
+  /// <summary>
+  /// Generates a <see cref="JsonSchema"/> from a specified <see cref="Type"/>.
+  /// </summary>
+  public class JsonSchemaGenerator
+  {
+    /// <summary>
+    /// Gets or sets how undefined schemas are handled by the serializer.
+    /// </summary>
+    public UndefinedSchemaIdHandling UndefinedSchemaIdHandling { get; set; }
+
+    private IContractResolver _contractResolver;
+    /// <summary>
+    /// Gets or sets the contract resolver.
+    /// </summary>
+    /// <value>The contract resolver.</value>
+    public IContractResolver ContractResolver
+    {
+      get
+      {
+        if (_contractResolver == null)
+          return DefaultContractResolver.Instance;
+
+        return _contractResolver;
+      }
+      set { _contractResolver = value; }
+    }
+
+    private class TypeSchema
+    {
+      public Type Type { get; private set; }
+      public JsonSchema Schema { get; private set;}
+
+      public TypeSchema(Type type, JsonSchema schema)
+      {
+        ValidationUtils.ArgumentNotNull(type, "type");
+        ValidationUtils.ArgumentNotNull(schema, "schema");
+
+        Type = type;
+        Schema = schema;
+      }
+    }
+
+    private JsonSchemaResolver _resolver;
+    private IList<TypeSchema> _stack = new List<TypeSchema>();
+    private JsonSchema _currentSchema;
+
+    private JsonSchema CurrentSchema
+    {
+      get { return _currentSchema; }
+    }
+
+    private void Push(TypeSchema typeSchema)
+    {
+      _currentSchema = typeSchema.Schema;
+      _stack.Add(typeSchema);
+      _resolver.LoadedSchemas.Add(typeSchema.Schema);
+    }
+
+    private TypeSchema Pop()
+    {
+      TypeSchema popped = _stack[_stack.Count - 1];
+      _stack.RemoveAt(_stack.Count - 1);
+      TypeSchema newValue = _stack.LastOrDefault();
+      if (newValue != null)
+      {
+        _currentSchema = newValue.Schema;
+      }
+      else
+      {
+        _currentSchema = null;
+      }
+
+      return popped;
+    }
+
+    /// <summary>
+    /// Generate a <see cref="JsonSchema"/> from the specified type.
+    /// </summary>
+    /// <param name="type">The type to generate a <see cref="JsonSchema"/> from.</param>
+    /// <returns>A <see cref="JsonSchema"/> generated from the specified type.</returns>
+    public JsonSchema Generate(Type type)
+    {
+      return Generate(type, new JsonSchemaResolver(), false);
+    }
+
+    /// <summary>
+    /// Generate a <see cref="JsonSchema"/> from the specified type.
+    /// </summary>
+    /// <param name="type">The type to generate a <see cref="JsonSchema"/> from.</param>
+    /// <param name="resolver">The <see cref="JsonSchemaResolver"/> used to resolve schema references.</param>
+    /// <returns>A <see cref="JsonSchema"/> generated from the specified type.</returns>
+    public JsonSchema Generate(Type type, JsonSchemaResolver resolver)
+    {
+      return Generate(type, resolver, false);
+    }
+
+    /// <summary>
+    /// Generate a <see cref="JsonSchema"/> from the specified type.
+    /// </summary>
+    /// <param name="type">The type to generate a <see cref="JsonSchema"/> from.</param>
+    /// <param name="rootSchemaNullable">Specify whether the generated root <see cref="JsonSchema"/> will be nullable.</param>
+    /// <returns>A <see cref="JsonSchema"/> generated from the specified type.</returns>
+    public JsonSchema Generate(Type type, bool rootSchemaNullable)
+    {
+      return Generate(type, new JsonSchemaResolver(), rootSchemaNullable);
+    }
+
+    /// <summary>
+    /// Generate a <see cref="JsonSchema"/> from the specified type.
+    /// </summary>
+    /// <param name="type">The type to generate a <see cref="JsonSchema"/> from.</param>
+    /// <param name="resolver">The <see cref="JsonSchemaResolver"/> used to resolve schema references.</param>
+    /// <param name="rootSchemaNullable">Specify whether the generated root <see cref="JsonSchema"/> will be nullable.</param>
+    /// <returns>A <see cref="JsonSchema"/> generated from the specified type.</returns>
+    public JsonSchema Generate(Type type, JsonSchemaResolver resolver, bool rootSchemaNullable)
+    {
+      ValidationUtils.ArgumentNotNull(type, "type");
+      ValidationUtils.ArgumentNotNull(resolver, "resolver");
+
+      _resolver = resolver;
+
+      return GenerateInternal(type, (!rootSchemaNullable) ? Required.Always : Required.Default, false);
+    }
+
+    private string GetTitle(Type type)
+    {
+      JsonContainerAttribute containerAttribute = JsonTypeReflector.GetJsonContainerAttribute(type);
+
+      if (containerAttribute != null && !string.IsNullOrEmpty(containerAttribute.Title))
+        return containerAttribute.Title;
+
+      return null;
+    }
+
+    private string GetDescription(Type type)
+    {
+      JsonContainerAttribute containerAttribute = JsonTypeReflector.GetJsonContainerAttribute(type);
+
+      if (containerAttribute != null && !string.IsNullOrEmpty(containerAttribute.Description))
+        return containerAttribute.Description;
+
+#if !PocketPC
+      DescriptionAttribute descriptionAttribute = ReflectionUtils.GetAttribute<DescriptionAttribute>(type);
+      if (descriptionAttribute != null)
+        return descriptionAttribute.Description;
+#endif
+
+      return null;
+    }
+
+    private string GetTypeId(Type type, bool explicitOnly)
+    {
+      JsonContainerAttribute containerAttribute = JsonTypeReflector.GetJsonContainerAttribute(type);
+
+      if (containerAttribute != null && !string.IsNullOrEmpty(containerAttribute.Id))
+        return containerAttribute.Id;
+
+      if (explicitOnly)
+        return null;
+
+      switch (UndefinedSchemaIdHandling)
+      {
+        case UndefinedSchemaIdHandling.UseTypeName:
+          return type.FullName;
+        case UndefinedSchemaIdHandling.UseAssemblyQualifiedName:
+          return type.AssemblyQualifiedName;
+        default:
+          return null;
+      }
+    }
+
+    private JsonSchema GenerateInternal(Type type, Required valueRequired, bool required)
+    {
+      ValidationUtils.ArgumentNotNull(type, "type");
+
+      string resolvedId = GetTypeId(type, false);
+      string explicitId = GetTypeId(type, true);
+
+      if (!string.IsNullOrEmpty(resolvedId))
+      {
+        JsonSchema resolvedSchema = _resolver.GetSchema(resolvedId);
+        if (resolvedSchema != null)
+        {
+          // resolved schema is not null but referencing member allows nulls
+          // change resolved schema to allow nulls. hacky but what are ya gonna do?
+          if (valueRequired != Required.Always && !HasFlag(resolvedSchema.Type, JsonSchemaType.Null))
+            resolvedSchema.Type |= JsonSchemaType.Null;
+          if (required && resolvedSchema.Required != true)
+            resolvedSchema.Required = true;
+
+          return resolvedSchema;
+        }
+      }
+
+      // test for unresolved circular reference
+      if (_stack.Any(tc => tc.Type == type))
+      {
+        throw new Exception("Unresolved circular reference for type '{0}'. Explicitly define an Id for the type using a JsonObject/JsonArray attribute or automatically generate a type Id using the UndefinedSchemaIdHandling property.".FormatWith(CultureInfo.InvariantCulture, type));
+      }
+
+      JsonContract contract = ContractResolver.ResolveContract(type);
+      JsonConverter converter;
+      if ((converter = contract.Converter) != null || (converter = contract.InternalConverter) != null)
+      {
+        JsonSchema converterSchema = converter.GetSchema();
+        if (converterSchema != null)
+          return converterSchema;
+      }
+
+      Push(new TypeSchema(type, new JsonSchema()));
+
+      if (explicitId != null)
+        CurrentSchema.Id = explicitId;
+
+      if (required)
+        CurrentSchema.Required = true;
+      CurrentSchema.Title = GetTitle(type);
+      CurrentSchema.Description = GetDescription(type);
+
+      if (converter != null)
+      {
+        // todo: Add GetSchema to JsonConverter and use here?
+        CurrentSchema.Type = JsonSchemaType.Any;
+      }
+      else if (contract is JsonDictionaryContract)
+      {
+        CurrentSchema.Type = AddNullType(JsonSchemaType.Object, valueRequired);
+
+        Type keyType;
+        Type valueType;
+        ReflectionUtils.GetDictionaryKeyValueTypes(type, out keyType, out valueType);
+
+        if (keyType != null)
+        {
+          // can be converted to a string
+          if (typeof (IConvertible).IsAssignableFrom(keyType))
+          {
+            CurrentSchema.AdditionalProperties = GenerateInternal(valueType, Required.Default, false);
+          }
+        }
+      }
+      else if (contract is JsonArrayContract)
+      {
+        CurrentSchema.Type = AddNullType(JsonSchemaType.Array, valueRequired);
+
+        CurrentSchema.Id = GetTypeId(type, false);
+
+        JsonArrayAttribute arrayAttribute = JsonTypeReflector.GetJsonContainerAttribute(type) as JsonArrayAttribute;
+        bool allowNullItem = (arrayAttribute != null) ? arrayAttribute.AllowNullItems : true;
+
+        Type collectionItemType = ReflectionUtils.GetCollectionItemType(type);
+        if (collectionItemType != null)
+        {
+          CurrentSchema.Items = new List<JsonSchema>();
+          CurrentSchema.Items.Add(GenerateInternal(collectionItemType, (!allowNullItem) ? Required.Always : Required.Default, false));
+        }
+      }
+      else if (contract is JsonPrimitiveContract)
+      {
+        CurrentSchema.Type = GetJsonSchemaType(type, valueRequired);
+
+        if (CurrentSchema.Type == JsonSchemaType.Integer && type.IsEnum && !type.IsDefined(typeof(FlagsAttribute), true))
+        {
+          CurrentSchema.Enum = new List<JToken>();
+          CurrentSchema.Options = new Dictionary<JToken, string>();
+
+          EnumValues<long> enumValues = EnumUtils.GetNamesAndValues<long>(type);
+          foreach (EnumValue<long> enumValue in enumValues)
+          {
+            JToken value = JToken.FromObject(enumValue.Value);
+
+            CurrentSchema.Enum.Add(value);
+            CurrentSchema.Options.Add(value, enumValue.Name);
+          }
+        }
+      }
+      else if (contract is JsonObjectContract)
+      {
+        CurrentSchema.Type = AddNullType(JsonSchemaType.Object, valueRequired);
+        CurrentSchema.Id = GetTypeId(type, false);
+        GenerateObjectSchema(type, (JsonObjectContract)contract);
+      }
+#if !SILVERLIGHT && !PocketPC
+      else if (contract is JsonISerializableContract)
+      {
+        CurrentSchema.Type = AddNullType(JsonSchemaType.Object, valueRequired);
+        CurrentSchema.Id = GetTypeId(type, false);
+        GenerateISerializableContract(type, (JsonISerializableContract) contract);
+      }
+#endif
+      else if (contract is JsonStringContract)
+      {
+        JsonSchemaType schemaType = (!ReflectionUtils.IsNullable(contract.UnderlyingType))
+                                      ? JsonSchemaType.String
+                                      : AddNullType(JsonSchemaType.String, valueRequired);
+
+        CurrentSchema.Type = schemaType;
+      }
+      else if (contract is JsonLinqContract)
+      {
+        CurrentSchema.Type = JsonSchemaType.Any;
+      }
+      else
+      {
+        throw new Exception("Unexpected contract type: {0}".FormatWith(CultureInfo.InvariantCulture, contract));
+      }
+
+      return Pop().Schema;
+    }
+
+    private JsonSchemaType AddNullType(JsonSchemaType type, Required valueRequired)
+    {
+      if (valueRequired != Required.Always)
+        return type | JsonSchemaType.Null;
+
+      return type;
+    }
+
+    private void GenerateObjectSchema(Type type, JsonObjectContract contract)
+    {
+      CurrentSchema.Properties = new Dictionary<string, JsonSchema>();
+      foreach (JsonProperty property in contract.Properties)
+      {
+        if (!property.Ignored)
+        {
+          bool optional = property.NullValueHandling == NullValueHandling.Ignore ||
+                          property.DefaultValueHandling == DefaultValueHandling.Ignore ||
+                          property.ShouldSerialize != null ||
+                          property.GetIsSpecified != null;
+
+          JsonSchema propertySchema = GenerateInternal(property.PropertyType, property.Required, !optional);
+
+          if (property.DefaultValue != null)
+            propertySchema.Default = JToken.FromObject(property.DefaultValue);
+
+          CurrentSchema.Properties.Add(property.PropertyName, propertySchema);
+        }
+      }
+
+      if (type.IsSealed)
+        CurrentSchema.AllowAdditionalProperties = false;
+    }
+
+#if !SILVERLIGHT && !PocketPC
+    private void GenerateISerializableContract(Type type, JsonISerializableContract contract)
+    {
+      CurrentSchema.AllowAdditionalProperties = true;
+    }
+#endif
+
+    internal static bool HasFlag(JsonSchemaType? value, JsonSchemaType flag)
+    {
+      // default value is Any
+      if (value == null)
+        return true;
+
+      return ((value & flag) == flag);
+    }
+
+    private JsonSchemaType GetJsonSchemaType(Type type, Required valueRequired)
+    {
+      JsonSchemaType schemaType = JsonSchemaType.None;
+      if (valueRequired != Required.Always && ReflectionUtils.IsNullable(type))
+      {
+        schemaType = JsonSchemaType.Null;
+        if (ReflectionUtils.IsNullableType(type))
+          type = Nullable.GetUnderlyingType(type);
+      }
+
+      TypeCode typeCode = Type.GetTypeCode(type);
+
+      switch (typeCode)
+      {
+        case TypeCode.Empty:
+        case TypeCode.Object:
+          return schemaType | JsonSchemaType.String;
+        case TypeCode.DBNull:
+          return schemaType | JsonSchemaType.Null;
+        case TypeCode.Boolean:
+          return schemaType | JsonSchemaType.Boolean;
+        case TypeCode.Char:
+          return schemaType | JsonSchemaType.String;
+        case TypeCode.SByte:
+        case TypeCode.Byte:
+        case TypeCode.Int16:
+        case TypeCode.UInt16:
+        case TypeCode.Int32:
+        case TypeCode.UInt32:
+        case TypeCode.Int64:
+        case TypeCode.UInt64:
+          return schemaType | JsonSchemaType.Integer;
+        case TypeCode.Single:
+        case TypeCode.Double:
+        case TypeCode.Decimal:
+          return schemaType | JsonSchemaType.Float;
+        // convert to string?
+        case TypeCode.DateTime:
+          return schemaType | JsonSchemaType.String;
+        case TypeCode.String:
+          return schemaType | JsonSchemaType.String;
+        default:
+          throw new Exception("Unexpected type code '{0}' for type '{1}'.".FormatWith(CultureInfo.InvariantCulture, typeCode, type));
+      }
+    }
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaModel.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaModel.cs
new file mode 100644 (file)
index 0000000..82926d5
--- /dev/null
@@ -0,0 +1,113 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Schema
+{
+  internal class JsonSchemaModel
+  {
+    public bool Required { get; set; }
+    public JsonSchemaType Type { get; set; }
+    public int? MinimumLength { get; set; }
+    public int? MaximumLength { get; set; }
+    public double? DivisibleBy { get; set; }
+    public double? Minimum { get; set; }
+    public double? Maximum { get; set; }
+    public bool ExclusiveMinimum { get; set; }
+    public bool ExclusiveMaximum { get; set; }
+    public int? MinimumItems { get; set; }
+    public int? MaximumItems { get; set; }
+    public IList<string> Patterns { get; set; }
+    public IList<JsonSchemaModel> Items { get; set; }
+    public IDictionary<string, JsonSchemaModel> Properties { get; set; }
+    public IDictionary<string, JsonSchemaModel> PatternProperties { get; set; }
+    public JsonSchemaModel AdditionalProperties { get; set; }
+    public bool AllowAdditionalProperties { get; set; }
+    public IList<JToken> Enum { get; set; }
+    public JsonSchemaType Disallow { get; set; }
+
+    public JsonSchemaModel()
+    {
+      Type = JsonSchemaType.Any;
+      AllowAdditionalProperties = true;
+      Required = false;
+    }
+
+    public static JsonSchemaModel Create(IList<JsonSchema> schemata)
+    {
+      JsonSchemaModel model = new JsonSchemaModel();
+
+      foreach (JsonSchema schema in schemata)
+      {
+        Combine(model, schema);
+      }
+
+      return model;
+    }
+
+    private static void Combine(JsonSchemaModel model, JsonSchema schema)
+    {
+      // Version 3 of the Draft JSON Schema has the default value of Not Required
+      model.Required = model.Required || (schema.Required ?? false);
+      model.Type = model.Type & (schema.Type ?? JsonSchemaType.Any);
+
+      model.MinimumLength = MathUtils.Max(model.MinimumLength, schema.MinimumLength);
+      model.MaximumLength = MathUtils.Min(model.MaximumLength, schema.MaximumLength);
+
+      // not sure what is the best way to combine divisibleBy
+      model.DivisibleBy = MathUtils.Max(model.DivisibleBy, schema.DivisibleBy);
+
+      model.Minimum = MathUtils.Max(model.Minimum, schema.Minimum);
+      model.Maximum = MathUtils.Max(model.Maximum, schema.Maximum);
+      model.ExclusiveMinimum = model.ExclusiveMinimum || (schema.ExclusiveMinimum ?? false);
+      model.ExclusiveMaximum = model.ExclusiveMaximum || (schema.ExclusiveMaximum ?? false);
+
+      model.MinimumItems = MathUtils.Max(model.MinimumItems, schema.MinimumItems);
+      model.MaximumItems = MathUtils.Min(model.MaximumItems, schema.MaximumItems);
+      model.AllowAdditionalProperties = model.AllowAdditionalProperties && schema.AllowAdditionalProperties;
+      if (schema.Enum != null)
+      {
+        if (model.Enum == null)
+          model.Enum = new List<JToken>();
+
+        model.Enum.AddRangeDistinct(schema.Enum, new JTokenEqualityComparer());
+      }
+      model.Disallow = model.Disallow | (schema.Disallow ?? JsonSchemaType.None);
+
+      if (schema.Pattern != null)
+      {
+        if (model.Patterns == null)
+          model.Patterns = new List<string>();
+
+        model.Patterns.AddDistinct(schema.Pattern);
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaModelBuilder.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaModelBuilder.cs
new file mode 100644 (file)
index 0000000..b040248
--- /dev/null
@@ -0,0 +1,173 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Schema
+{
+  internal class JsonSchemaModelBuilder
+  {
+    private JsonSchemaNodeCollection _nodes = new JsonSchemaNodeCollection();
+    private Dictionary<JsonSchemaNode, JsonSchemaModel> _nodeModels = new Dictionary<JsonSchemaNode, JsonSchemaModel>();
+    private JsonSchemaNode _node ;
+
+    public JsonSchemaModel Build(JsonSchema schema)
+    {
+      _nodes = new JsonSchemaNodeCollection();
+      _node = AddSchema(null, schema);
+
+      _nodeModels = new Dictionary<JsonSchemaNode, JsonSchemaModel>();
+      JsonSchemaModel model = BuildNodeModel(_node);
+
+      return model;
+    }
+
+    public JsonSchemaNode AddSchema(JsonSchemaNode existingNode, JsonSchema schema)
+    {
+      string newId;
+      if (existingNode != null)
+      {
+        if (existingNode.Schemas.Contains(schema))
+          return existingNode;
+
+        newId = JsonSchemaNode.GetId(existingNode.Schemas.Union(new[] { schema }));
+      }
+      else
+      {
+        newId = JsonSchemaNode.GetId(new[] { schema });
+      }
+
+      if (_nodes.Contains(newId))
+        return _nodes[newId];
+
+      JsonSchemaNode currentNode = (existingNode != null)
+        ? existingNode.Combine(schema)
+        : new JsonSchemaNode(schema);
+
+      _nodes.Add(currentNode);
+
+      AddProperties(schema.Properties, currentNode.Properties);
+
+      AddProperties(schema.PatternProperties, currentNode.PatternProperties);
+
+      if (schema.Items != null)
+      {
+        for (int i = 0; i < schema.Items.Count; i++)
+        {
+          AddItem(currentNode, i, schema.Items[i]);
+        }
+      }
+
+      if (schema.AdditionalProperties != null)
+        AddAdditionalProperties(currentNode, schema.AdditionalProperties);
+
+      if (schema.Extends != null)
+        currentNode = AddSchema(currentNode, schema.Extends);
+
+      return currentNode;
+    }
+
+    public void AddProperties(IDictionary<string, JsonSchema> source, IDictionary<string, JsonSchemaNode> target)
+    {
+      if (source != null)
+      {
+        foreach (KeyValuePair<string, JsonSchema> property in source)
+        {
+          AddProperty(target, property.Key, property.Value);
+        }
+      }
+    }
+
+    public void AddProperty(IDictionary<string, JsonSchemaNode> target, string propertyName, JsonSchema schema)
+    {
+      JsonSchemaNode propertyNode;
+      target.TryGetValue(propertyName, out propertyNode);
+
+      target[propertyName] = AddSchema(propertyNode, schema);
+    }
+
+    public void AddItem(JsonSchemaNode parentNode, int index, JsonSchema schema)
+    {
+      JsonSchemaNode existingItemNode = (parentNode.Items.Count > index)
+                                  ? parentNode.Items[index]
+                                  : null;
+
+      JsonSchemaNode newItemNode = AddSchema(existingItemNode, schema);
+      
+      if (!(parentNode.Items.Count > index))
+      {
+        parentNode.Items.Add(newItemNode);
+      }
+      else
+      {
+        parentNode.Items[index] = newItemNode;
+      }
+    }
+
+    public void AddAdditionalProperties(JsonSchemaNode parentNode, JsonSchema schema)
+    {
+      parentNode.AdditionalProperties = AddSchema(parentNode.AdditionalProperties, schema);
+    }
+
+    private JsonSchemaModel BuildNodeModel(JsonSchemaNode node)
+    {
+      JsonSchemaModel model;
+      if (_nodeModels.TryGetValue(node, out model))
+        return model;
+      
+      model = JsonSchemaModel.Create(node.Schemas);
+      _nodeModels[node] = model;
+
+      foreach (KeyValuePair<string, JsonSchemaNode> property in node.Properties)
+      {
+        if (model.Properties == null)
+          model.Properties = new Dictionary<string, JsonSchemaModel>();
+
+        model.Properties[property.Key] = BuildNodeModel(property.Value);
+      }
+      foreach (KeyValuePair<string, JsonSchemaNode> property in node.PatternProperties)
+      {
+        if (model.PatternProperties == null)
+          model.PatternProperties = new Dictionary<string, JsonSchemaModel>();
+
+        model.PatternProperties[property.Key] = BuildNodeModel(property.Value);
+      }
+      for (int i = 0; i < node.Items.Count; i++)
+      {
+        if (model.Items == null)
+          model.Items = new List<JsonSchemaModel>();
+
+        model.Items.Add(BuildNodeModel(node.Items[i]));
+      }
+      if (node.AdditionalProperties != null)
+        model.AdditionalProperties = BuildNodeModel(node.AdditionalProperties);
+
+      return model;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaNode.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaNode.cs
new file mode 100644 (file)
index 0000000..093f2b3
--- /dev/null
@@ -0,0 +1,73 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+
+namespace Newtonsoft.Json.Schema
+{
+  internal class JsonSchemaNode
+  {
+    public string Id { get; private set; }
+    public ReadOnlyCollection<JsonSchema> Schemas { get; private set; }
+    public Dictionary<string, JsonSchemaNode> Properties { get; private set; }
+    public Dictionary<string, JsonSchemaNode> PatternProperties { get; private set; }
+    public List<JsonSchemaNode> Items { get; private set; }
+    public JsonSchemaNode AdditionalProperties { get; set; }
+
+    public JsonSchemaNode(JsonSchema schema)
+    {
+      Schemas = new ReadOnlyCollection<JsonSchema>(new []{ schema });
+      Properties = new Dictionary<string, JsonSchemaNode>();
+      PatternProperties = new Dictionary<string, JsonSchemaNode>();
+      Items = new List<JsonSchemaNode>();
+
+      Id = GetId(Schemas);
+    }
+
+    private JsonSchemaNode(JsonSchemaNode source, JsonSchema schema)
+    {
+      Schemas = new ReadOnlyCollection<JsonSchema>(source.Schemas.Union(new[] { schema }).ToList());
+      Properties = new Dictionary<string, JsonSchemaNode>(source.Properties);
+      PatternProperties = new Dictionary<string, JsonSchemaNode>(source.PatternProperties);
+      Items = new List<JsonSchemaNode>(source.Items);
+      AdditionalProperties = source.AdditionalProperties;
+
+      Id = GetId(Schemas);
+    }
+
+    public JsonSchemaNode Combine(JsonSchema schema)
+    {
+      return new JsonSchemaNode(this, schema);
+    }
+
+    public static string GetId(IEnumerable<JsonSchema> schemata)
+    {
+      return string.Join("-", schemata.Select(s => s.InternalId).OrderBy(id => id, StringComparer.Ordinal).ToArray());
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaNodeCollection.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaNodeCollection.cs
new file mode 100644 (file)
index 0000000..5f2ef01
--- /dev/null
@@ -0,0 +1,37 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System.Collections.ObjectModel;
+
+namespace Newtonsoft.Json.Schema
+{
+  internal class JsonSchemaNodeCollection : KeyedCollection<string, JsonSchemaNode>
+  {
+    protected override string GetKeyForItem(JsonSchemaNode item)
+    {
+      return item.Id;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaResolver.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaResolver.cs
new file mode 100644 (file)
index 0000000..6b50a6c
--- /dev/null
@@ -0,0 +1,66 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Globalization;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Schema
+{
+  /// <summary>
+  /// Resolves <see cref="JsonSchema"/> from an id.
+  /// </summary>
+  public class JsonSchemaResolver
+  {
+    /// <summary>
+    /// Gets or sets the loaded schemas.
+    /// </summary>
+    /// <value>The loaded schemas.</value>
+    public IList<JsonSchema> LoadedSchemas { get; protected set; }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonSchemaResolver"/> class.
+    /// </summary>
+    public JsonSchemaResolver()
+    {
+      LoadedSchemas = new List<JsonSchema>();
+    }
+
+    /// <summary>
+    /// Gets a <see cref="JsonSchema"/> for the specified id.
+    /// </summary>
+    /// <param name="id">The id.</param>
+    /// <returns>A <see cref="JsonSchema"/> for the specified id.</returns>
+    public virtual JsonSchema GetSchema(string id)
+    {
+      JsonSchema schema = LoadedSchemas.SingleOrDefault(s => s.Id == id);
+      return schema;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaType.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaType.cs
new file mode 100644 (file)
index 0000000..a58805a
--- /dev/null
@@ -0,0 +1,76 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Schema
+{
+  /// <summary>
+  /// The value types allowed by the <see cref="JsonSchema"/>.
+  /// </summary>
+  [Flags]
+  public enum JsonSchemaType
+  {
+    /// <summary>
+    /// No type specified.
+    /// </summary>
+    None = 0,
+    /// <summary>
+    /// String type.
+    /// </summary>
+    String = 1,
+    /// <summary>
+    /// Float type.
+    /// </summary>
+    Float = 2,
+    /// <summary>
+    /// Integer type.
+    /// </summary>
+    Integer = 4,
+    /// <summary>
+    /// Boolean type.
+    /// </summary>
+    Boolean = 8,
+    /// <summary>
+    /// Object type.
+    /// </summary>
+    Object = 16,
+    /// <summary>
+    /// Array type.
+    /// </summary>
+    Array = 32,
+    /// <summary>
+    /// Null type.
+    /// </summary>
+    Null = 64,
+    /// <summary>
+    /// Any type.
+    /// </summary>
+    Any = String | Float | Integer | Boolean | Object | Array | Null
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaWriter.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/JsonSchemaWriter.cs
new file mode 100644 (file)
index 0000000..1584fc4
--- /dev/null
@@ -0,0 +1,221 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Schema
+{
+  internal class JsonSchemaWriter
+  {
+    private readonly JsonWriter _writer;
+    private readonly JsonSchemaResolver _resolver;
+
+    public JsonSchemaWriter(JsonWriter writer, JsonSchemaResolver resolver)
+    {
+      ValidationUtils.ArgumentNotNull(writer, "writer");
+      _writer = writer;
+      _resolver = resolver;
+    }
+
+    private void ReferenceOrWriteSchema(JsonSchema schema)
+    {
+      if (schema.Id != null && _resolver.GetSchema(schema.Id) != null)
+      {
+        _writer.WriteStartObject();
+        _writer.WritePropertyName(JsonSchemaConstants.ReferencePropertyName);
+        _writer.WriteValue(schema.Id);
+        _writer.WriteEndObject();
+      }
+      else
+      {
+        WriteSchema(schema);
+      }
+    }
+
+    public void WriteSchema(JsonSchema schema)
+    {
+      ValidationUtils.ArgumentNotNull(schema, "schema");
+
+      if (!_resolver.LoadedSchemas.Contains(schema))
+        _resolver.LoadedSchemas.Add(schema);
+
+      _writer.WriteStartObject();
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.IdPropertyName, schema.Id);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.TitlePropertyName, schema.Title);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.DescriptionPropertyName, schema.Description);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.RequiredPropertyName, schema.Required);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.ReadOnlyPropertyName, schema.ReadOnly);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.HiddenPropertyName, schema.Hidden);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.TransientPropertyName, schema.Transient);
+      if (schema.Type != null)
+        WriteType(JsonSchemaConstants.TypePropertyName, _writer, schema.Type.Value);
+      if (!schema.AllowAdditionalProperties)
+      {
+        _writer.WritePropertyName(JsonSchemaConstants.AdditionalPropertiesPropertyName);
+        _writer.WriteValue(schema.AllowAdditionalProperties);
+      }
+      else
+      {
+        if (schema.AdditionalProperties != null)
+        {
+          _writer.WritePropertyName(JsonSchemaConstants.AdditionalPropertiesPropertyName);
+          ReferenceOrWriteSchema(schema.AdditionalProperties);
+        }
+      }
+      WriteSchemaDictionaryIfNotNull(_writer, JsonSchemaConstants.PropertiesPropertyName, schema.Properties);
+      WriteSchemaDictionaryIfNotNull(_writer, JsonSchemaConstants.PatternPropertiesPropertyName, schema.PatternProperties);
+      WriteItems(schema);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.MinimumPropertyName, schema.Minimum);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.MaximumPropertyName, schema.Maximum);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.ExclusiveMinimumPropertyName, schema.ExclusiveMinimum);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.ExclusiveMaximumPropertyName, schema.ExclusiveMaximum);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.MinimumLengthPropertyName, schema.MinimumLength);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.MaximumLengthPropertyName, schema.MaximumLength);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.MinimumItemsPropertyName, schema.MinimumItems);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.MaximumItemsPropertyName, schema.MaximumItems);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.DivisibleByPropertyName, schema.DivisibleBy);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.FormatPropertyName, schema.Format);
+      WritePropertyIfNotNull(_writer, JsonSchemaConstants.PatternPropertyName, schema.Pattern);
+      if (schema.Enum != null)
+      {
+        _writer.WritePropertyName(JsonSchemaConstants.EnumPropertyName);
+        _writer.WriteStartArray();
+        foreach (JToken token in schema.Enum)
+        {
+          token.WriteTo(_writer);
+        }
+        _writer.WriteEndArray();
+      }
+      if (schema.Default != null)
+      {
+        _writer.WritePropertyName(JsonSchemaConstants.DefaultPropertyName);
+        schema.Default.WriteTo(_writer);
+      }
+      if (schema.Options != null)
+      {
+        _writer.WritePropertyName(JsonSchemaConstants.OptionsPropertyName);
+        _writer.WriteStartArray();
+        foreach (KeyValuePair<JToken, string> option in schema.Options)
+        {
+          _writer.WriteStartObject();
+          _writer.WritePropertyName(JsonSchemaConstants.OptionValuePropertyName);
+          option.Key.WriteTo(_writer);
+          if (option.Value != null)
+          {
+            _writer.WritePropertyName(JsonSchemaConstants.OptionLabelPropertyName);
+            _writer.WriteValue(option.Value);
+          }
+          _writer.WriteEndObject();
+        }
+        _writer.WriteEndArray();
+      }
+      if (schema.Disallow != null)
+        WriteType(JsonSchemaConstants.DisallowPropertyName, _writer, schema.Disallow.Value);
+      if (schema.Extends != null)
+      {
+        _writer.WritePropertyName(JsonSchemaConstants.ExtendsPropertyName);
+        ReferenceOrWriteSchema(schema.Extends);
+      }
+      _writer.WriteEndObject();
+    }
+
+    private void WriteSchemaDictionaryIfNotNull(JsonWriter writer, string propertyName, IDictionary<string, JsonSchema> properties)
+    {
+      if (properties != null)
+      {
+        writer.WritePropertyName(propertyName);
+        writer.WriteStartObject();
+        foreach (KeyValuePair<string, JsonSchema> property in properties)
+        {
+          writer.WritePropertyName(property.Key);
+          ReferenceOrWriteSchema(property.Value);
+        }
+        writer.WriteEndObject();
+      }
+    }
+
+    private void WriteItems(JsonSchema schema)
+    {
+      if (CollectionUtils.IsNullOrEmpty(schema.Items))
+        return;
+
+      _writer.WritePropertyName(JsonSchemaConstants.ItemsPropertyName);
+
+      if (schema.Items.Count == 1)
+      {
+        ReferenceOrWriteSchema(schema.Items[0]);
+        return;
+      }
+
+      _writer.WriteStartArray();
+      foreach (JsonSchema itemSchema in schema.Items)
+      {
+        ReferenceOrWriteSchema(itemSchema);
+      }
+      _writer.WriteEndArray();
+    }
+
+    private void WriteType(string propertyName, JsonWriter writer, JsonSchemaType type)
+    {
+      IList<JsonSchemaType> types;
+      if (System.Enum.IsDefined(typeof(JsonSchemaType), type))
+        types = new List<JsonSchemaType> { type };
+      else
+        types = EnumUtils.GetFlagsValues(type).Where(v => v != JsonSchemaType.None).ToList();
+
+      if (types.Count == 0)
+        return;
+
+      writer.WritePropertyName(propertyName);
+
+      if (types.Count == 1)
+      {
+        writer.WriteValue(JsonSchemaBuilder.MapType(types[0]));
+        return;
+      }
+
+      writer.WriteStartArray();
+      foreach (JsonSchemaType jsonSchemaType in types)
+      {
+        writer.WriteValue(JsonSchemaBuilder.MapType(jsonSchemaType));
+      }
+      writer.WriteEndArray();
+    }
+
+    private void WritePropertyIfNotNull(JsonWriter writer, string propertyName, object value)
+    {
+      if (value != null)
+      {
+        writer.WritePropertyName(propertyName);
+        writer.WriteValue(value);
+      }
+    }
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/UndefinedSchemaIdHandling.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/UndefinedSchemaIdHandling.cs
new file mode 100644 (file)
index 0000000..34bbbee
--- /dev/null
@@ -0,0 +1,46 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Schema
+{
+  /// <summary>
+  /// Specifies undefined schema Id handling options for the <see cref="JsonSchemaGenerator"/>.
+  /// </summary>
+  public enum UndefinedSchemaIdHandling
+  {
+    /// <summary>
+    /// Do not infer a schema Id.
+    /// </summary>
+    None = 0,
+    /// <summary>
+    /// Use the .NET type name as the schema Id.
+    /// </summary>
+    UseTypeName = 1,
+    /// <summary>
+    /// Use the assembly qualified .NET type name as the schema Id.
+    /// </summary>
+    UseAssemblyQualifiedName = 2,
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/ValidationEventArgs.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/ValidationEventArgs.cs
new file mode 100644 (file)
index 0000000..d56fb9f
--- /dev/null
@@ -0,0 +1,62 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Schema
+{
+  /// <summary>
+  /// Returns detailed information related to the <see cref="ValidationEventHandler"/>.
+  /// </summary>
+  public class ValidationEventArgs : EventArgs
+  {
+    private readonly JsonSchemaException _ex;
+
+    internal ValidationEventArgs(JsonSchemaException ex)
+    {
+      ValidationUtils.ArgumentNotNull(ex, "ex");
+      _ex = ex;
+    }
+
+    /// <summary>
+    /// Gets the <see cref="JsonSchemaException"/> associated with the validation event.
+    /// </summary>
+    /// <value>The JsonSchemaException associated with the validation event.</value>
+    public JsonSchemaException Exception
+    {
+      get { return _ex; }
+    }
+
+    /// <summary>
+    /// Gets the text description corresponding to the validation event.
+    /// </summary>
+    /// <value>The text description.</value>
+    public string Message
+    {
+      get { return _ex.Message; }
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/ValidationEventHandler.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Schema/ValidationEventHandler.cs
new file mode 100644 (file)
index 0000000..95d213d
--- /dev/null
@@ -0,0 +1,32 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Schema
+{
+  /// <summary>
+  /// Represents the callback method that will handle JSON schema validation events and the <see cref="ValidationEventArgs"/>.
+  /// </summary>
+  public delegate void ValidationEventHandler(object sender, ValidationEventArgs e);
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/CachedAttributeGetter.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/CachedAttributeGetter.cs
new file mode 100644 (file)
index 0000000..552920e
--- /dev/null
@@ -0,0 +1,44 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Serialization
+{
+  internal static class CachedAttributeGetter<T> where T : Attribute
+  {
+    private static readonly ThreadSafeStore<ICustomAttributeProvider, T> TypeAttributeCache = new ThreadSafeStore<ICustomAttributeProvider, T>(JsonTypeReflector.GetAttribute<T>);
+
+    public static T GetAttribute(ICustomAttributeProvider type)
+    {
+      return TypeAttributeCache.Get(type);
+    }
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/CamelCasePropertyNamesContractResolver.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/CamelCasePropertyNamesContractResolver.cs
new file mode 100644 (file)
index 0000000..34784c8
--- /dev/null
@@ -0,0 +1,55 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System.Globalization;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Resolves member mappings for a type, camel casing property names.
+  /// </summary>
+  public class CamelCasePropertyNamesContractResolver : DefaultContractResolver
+  {
+    /// <summary>
+    /// Initializes a new instance of the <see cref="CamelCasePropertyNamesContractResolver"/> class.
+    /// </summary>
+    public CamelCasePropertyNamesContractResolver()
+      : base(true)
+    {
+    }
+
+    /// <summary>
+    /// Resolves the name of the property.
+    /// </summary>
+    /// <param name="propertyName">Name of the property.</param>
+    /// <returns>The property name camel cased.</returns>
+    protected override string ResolvePropertyName(string propertyName)
+    {
+      // lower case the first letter of the passed in name
+      return StringUtils.ToCamelCase(propertyName);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs
new file mode 100644 (file)
index 0000000..51498ac
--- /dev/null
@@ -0,0 +1,788 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+#if !(NET35 || NET20 || WINDOWS_PHONE)
+using System.Dynamic;
+#endif
+using System.Globalization;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.Serialization;
+using System.Security.Permissions;
+using System.Xml.Serialization;
+using Newtonsoft.Json.Converters;
+using Newtonsoft.Json.Utilities;
+using Newtonsoft.Json.Linq;
+using System.Runtime.CompilerServices;
+
+namespace Newtonsoft.Json.Serialization
+{
+  internal struct ResolverContractKey : IEquatable<ResolverContractKey>
+  {
+    private readonly Type _resolverType;
+    private readonly Type _contractType;
+
+    public ResolverContractKey(Type resolverType, Type contractType)
+    {
+      _resolverType = resolverType;
+      _contractType = contractType;
+    }
+
+    public override int GetHashCode()
+    {
+      return _resolverType.GetHashCode() ^ _contractType.GetHashCode();
+    }
+
+    public override bool Equals(object obj)
+    {
+      if (!(obj is ResolverContractKey))
+        return false;
+
+      return Equals((ResolverContractKey)obj);
+    }
+
+    public bool Equals(ResolverContractKey other)
+    {
+      return (_resolverType == other._resolverType && _contractType == other._contractType);
+    }
+  }
+
+  /// <summary>
+  /// Used by <see cref="JsonSerializer"/> to resolves a <see cref="JsonContract"/> for a given <see cref="Type"/>.
+  /// </summary>
+  public class DefaultContractResolver : IContractResolver
+  {
+    internal static readonly IContractResolver Instance = new DefaultContractResolver(true);
+    private static readonly IList<JsonConverter> BuiltInConverters = new List<JsonConverter>
+      {
+#if !PocketPC && !SILVERLIGHT && !NET20
+        new EntityKeyMemberConverter(),
+#endif
+#if !(NET35 || NET20 || WINDOWS_PHONE)
+        new ExpandoObjectConverter(),
+#endif
+        new BinaryConverter(),
+        new KeyValuePairConverter(),
+#if !SILVERLIGHT || WINDOWS_PHONE
+        new XmlNodeConverter(),
+#endif
+#if !SILVERLIGHT
+        new DataSetConverter(),
+        new DataTableConverter(),
+#endif
+        new BsonObjectIdConverter()
+      };
+
+    private static Dictionary<ResolverContractKey, JsonContract> _sharedContractCache;
+    private static readonly object _typeContractCacheLock = new object();
+
+    private Dictionary<ResolverContractKey, JsonContract> _instanceContractCache;
+    private readonly bool _sharedCache;
+
+    /// <summary>
+    /// Gets a value indicating whether members are being get and set using dynamic code generation.
+    /// This value is determined by the runtime permissions available.
+    /// </summary>
+    /// <value>
+    ///        <c>true</c> if using dynamic code generation; otherwise, <c>false</c>.
+    /// </value>
+    public bool DynamicCodeGeneration
+    {
+      get { return JsonTypeReflector.DynamicCodeGeneration; }
+    }
+
+    /// <summary>
+    /// Gets or sets the default members search flags.
+    /// </summary>
+    /// <value>The default members search flags.</value>
+    public BindingFlags DefaultMembersSearchFlags { get; set; }
+
+    /// <summary>
+    /// Gets or sets a value indicating whether compiler generated members should be serialized.
+    /// </summary>
+    /// <value>
+    ///        <c>true</c> if serialized compiler generated members; otherwise, <c>false</c>.
+    /// </value>
+    public bool SerializeCompilerGeneratedMembers { get; set; }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="DefaultContractResolver"/> class.
+    /// </summary>
+    public DefaultContractResolver()
+      : this(false)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="DefaultContractResolver"/> class.
+    /// </summary>
+    /// <param name="shareCache">
+    /// If set to <c>true</c> the <see cref="DefaultContractResolver"/> will use a cached shared with other resolvers of the same type.
+    /// Sharing the cache will significantly performance because expensive reflection will only happen once but could cause unexpected
+    /// behavior if different instances of the resolver are suppose to produce different results. When set to false it is highly
+    /// recommended to reuse <see cref="DefaultContractResolver"/> instances with the <see cref="JsonSerializer"/>.
+    /// </param>
+    public DefaultContractResolver(bool shareCache)
+    {
+      DefaultMembersSearchFlags = BindingFlags.Public | BindingFlags.Instance;
+      _sharedCache = shareCache;
+    }
+
+    private Dictionary<ResolverContractKey, JsonContract> GetCache()
+    {
+      if (_sharedCache)
+        return _sharedContractCache;
+      else
+        return _instanceContractCache;
+    }
+
+    private void UpdateCache(Dictionary<ResolverContractKey, JsonContract> cache)
+    {
+      if (_sharedCache)
+        _sharedContractCache = cache;
+      else
+        _instanceContractCache = cache;
+    }
+
+    /// <summary>
+    /// Resolves the contract for a given type.
+    /// </summary>
+    /// <param name="type">The type to resolve a contract for.</param>
+    /// <returns>The contract for a given type.</returns>
+    public virtual JsonContract ResolveContract(Type type)
+    {
+      if (type == null)
+        throw new ArgumentNullException("type");
+
+      JsonContract contract;
+      ResolverContractKey key = new ResolverContractKey(GetType(), type);
+      Dictionary<ResolverContractKey, JsonContract> cache = GetCache();
+      if (cache == null || !cache.TryGetValue(key, out contract))
+      {
+        contract = CreateContract(type);
+
+        // avoid the possibility of modifying the cache dictionary while another thread is accessing it
+        lock (_typeContractCacheLock)
+        {
+          cache = GetCache();
+          Dictionary<ResolverContractKey, JsonContract> updatedCache =
+            (cache != null)
+              ? new Dictionary<ResolverContractKey, JsonContract>(cache)
+              : new Dictionary<ResolverContractKey, JsonContract>();
+          updatedCache[key] = contract;
+
+          UpdateCache(updatedCache);
+        }
+      }
+
+      return contract;
+    }
+
+    /// <summary>
+    /// Gets the serializable members for the type.
+    /// </summary>
+    /// <param name="objectType">The type to get serializable members for.</param>
+    /// <returns>The serializable members for the type.</returns>
+    protected virtual List<MemberInfo> GetSerializableMembers(Type objectType)
+    {
+#if !PocketPC && !NET20
+      DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(objectType);
+#endif
+
+      List<MemberInfo> defaultMembers = ReflectionUtils.GetFieldsAndProperties(objectType, DefaultMembersSearchFlags)
+        .Where(m => !ReflectionUtils.IsIndexedProperty(m)).ToList();
+      List<MemberInfo> allMembers = ReflectionUtils.GetFieldsAndProperties(objectType, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)
+        .Where(m => !ReflectionUtils.IsIndexedProperty(m)).ToList();
+
+      List<MemberInfo> serializableMembers = new List<MemberInfo>();
+      foreach (MemberInfo member in allMembers)
+      {
+        // exclude members that are compiler generated if set
+        if (SerializeCompilerGeneratedMembers || !member.IsDefined(typeof(CompilerGeneratedAttribute), true))
+        {
+          if (defaultMembers.Contains(member))
+          {
+            // add all members that are found by default member search
+            serializableMembers.Add(member);
+          }
+          else
+          {
+            // add members that are explicitly marked with JsonProperty/DataMember attribute
+            if (JsonTypeReflector.GetAttribute<JsonPropertyAttribute>(member) != null)
+              serializableMembers.Add(member);
+#if !PocketPC && !NET20
+            else if (dataContractAttribute != null && JsonTypeReflector.GetAttribute<DataMemberAttribute>(member) != null)
+              serializableMembers.Add(member);
+#endif
+          }
+        }
+      }
+
+#if !PocketPC && !SILVERLIGHT && !NET20
+      Type match;
+      // don't include EntityKey on entities objects... this is a bit hacky
+      if (objectType.AssignableToTypeName("System.Data.Objects.DataClasses.EntityObject", out match))
+        serializableMembers = serializableMembers.Where(ShouldSerializeEntityMember).ToList();
+#endif
+
+      return serializableMembers;
+    }
+
+#if !PocketPC && !SILVERLIGHT && !NET20
+    private bool ShouldSerializeEntityMember(MemberInfo memberInfo)
+    {
+      PropertyInfo propertyInfo = memberInfo as PropertyInfo;
+      if (propertyInfo != null)
+      {
+        if (propertyInfo.PropertyType.IsGenericType && propertyInfo.PropertyType.GetGenericTypeDefinition().FullName == "System.Data.Objects.DataClasses.EntityReference`1")
+          return false;
+      }
+
+      return true;
+    }
+#endif
+
+    /// <summary>
+    /// Creates a <see cref="JsonObjectContract"/> for the given type.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns>A <see cref="JsonObjectContract"/> for the given type.</returns>
+    protected virtual JsonObjectContract CreateObjectContract(Type objectType)
+    {
+      JsonObjectContract contract = new JsonObjectContract(objectType);
+      InitializeContract(contract);
+
+      contract.MemberSerialization = JsonTypeReflector.GetObjectMemberSerialization(objectType);
+      contract.Properties.AddRange(CreateProperties(contract.UnderlyingType, contract.MemberSerialization));
+      if (objectType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Any(c => c.IsDefined(typeof(JsonConstructorAttribute), true)))
+        contract.OverrideConstructor = GetAttributeConstructor(objectType);
+      else if (contract.DefaultCreator == null || contract.DefaultCreatorNonPublic)
+        contract.ParametrizedConstructor = GetParametrizedConstructor(objectType);
+
+      return contract;
+    }
+
+    private ConstructorInfo GetAttributeConstructor(Type objectType)
+    {
+      IList<ConstructorInfo> markedConstructors = objectType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Where(c => c.IsDefined(typeof(JsonConstructorAttribute), true)).ToList();
+
+      if (markedConstructors.Count > 1)
+        throw new Exception("Multiple constructors with the JsonConstructorAttribute.");
+      else if (markedConstructors.Count == 1)
+        return markedConstructors[0];
+
+      return null;
+    }
+
+    private ConstructorInfo GetParametrizedConstructor(Type objectType)
+    {
+      IList<ConstructorInfo> constructors = objectType.GetConstructors(BindingFlags.Public | BindingFlags.Instance);
+
+      if (constructors.Count == 1)
+        return constructors[0];
+      else
+        return null;
+    }
+
+    /// <summary>
+    /// Resolves the default <see cref="JsonConverter" /> for the contract.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns></returns>
+    protected virtual JsonConverter ResolveContractConverter(Type objectType)
+    {
+      return JsonTypeReflector.GetJsonConverter(objectType, objectType);
+    }
+
+    private Func<object> GetDefaultCreator(Type createdType)
+    {
+      return JsonTypeReflector.ReflectionDelegateFactory.CreateDefaultConstructor<object>(createdType);
+    }
+
+#if !PocketPC && !NET20
+    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Portability", "CA1903:UseOnlyApiFromTargetedFramework", MessageId = "System.Runtime.Serialization.DataContractAttribute.#get_IsReference()")]
+#endif
+    private void InitializeContract(JsonContract contract)
+    {
+      JsonContainerAttribute containerAttribute = JsonTypeReflector.GetJsonContainerAttribute(contract.UnderlyingType);
+      if (containerAttribute != null)
+      {
+        contract.IsReference = containerAttribute._isReference;
+      }
+#if !PocketPC && !NET20
+      else
+      {
+        DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(contract.UnderlyingType);
+        // doesn't have a null value
+        if (dataContractAttribute != null && dataContractAttribute.IsReference)
+          contract.IsReference = true;
+      }
+#endif
+
+      contract.Converter = ResolveContractConverter(contract.UnderlyingType);
+
+      // then see whether object is compadible with any of the built in converters
+      contract.InternalConverter = JsonSerializer.GetMatchingConverter(BuiltInConverters, contract.UnderlyingType);
+
+      if (ReflectionUtils.HasDefaultConstructor(contract.CreatedType, true)
+        || contract.CreatedType.IsValueType)
+      {
+        contract.DefaultCreator = GetDefaultCreator(contract.CreatedType);
+
+        contract.DefaultCreatorNonPublic = (!contract.CreatedType.IsValueType &&
+                                            ReflectionUtils.GetDefaultConstructor(contract.CreatedType) == null);
+      }
+
+      foreach (MethodInfo method in contract.UnderlyingType.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
+      {
+        // compact framework errors when getting parameters for a generic method
+        // lame, but generic methods should not be callbacks anyway
+        if (method.ContainsGenericParameters)
+          continue;
+
+        Type prevAttributeType = null;
+        ParameterInfo[] parameters = method.GetParameters();
+
+#if !PocketPC
+        if (IsValidCallback(method, parameters, typeof(OnSerializingAttribute), contract.OnSerializing, ref prevAttributeType))
+        {
+          contract.OnSerializing = method;
+        }
+        if (IsValidCallback(method, parameters, typeof(OnSerializedAttribute), contract.OnSerialized, ref prevAttributeType))
+        {
+          contract.OnSerialized = method;
+        }
+        if (IsValidCallback(method, parameters, typeof(OnDeserializingAttribute), contract.OnDeserializing, ref prevAttributeType))
+        {
+          contract.OnDeserializing = method;
+        }
+        if (IsValidCallback(method, parameters, typeof(OnDeserializedAttribute), contract.OnDeserialized, ref prevAttributeType))
+        {
+          contract.OnDeserialized = method;
+        }
+#endif
+        if (IsValidCallback(method, parameters, typeof(OnErrorAttribute), contract.OnError, ref prevAttributeType))
+        {
+          contract.OnError = method;
+        }
+      }
+    }
+
+    /// <summary>
+    /// Creates a <see cref="JsonDictionaryContract"/> for the given type.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns>A <see cref="JsonDictionaryContract"/> for the given type.</returns>
+    protected virtual JsonDictionaryContract CreateDictionaryContract(Type objectType)
+    {
+      JsonDictionaryContract contract = new JsonDictionaryContract(objectType);
+      InitializeContract(contract);
+
+      contract.PropertyNameResolver = ResolvePropertyName;
+
+      return contract;
+    }
+
+    /// <summary>
+    /// Creates a <see cref="JsonArrayContract"/> for the given type.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns>A <see cref="JsonArrayContract"/> for the given type.</returns>
+    protected virtual JsonArrayContract CreateArrayContract(Type objectType)
+    {
+      JsonArrayContract contract = new JsonArrayContract(objectType);
+      InitializeContract(contract);
+
+      return contract;
+    }
+
+    /// <summary>
+    /// Creates a <see cref="JsonPrimitiveContract"/> for the given type.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns>A <see cref="JsonPrimitiveContract"/> for the given type.</returns>
+    protected virtual JsonPrimitiveContract CreatePrimitiveContract(Type objectType)
+    {
+      JsonPrimitiveContract contract = new JsonPrimitiveContract(objectType);
+      InitializeContract(contract);
+
+      return contract;
+    }
+
+    /// <summary>
+    /// Creates a <see cref="JsonLinqContract"/> for the given type.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns>A <see cref="JsonLinqContract"/> for the given type.</returns>
+    protected virtual JsonLinqContract CreateLinqContract(Type objectType)
+    {
+      JsonLinqContract contract = new JsonLinqContract(objectType);
+      InitializeContract(contract);
+
+      return contract;
+    }
+
+#if !SILVERLIGHT && !PocketPC
+    /// <summary>
+    /// Creates a <see cref="JsonISerializableContract"/> for the given type.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns>A <see cref="JsonISerializableContract"/> for the given type.</returns>
+    protected virtual JsonISerializableContract CreateISerializableContract(Type objectType)
+    {
+      JsonISerializableContract contract = new JsonISerializableContract(objectType);
+      InitializeContract(contract);
+
+      ConstructorInfo constructorInfo = objectType.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { typeof(SerializationInfo), typeof(StreamingContext) }, null);
+      if (constructorInfo != null)
+      {
+        MethodCall<object, object> methodCall = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall<object>(constructorInfo);
+
+        contract.ISerializableCreator = (args => methodCall(null, args));
+      }
+
+      return contract;
+    }
+#endif
+
+#if !(NET35 || NET20 || WINDOWS_PHONE)
+    /// <summary>
+    /// Creates a <see cref="JsonDynamicContract"/> for the given type.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns>A <see cref="JsonDynamicContract"/> for the given type.</returns>
+    protected virtual JsonDynamicContract CreateDynamicContract(Type objectType)
+    {
+      JsonDynamicContract contract = new JsonDynamicContract(objectType);
+      InitializeContract(contract);
+
+      contract.PropertyNameResolver = ResolvePropertyName;
+      contract.Properties.AddRange(CreateProperties(objectType, MemberSerialization.OptOut));
+
+      return contract;
+    }
+#endif
+
+    /// <summary>
+    /// Creates a <see cref="JsonStringContract"/> for the given type.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns>A <see cref="JsonStringContract"/> for the given type.</returns>
+    protected virtual JsonStringContract CreateStringContract(Type objectType)
+    {
+      JsonStringContract contract = new JsonStringContract(objectType);
+      InitializeContract(contract);
+
+      return contract;
+    }
+
+    /// <summary>
+    /// Determines which contract type is created for the given type.
+    /// </summary>
+    /// <param name="objectType">Type of the object.</param>
+    /// <returns>A <see cref="JsonContract"/> for the given type.</returns>
+    protected virtual JsonContract CreateContract(Type objectType)
+    {
+      Type t = ReflectionUtils.EnsureNotNullableType(objectType);
+
+      if (JsonConvert.IsJsonPrimitiveType(t))
+        return CreatePrimitiveContract(t);
+
+      if (JsonTypeReflector.GetJsonObjectAttribute(t) != null)
+        return CreateObjectContract(t);
+
+      if (JsonTypeReflector.GetJsonArrayAttribute(t) != null)
+        return CreateArrayContract(t);
+
+      if (t == typeof(JToken) || t.IsSubclassOf(typeof(JToken)))
+        return CreateLinqContract(t);
+
+      if (CollectionUtils.IsDictionaryType(t))
+        return CreateDictionaryContract(t);
+
+      if (typeof(IEnumerable).IsAssignableFrom(t))
+        return CreateArrayContract(t);
+
+      if (CanConvertToString(t))
+        return CreateStringContract(t);
+
+#if !SILVERLIGHT && !PocketPC
+      if (typeof(ISerializable).IsAssignableFrom(t))
+        return CreateISerializableContract(t);
+#endif
+
+#if !(NET35 || NET20 || WINDOWS_PHONE)
+      if (typeof(IDynamicMetaObjectProvider).IsAssignableFrom(t))
+        return CreateDynamicContract(t);
+#endif
+
+      return CreateObjectContract(t);
+    }
+
+    internal static bool CanConvertToString(Type type)
+    {
+#if !PocketPC
+      TypeConverter converter = ConvertUtils.GetConverter(type);
+
+      // use the objectType's TypeConverter if it has one and can convert to a string
+      if (converter != null
+#if !SILVERLIGHT
+ && !(converter is ComponentConverter)
+ && !(converter is ReferenceConverter)
+#endif
+ && converter.GetType() != typeof(TypeConverter))
+      {
+        if (converter.CanConvertTo(typeof(string)))
+          return true;
+      }
+#endif
+
+      if (type == typeof(Type) || type.IsSubclassOf(typeof(Type)))
+        return true;
+
+#if SILVERLIGHT || PocketPC
+      if (type == typeof(Guid) || type == typeof(Uri) || type == typeof(TimeSpan))
+        return true;
+#endif
+
+      return false;
+    }
+
+    private static bool IsValidCallback(MethodInfo method, ParameterInfo[] parameters, Type attributeType, MethodInfo currentCallback, ref Type prevAttributeType)
+    {
+      if (!method.IsDefined(attributeType, false))
+        return false;
+
+      if (currentCallback != null)
+        throw new Exception("Invalid attribute. Both '{0}' and '{1}' in type '{2}' have '{3}'.".FormatWith(CultureInfo.InvariantCulture, method, currentCallback, GetClrTypeFullName(method.DeclaringType), attributeType));
+
+      if (prevAttributeType != null)
+        throw new Exception("Invalid Callback. Method '{3}' in type '{2}' has both '{0}' and '{1}'.".FormatWith(CultureInfo.InvariantCulture, prevAttributeType, attributeType, GetClrTypeFullName(method.DeclaringType), method));
+
+      if (method.IsVirtual)
+        throw new Exception("Virtual Method '{0}' of type '{1}' cannot be marked with '{2}' attribute.".FormatWith(CultureInfo.InvariantCulture, method, GetClrTypeFullName(method.DeclaringType), attributeType));
+
+      if (method.ReturnType != typeof(void))
+        throw new Exception("Serialization Callback '{1}' in type '{0}' must return void.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(method.DeclaringType), method));
+
+      if (attributeType == typeof(OnErrorAttribute))
+      {
+        if (parameters == null || parameters.Length != 2 || parameters[0].ParameterType != typeof(StreamingContext) || parameters[1].ParameterType != typeof(ErrorContext))
+          throw new Exception("Serialization Error Callback '{1}' in type '{0}' must have two parameters of type '{2}' and '{3}'.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(method.DeclaringType), method, typeof(StreamingContext), typeof(ErrorContext)));
+      }
+      else
+      {
+        if (parameters == null || parameters.Length != 1 || parameters[0].ParameterType != typeof(StreamingContext))
+          throw new Exception("Serialization Callback '{1}' in type '{0}' must have a single parameter of type '{2}'.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(method.DeclaringType), method, typeof(StreamingContext)));
+      }
+
+      prevAttributeType = attributeType;
+
+      return true;
+    }
+
+    internal static string GetClrTypeFullName(Type type)
+    {
+      if (type.IsGenericTypeDefinition || !type.ContainsGenericParameters)
+        return type.FullName;
+
+      return string.Format(CultureInfo.InvariantCulture, "{0}.{1}", new object[] { type.Namespace, type.Name });
+    }
+
+    /// <summary>
+    /// Creates properties for the given <see cref="JsonContract"/>.
+    /// </summary>
+    /// <param name="type">The type to create properties for.</param>
+    /// /// <param name="memberSerialization">The member serialization mode for the type.</param>
+    /// <returns>Properties for the given <see cref="JsonContract"/>.</returns>
+    protected virtual IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
+    {
+      List<MemberInfo> members = GetSerializableMembers(type);
+      if (members == null)
+        throw new JsonSerializationException("Null collection of seralizable members returned.");
+
+      JsonPropertyCollection properties = new JsonPropertyCollection(type);
+
+      foreach (MemberInfo member in members)
+      {
+        JsonProperty property = CreateProperty(member, memberSerialization);
+
+        if (property != null)
+          properties.AddProperty(property);
+      }
+
+      return properties;
+    }
+
+    /// <summary>
+    /// Creates the <see cref="IValueProvider"/> used by the serializer to get and set values from a member.
+    /// </summary>
+    /// <param name="member">The member.</param>
+    /// <returns>The <see cref="IValueProvider"/> used by the serializer to get and set values from a member.</returns>
+    protected virtual IValueProvider CreateMemberValueProvider(MemberInfo member)
+    {
+#if !PocketPC && !SILVERLIGHT
+      if (DynamicCodeGeneration)
+        return new DynamicValueProvider(member);
+#endif
+
+      return new ReflectionValueProvider(member);
+    }
+
+    /// <summary>
+    /// Creates a <see cref="JsonProperty"/> for the given <see cref="MemberInfo"/>.
+    /// </summary>
+    /// <param name="memberSerialization">The member's parent <see cref="MemberSerialization"/>.</param>
+    /// <param name="member">The member to create a <see cref="JsonProperty"/> for.</param>
+    /// <returns>A created <see cref="JsonProperty"/> for the given <see cref="MemberInfo"/>.</returns>
+    protected virtual JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
+    {
+      JsonProperty property = new JsonProperty();
+      property.PropertyType = ReflectionUtils.GetMemberUnderlyingType(member);
+      property.ValueProvider = CreateMemberValueProvider(member);
+
+      // resolve converter for property
+      // the class type might have a converter but the property converter takes presidence
+      property.Converter = JsonTypeReflector.GetJsonConverter(member, property.PropertyType);
+
+#if !PocketPC && !NET20
+      DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(member.DeclaringType);
+
+      DataMemberAttribute dataMemberAttribute;
+      if (dataContractAttribute != null)
+        dataMemberAttribute = JsonTypeReflector.GetAttribute<DataMemberAttribute>(member);
+      else
+        dataMemberAttribute = null;
+#endif
+
+      JsonPropertyAttribute propertyAttribute = JsonTypeReflector.GetAttribute<JsonPropertyAttribute>(member);
+      bool hasIgnoreAttribute = (JsonTypeReflector.GetAttribute<JsonIgnoreAttribute>(member) != null);
+
+      string mappedName;
+      if (propertyAttribute != null && propertyAttribute.PropertyName != null)
+        mappedName = propertyAttribute.PropertyName;
+#if !PocketPC && !NET20
+      else if (dataMemberAttribute != null && dataMemberAttribute.Name != null)
+        mappedName = dataMemberAttribute.Name;
+#endif
+      else
+        mappedName = member.Name;
+
+      property.PropertyName = ResolvePropertyName(mappedName);
+
+      if (propertyAttribute != null)
+        property.Required = propertyAttribute.Required;
+#if !PocketPC && !NET20
+      else if (dataMemberAttribute != null)
+        property.Required = (dataMemberAttribute.IsRequired) ? Required.AllowNull : Required.Default;
+#endif
+      else
+        property.Required = Required.Default;
+
+      property.Ignored = (hasIgnoreAttribute ||
+                      (memberSerialization == MemberSerialization.OptIn
+                       && propertyAttribute == null
+#if !PocketPC && !NET20
+ && dataMemberAttribute == null
+#endif
+));
+
+      bool allowNonPublicAccess = false;
+      if ((DefaultMembersSearchFlags & BindingFlags.NonPublic) == BindingFlags.NonPublic)
+        allowNonPublicAccess = true;
+      if (propertyAttribute != null)
+        allowNonPublicAccess = true;
+#if !PocketPC && !NET20
+      if (dataMemberAttribute != null)
+        allowNonPublicAccess = true;
+#endif
+
+      property.Readable = ReflectionUtils.CanReadMemberValue(member, allowNonPublicAccess);
+      property.Writable = ReflectionUtils.CanSetMemberValue(member, allowNonPublicAccess);
+
+      property.MemberConverter = JsonTypeReflector.GetJsonConverter(member, ReflectionUtils.GetMemberUnderlyingType(member));
+
+      DefaultValueAttribute defaultValueAttribute = JsonTypeReflector.GetAttribute<DefaultValueAttribute>(member);
+      property.DefaultValue = (defaultValueAttribute != null) ? defaultValueAttribute.Value : null;
+
+      property.NullValueHandling = (propertyAttribute != null) ? propertyAttribute._nullValueHandling : null;
+      property.DefaultValueHandling = (propertyAttribute != null) ? propertyAttribute._defaultValueHandling : null;
+      property.ReferenceLoopHandling = (propertyAttribute != null) ? propertyAttribute._referenceLoopHandling : null;
+      property.ObjectCreationHandling = (propertyAttribute != null) ? propertyAttribute._objectCreationHandling : null;
+      property.TypeNameHandling = (propertyAttribute != null) ? propertyAttribute._typeNameHandling : null;
+      property.IsReference = (propertyAttribute != null) ? propertyAttribute._isReference : null;
+
+      property.ShouldSerialize = CreateShouldSerializeTest(member);
+
+      SetIsSpecifiedActions(property, member);
+
+      return property;
+    }
+
+    private Predicate<object> CreateShouldSerializeTest(MemberInfo member)
+    {
+      MethodInfo shouldSerializeMethod = member.DeclaringType.GetMethod(JsonTypeReflector.ShouldSerializePrefix + member.Name, new Type[0]);
+
+      if (shouldSerializeMethod == null || shouldSerializeMethod.ReturnType != typeof(bool))
+        return null;
+
+      MethodCall<object, object> shouldSerializeCall =
+        JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall<object>(shouldSerializeMethod);
+
+      return o => (bool)shouldSerializeCall(o);
+    }
+
+    private void SetIsSpecifiedActions(JsonProperty property, MemberInfo member)
+    {
+      MemberInfo specifiedMember = member.DeclaringType.GetProperty(member.Name + JsonTypeReflector.SpecifiedPostfix);
+      if (specifiedMember == null)
+        specifiedMember = member.DeclaringType.GetField(member.Name + JsonTypeReflector.SpecifiedPostfix);
+
+      if (specifiedMember == null || ReflectionUtils.GetMemberUnderlyingType(specifiedMember) != typeof(bool))
+      {
+        return;
+      }
+
+      Func<object, object> specifiedPropertyGet = JsonTypeReflector.ReflectionDelegateFactory.CreateGet<object>(specifiedMember);
+
+      property.GetIsSpecified = o => (bool)specifiedPropertyGet(o);
+      property.SetIsSpecified = JsonTypeReflector.ReflectionDelegateFactory.CreateSet<object>(specifiedMember);
+    }
+
+    /// <summary>
+    /// Resolves the name of the property.
+    /// </summary>
+    /// <param name="propertyName">Name of the property.</param>
+    /// <returns>Name of the property.</returns>
+    protected virtual string ResolvePropertyName(string propertyName)
+    {
+      return propertyName;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/DefaultReferenceResolver.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/DefaultReferenceResolver.cs
new file mode 100644 (file)
index 0000000..cb8dbe1
--- /dev/null
@@ -0,0 +1,87 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text;
+using Newtonsoft.Json.Utilities;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Serialization
+{
+  internal class DefaultReferenceResolver : IReferenceResolver
+  {
+    private int _referenceCount;
+
+    private BidirectionalDictionary<string, object> GetMappings(object context)
+    {
+      JsonSerializerInternalBase internalSerializer;
+
+      if (context is JsonSerializerInternalBase)
+        internalSerializer = (JsonSerializerInternalBase) context;
+      else if (context is JsonSerializerProxy)
+        internalSerializer = ((JsonSerializerProxy) context).GetInternalSerializer();
+      else
+        throw new Exception("The DefaultReferenceResolver can only be used internally.");
+
+      return internalSerializer.DefaultReferenceMappings;
+    }
+
+    public object ResolveReference(object context, string reference)
+    {
+      object value;
+      GetMappings(context).TryGetByFirst(reference, out value);
+      return value;
+    }
+
+    public string GetReference(object context, object value)
+    {
+      var mappings = GetMappings(context);
+
+      string reference;
+      if (!mappings.TryGetBySecond(value, out reference))
+      {
+        _referenceCount++;
+        reference = _referenceCount.ToString(CultureInfo.InvariantCulture);
+        mappings.Add(reference, value);
+      }
+
+      return reference;
+    }
+
+    public void AddReference(object context, string reference, object value)
+    {
+      GetMappings(context).Add(reference, value);
+    }
+
+    public bool IsReferenced(object context, object value)
+    {
+      string reference;
+      return GetMappings(context).TryGetBySecond(value, out reference);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/DefaultSerializationBinder.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/DefaultSerializationBinder.cs
new file mode 100644 (file)
index 0000000..3a5c772
--- /dev/null
@@ -0,0 +1,120 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Runtime.Serialization;
+using System.Reflection;
+using System.Globalization;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// The default serialization binder used when resolving and loading classes from type names.
+  /// </summary>
+  public class DefaultSerializationBinder : SerializationBinder
+  {
+    internal static readonly DefaultSerializationBinder Instance = new DefaultSerializationBinder();
+
+    private readonly ThreadSafeStore<TypeNameKey, Type> _typeCache = new ThreadSafeStore<TypeNameKey, Type>(GetTypeFromTypeNameKey);
+
+    private static Type GetTypeFromTypeNameKey(TypeNameKey typeNameKey)
+    {
+      string assemblyName = typeNameKey.AssemblyName;
+      string typeName = typeNameKey.TypeName;
+
+      if (assemblyName != null)
+      {
+        Assembly assembly;
+
+#if !SILVERLIGHT && !PocketPC
+        // look, I don't like using obsolete methods as much as you do but this is the only way
+        // Assembly.Load won't check the GAC for a partial name
+#pragma warning disable 618,612
+        assembly = Assembly.LoadWithPartialName(assemblyName);
+#pragma warning restore 618,612
+#else
+        assembly = Assembly.Load(assemblyName);
+#endif
+
+        if (assembly == null)
+          throw new JsonSerializationException("Could not load assembly '{0}'.".FormatWith(CultureInfo.InvariantCulture, assemblyName));
+
+        Type type = assembly.GetType(typeName);
+        if (type == null)
+          throw new JsonSerializationException("Could not find type '{0}' in assembly '{1}'.".FormatWith(CultureInfo.InvariantCulture, typeName, assembly.FullName));
+
+        return type;
+      }
+      else
+      {
+        return Type.GetType(typeName);
+      }
+    }
+
+    internal struct TypeNameKey : IEquatable<TypeNameKey>
+    {
+      internal readonly string AssemblyName;
+      internal readonly string TypeName;
+
+      public TypeNameKey(string assemblyName, string typeName)
+      {
+        AssemblyName = assemblyName;
+        TypeName = typeName;
+      }
+
+      public override int GetHashCode()
+      {
+        return ((AssemblyName != null) ? AssemblyName.GetHashCode() : 0) ^ ((TypeName != null) ? TypeName.GetHashCode() : 0);
+      }
+
+      public override bool Equals(object obj)
+      {
+        if (!(obj is TypeNameKey))
+          return false;
+
+        return Equals((TypeNameKey)obj);
+      }
+
+      public bool Equals(TypeNameKey other)
+      {
+        return (AssemblyName == other.AssemblyName && TypeName == other.TypeName);
+      }
+    }
+
+    /// <summary>
+    /// When overridden in a derived class, controls the binding of a serialized object to a type.
+    /// </summary>
+    /// <param name="assemblyName">Specifies the <see cref="T:System.Reflection.Assembly"/> name of the serialized object.</param>
+    /// <param name="typeName">Specifies the <see cref="T:System.Type"/> name of the serialized object.</param>
+    /// <returns>
+    /// The type of the object the formatter creates a new instance of.
+    /// </returns>
+    public override Type BindToType(string assemblyName, string typeName)
+    {
+      return _typeCache.Get(new TypeNameKey(assemblyName, typeName));
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/DynamicValueProvider.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/DynamicValueProvider.cs
new file mode 100644 (file)
index 0000000..e998bad
--- /dev/null
@@ -0,0 +1,111 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+#if !PocketPC && !SILVERLIGHT
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Newtonsoft.Json.Utilities;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Get and set values for a <see cref="MemberInfo"/> using dynamic methods.
+  /// </summary>
+  public class DynamicValueProvider : IValueProvider
+  {
+    private readonly MemberInfo _memberInfo;
+    private Func<object, object> _getter;
+    private Action<object, object> _setter;
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="DynamicValueProvider"/> class.
+    /// </summary>
+    /// <param name="memberInfo">The member info.</param>
+    public DynamicValueProvider(MemberInfo memberInfo)
+    {
+      ValidationUtils.ArgumentNotNull(memberInfo, "memberInfo");
+      _memberInfo = memberInfo;
+    }
+
+    /// <summary>
+    /// Sets the value.
+    /// </summary>
+    /// <param name="target">The target to set the value on.</param>
+    /// <param name="value">The value to set on the target.</param>
+    public void SetValue(object target, object value)
+    {
+      try
+      {
+        if (_setter == null)
+          _setter = DynamicReflectionDelegateFactory.Instance.CreateSet<object>(_memberInfo);
+
+#if DEBUG
+        // dynamic method doesn't check whether the type is 'legal' to set
+        // add this check for unit tests
+        if (value == null)
+        {
+          if (!ReflectionUtils.IsNullable(ReflectionUtils.GetMemberUnderlyingType(_memberInfo)))
+            throw new Exception("Incompatible value. Cannot set {0} to null.".FormatWith(CultureInfo.InvariantCulture, _memberInfo));
+        }
+        else if (!ReflectionUtils.GetMemberUnderlyingType(_memberInfo).IsAssignableFrom(value.GetType()))
+        {
+            throw new Exception("Incompatible value. Cannot set {0} to type {1}.".FormatWith(CultureInfo.InvariantCulture, _memberInfo, value.GetType()));
+        }
+#endif
+
+        _setter(target, value);
+      }
+      catch (Exception ex)
+      {
+        throw new JsonSerializationException("Error setting value to '{0}' on '{1}'.".FormatWith(CultureInfo.InvariantCulture, _memberInfo.Name, target.GetType()), ex);
+      }
+    }
+
+    /// <summary>
+    /// Gets the value.
+    /// </summary>
+    /// <param name="target">The target to get the value from.</param>
+    /// <returns>The value.</returns>
+    public object GetValue(object target)
+    {
+      try
+      {
+        if (_getter == null)
+          _getter = DynamicReflectionDelegateFactory.Instance.CreateGet<object>(_memberInfo);
+
+        return _getter(target);
+      }
+      catch (Exception ex)
+      {
+        throw new JsonSerializationException("Error getting value from '{0}' on '{1}'.".FormatWith(CultureInfo.InvariantCulture, _memberInfo.Name, target.GetType()), ex);
+      }
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/ErrorContext.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/ErrorContext.cs
new file mode 100644 (file)
index 0000000..a89535f
--- /dev/null
@@ -0,0 +1,66 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Provides information surrounding an error.
+  /// </summary>
+  public class ErrorContext
+  {
+    internal ErrorContext(object originalObject, object member, Exception error)
+    {
+      OriginalObject = originalObject;
+      Member = member;
+      Error = error;
+    }
+
+    /// <summary>
+    /// Gets or sets the error.
+    /// </summary>
+    /// <value>The error.</value>
+    public Exception Error { get; private set; }
+    /// <summary>
+    /// Gets the original object that caused the error.
+    /// </summary>
+    /// <value>The original object that caused the error.</value>
+    public object OriginalObject { get; private set; }
+    /// <summary>
+    /// Gets the member that caused the error.
+    /// </summary>
+    /// <value>The member that caused the error.</value>
+    public object Member { get; private set; }
+    /// <summary>
+    /// Gets or sets a value indicating whether this <see cref="ErrorContext"/> is handled.
+    /// </summary>
+    /// <value><c>true</c> if handled; otherwise, <c>false</c>.</value>
+    public bool Handled { get; set; }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/ErrorEventArgs.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/ErrorEventArgs.cs
new file mode 100644 (file)
index 0000000..0c38b12
--- /dev/null
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Provides data for the Error event.
+  /// </summary>
+  public class ErrorEventArgs : EventArgs
+  {
+    /// <summary>
+    /// Gets the current object the error event is being raised against.
+    /// </summary>
+    /// <value>The current object the error event is being raised against.</value>
+    public object CurrentObject { get; private set; }
+    /// <summary>
+    /// Gets the error context.
+    /// </summary>
+    /// <value>The error context.</value>
+    public ErrorContext ErrorContext { get; private set; }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="ErrorEventArgs"/> class.
+    /// </summary>
+    /// <param name="currentObject">The current object.</param>
+    /// <param name="errorContext">The error context.</param>
+    public ErrorEventArgs(object currentObject, ErrorContext errorContext)
+    {
+      CurrentObject = currentObject;
+      ErrorContext = errorContext;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/IContractResolver.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/IContractResolver.cs
new file mode 100644 (file)
index 0000000..19d9671
--- /dev/null
@@ -0,0 +1,45 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Used by <see cref="JsonSerializer"/> to resolves a <see cref="JsonContract"/> for a given <see cref="Type"/>.
+  /// </summary>
+  public interface IContractResolver
+  {
+    /// <summary>
+    /// Resolves the contract for a given type.
+    /// </summary>
+    /// <param name="type">The type to resolve a contract for.</param>
+    /// <returns>The contract for a given type.</returns>
+    JsonContract ResolveContract(Type type);
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/IReferenceResolver.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/IReferenceResolver.cs
new file mode 100644 (file)
index 0000000..bd96b19
--- /dev/null
@@ -0,0 +1,64 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Used to resolve references when serializing and deserializing JSON by the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public interface IReferenceResolver
+  {
+    /// <summary>
+    /// Resolves a reference to its object.
+    /// </summary>
+    /// <param name="context">The serialization context.</param>
+    /// <param name="reference">The reference to resolve.</param>
+    /// <returns>The object that</returns>
+    object ResolveReference(object context, string reference);
+    /// <summary>
+    /// Gets the reference for the sepecified object.
+    /// </summary>
+    /// <param name="context">The serialization context.</param>
+    /// <param name="value">The object to get a reference for.</param>
+    /// <returns>The reference to the object.</returns>
+    string GetReference(object context, object value);
+    /// <summary>
+    /// Determines whether the specified object is referenced.
+    /// </summary>
+    /// <param name="context">The serialization context.</param>
+    /// <param name="value">The object to test for a reference.</param>
+    /// <returns>
+    ///        <c>true</c> if the specified object is referenced; otherwise, <c>false</c>.
+    /// </returns>
+    bool IsReferenced(object context, object value);
+    /// <summary>
+    /// Adds a reference to the specified object.
+    /// </summary>
+    /// <param name="context">The serialization context.</param>
+    /// <param name="reference">The reference.</param>
+    /// <param name="value">The object to reference.</param>
+    void AddReference(object context, string reference, object value);
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/IValueProvider.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/IValueProvider.cs
new file mode 100644 (file)
index 0000000..9f75f7f
--- /dev/null
@@ -0,0 +1,47 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Provides methods to get and set values.
+  /// </summary>
+  public interface IValueProvider
+  {
+    /// <summary>
+    /// Sets the value.
+    /// </summary>
+    /// <param name="target">The target to set the value on.</param>
+    /// <param name="value">The value to set on the target.</param>
+    void SetValue(object target, object value);
+
+    /// <summary>
+    /// Gets the value.
+    /// </summary>
+    /// <param name="target">The target to get the value from.</param>
+    /// <returns>The value.</returns>
+    object GetValue(object target);
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs
new file mode 100644 (file)
index 0000000..d196aea
--- /dev/null
@@ -0,0 +1,129 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using Newtonsoft.Json.Utilities;
+using System.Collections;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Contract details for a <see cref="Type"/> used by the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public class JsonArrayContract : JsonContract
+  {
+    internal Type CollectionItemType { get; private set; }
+
+    private readonly bool _isCollectionItemTypeNullableType;
+    private readonly Type _genericCollectionDefinitionType;
+    private Type _genericWrapperType;
+    private MethodCall<object, object> _genericWrapperCreator;
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonArrayContract"/> class.
+    /// </summary>
+    /// <param name="underlyingType">The underlying type for the contract.</param>
+    public JsonArrayContract(Type underlyingType)
+      : base(underlyingType)
+    {
+      if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(ICollection<>), out _genericCollectionDefinitionType))
+      {
+        CollectionItemType = _genericCollectionDefinitionType.GetGenericArguments()[0];
+      }
+      else
+      {
+        CollectionItemType = ReflectionUtils.GetCollectionItemType(UnderlyingType);
+      }
+
+      if (CollectionItemType != null)
+        _isCollectionItemTypeNullableType = ReflectionUtils.IsNullableType(CollectionItemType);
+
+      if (IsTypeGenericCollectionInterface(UnderlyingType))
+      {
+        CreatedType = ReflectionUtils.MakeGenericType(typeof(List<>), CollectionItemType);
+      }
+    }
+
+    internal IWrappedCollection CreateWrapper(object list)
+    {
+      if ((list is IList && (CollectionItemType == null || !_isCollectionItemTypeNullableType))
+        || UnderlyingType.IsArray)
+        return new CollectionWrapper<object>((IList)list);
+
+      if (_genericCollectionDefinitionType != null)
+      {
+        EnsureGenericWrapperCreator();
+        return (IWrappedCollection) _genericWrapperCreator(null, list);
+      }
+      else
+      {
+        IList values = ((IEnumerable) list).Cast<object>().ToList();
+
+        if (CollectionItemType != null)
+        {
+          Array array = Array.CreateInstance(CollectionItemType, values.Count);
+          for (int i = 0; i < values.Count; i++)
+          {
+            array.SetValue(values[i], i);
+          }
+
+          values = array;
+        }
+
+        return new CollectionWrapper<object>(values);
+      }
+    }
+
+    private void EnsureGenericWrapperCreator()
+    {
+      if (_genericWrapperType == null)
+      {
+        _genericWrapperType = ReflectionUtils.MakeGenericType(typeof (CollectionWrapper<>), CollectionItemType);
+
+        Type constructorArgument = (ReflectionUtils.InheritsGenericDefinition(_genericCollectionDefinitionType, typeof (List<>)))
+                                     ? ReflectionUtils.MakeGenericType(typeof (ICollection<>), CollectionItemType)
+                                     : _genericCollectionDefinitionType;
+
+        ConstructorInfo genericWrapperConstructor = _genericWrapperType.GetConstructor(new[] { constructorArgument });
+        _genericWrapperCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall<object>(genericWrapperConstructor);
+      }
+    }
+
+    private bool IsTypeGenericCollectionInterface(Type type)
+    {
+      if (!type.IsGenericType)
+        return false;
+
+      Type genericDefinition = type.GetGenericTypeDefinition();
+
+      return (genericDefinition == typeof(IList<>)
+              || genericDefinition == typeof(ICollection<>)
+              || genericDefinition == typeof(IEnumerable<>));
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonContract.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonContract.cs
new file mode 100644 (file)
index 0000000..6f20dbb
--- /dev/null
@@ -0,0 +1,153 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Reflection;
+using System.Runtime.Serialization;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Contract details for a <see cref="Type"/> used by the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public abstract class JsonContract
+  {
+    /// <summary>
+    /// Gets the underlying type for the contract.
+    /// </summary>
+    /// <value>The underlying type for the contract.</value>
+    public Type UnderlyingType { get; private set; }
+
+    /// <summary>
+    /// Gets or sets the type created during deserialization.
+    /// </summary>
+    /// <value>The type created during deserialization.</value>
+    public Type CreatedType { get; set; }
+
+    /// <summary>
+    /// Gets or sets whether this type contract is serialized as a reference.
+    /// </summary>
+    /// <value>Whether this type contract is serialized as a reference.</value>
+    public bool? IsReference { get; set; }
+
+    /// <summary>
+    /// Gets or sets the default <see cref="JsonConverter" /> for this contract.
+    /// </summary>
+    /// <value>The converter.</value>
+    public JsonConverter Converter { get; set; }
+
+    // internally specified JsonConverter's to override default behavour
+    // checked for after passed in converters and attribute specified converters
+    internal JsonConverter InternalConverter { get; set; }
+
+#if !PocketPC
+    /// <summary>
+    /// Gets or sets the method called immediately after deserialization of the object.
+    /// </summary>
+    /// <value>The method called immediately after deserialization of the object.</value>
+    public MethodInfo OnDeserialized { get; set; }
+    /// <summary>
+    /// Gets or sets the method called during deserialization of the object.
+    /// </summary>
+    /// <value>The method called during deserialization of the object.</value>
+    public MethodInfo OnDeserializing { get; set; }
+    /// <summary>
+    /// Gets or sets the method called after serialization of the object graph.
+    /// </summary>
+    /// <value>The method called after serialization of the object graph.</value>
+    public MethodInfo OnSerialized { get; set; }
+    /// <summary>
+    /// Gets or sets the method called before serialization of the object.
+    /// </summary>
+    /// <value>The method called before serialization of the object.</value>
+    public MethodInfo OnSerializing { get; set; }
+#endif
+
+    /// <summary>
+    /// Gets or sets the default creator method used to create the object.
+    /// </summary>
+    /// <value>The default creator method used to create the object.</value>
+    public Func<object> DefaultCreator { get; set; }
+
+    /// <summary>
+    /// Gets or sets a value indicating whether [default creator non public].
+    /// </summary>
+    /// <value><c>true</c> if the default object creator is non-public; otherwise, <c>false</c>.</value>
+    public bool DefaultCreatorNonPublic { get; set; }
+
+    /// <summary>
+    /// Gets or sets the method called when an error is thrown during the serialization of the object.
+    /// </summary>
+    /// <value>The method called when an error is thrown during the serialization of the object.</value>
+    public MethodInfo OnError { get; set; }
+
+    internal void InvokeOnSerializing(object o, StreamingContext context)
+    {
+#if !PocketPC
+      if (OnSerializing != null)
+        OnSerializing.Invoke(o, new object[] { context });
+#endif
+    }
+
+    internal void InvokeOnSerialized(object o, StreamingContext context)
+    {
+#if !PocketPC
+      if (OnSerialized != null)
+        OnSerialized.Invoke(o, new object[] { context });
+#endif
+    }
+
+    internal void InvokeOnDeserializing(object o, StreamingContext context)
+    {
+#if !PocketPC
+      if (OnDeserializing != null)
+        OnDeserializing.Invoke(o, new object[] { context });
+#endif
+    }
+
+    internal void InvokeOnDeserialized(object o, StreamingContext context)
+    {
+#if !PocketPC
+      if (OnDeserialized != null)
+        OnDeserialized.Invoke(o, new object[] { context });
+#endif
+    }
+
+    internal void InvokeOnError(object o, StreamingContext context, ErrorContext errorContext)
+    {
+      if (OnError != null)
+        OnError.Invoke(o, new object[] { context, errorContext });
+    }
+
+    internal JsonContract(Type underlyingType)
+    {
+      ValidationUtils.ArgumentNotNull(underlyingType, "underlyingType");
+
+      UnderlyingType = underlyingType;
+      CreatedType = underlyingType;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs
new file mode 100644 (file)
index 0000000..55b757d
--- /dev/null
@@ -0,0 +1,106 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using Newtonsoft.Json.Utilities;
+using System.Collections;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Contract details for a <see cref="Type"/> used by the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public class JsonDictionaryContract : JsonContract
+  {
+    /// <summary>
+    /// Gets or sets the property name resolver.
+    /// </summary>
+    /// <value>The property name resolver.</value>
+    public Func<string, string> PropertyNameResolver { get; set; }
+
+    internal Type DictionaryKeyType { get; private set; }
+    internal Type DictionaryValueType { get; private set; }
+
+    private readonly Type _genericCollectionDefinitionType;
+    private Type _genericWrapperType;
+    private MethodCall<object, object> _genericWrapperCreator;
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonDictionaryContract"/> class.
+    /// </summary>
+    /// <param name="underlyingType">The underlying type for the contract.</param>
+    public JsonDictionaryContract(Type underlyingType)
+      : base(underlyingType)
+    {
+      Type keyType;
+      Type valueType;
+      if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(IDictionary<,>), out _genericCollectionDefinitionType))
+      {
+        keyType = _genericCollectionDefinitionType.GetGenericArguments()[0];
+        valueType = _genericCollectionDefinitionType.GetGenericArguments()[1];
+      }
+      else
+      {
+        ReflectionUtils.GetDictionaryKeyValueTypes(UnderlyingType, out keyType, out valueType);
+      }
+
+      DictionaryKeyType = keyType;
+      DictionaryValueType = valueType;
+
+      if (IsTypeGenericDictionaryInterface(UnderlyingType))
+      {
+        CreatedType = ReflectionUtils.MakeGenericType(typeof(Dictionary<,>), keyType, valueType);
+      }
+    }
+
+    internal IWrappedDictionary CreateWrapper(object dictionary)
+    {
+      if (dictionary is IDictionary)
+        return new DictionaryWrapper<object, object>((IDictionary)dictionary);
+
+      if (_genericWrapperType == null)
+      {
+        _genericWrapperType = ReflectionUtils.MakeGenericType(typeof(DictionaryWrapper<,>), DictionaryKeyType, DictionaryValueType);
+
+        ConstructorInfo genericWrapperConstructor = _genericWrapperType.GetConstructor(new[] { _genericCollectionDefinitionType });
+        _genericWrapperCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall<object>(genericWrapperConstructor);
+      }
+
+      return (IWrappedDictionary)_genericWrapperCreator(null, dictionary);
+    }
+
+    private bool IsTypeGenericDictionaryInterface(Type type)
+    {
+      if (!type.IsGenericType)
+        return false;
+
+      Type genericDefinition = type.GetGenericTypeDefinition();
+
+      return (genericDefinition == typeof(IDictionary<,>));
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonDynamicContract.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonDynamicContract.cs
new file mode 100644 (file)
index 0000000..8d61f6a
--- /dev/null
@@ -0,0 +1,63 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+#if !(NET35 || NET20 || WINDOWS_PHONE)
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using Newtonsoft.Json.Utilities;
+using System.Collections;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Contract details for a <see cref="Type"/> used by the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public class JsonDynamicContract : JsonContract
+  {
+    /// <summary>
+    /// Gets the object's properties.
+    /// </summary>
+    /// <value>The object's properties.</value>
+    public JsonPropertyCollection Properties { get; private set; }
+
+    /// <summary>
+    /// Gets or sets the property name resolver.
+    /// </summary>
+    /// <value>The property name resolver.</value>
+    public Func<string, string> PropertyNameResolver { get; set; }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonDynamicContract"/> class.
+    /// </summary>
+    /// <param name="underlyingType">The underlying type for the contract.</param>
+    public JsonDynamicContract(Type underlyingType)
+      : base(underlyingType)
+    {
+      Properties = new JsonPropertyCollection(UnderlyingType);
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonFormatterConverter.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonFormatterConverter.cs
new file mode 100644 (file)
index 0000000..09f2bea
--- /dev/null
@@ -0,0 +1,154 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+#if !SILVERLIGHT && !PocketPC
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Runtime.Serialization;
+using System.Text;
+using Newtonsoft.Json.Utilities;
+using Newtonsoft.Json.Linq;
+
+namespace Newtonsoft.Json.Serialization
+{
+  internal class JsonFormatterConverter : IFormatterConverter
+  {
+    private readonly JsonSerializer _serializer;
+
+    public JsonFormatterConverter(JsonSerializer serializer)
+    {
+      ValidationUtils.ArgumentNotNull(serializer, "serializer");
+
+      _serializer = serializer;
+    }
+
+    private T GetTokenValue<T>(object value)
+    {
+      ValidationUtils.ArgumentNotNull(value, "value");
+      
+      JValue v = (JValue)value;
+      return (T)System.Convert.ChangeType(v.Value, typeof(T), CultureInfo.InvariantCulture);
+    }
+
+    public object Convert(object value, Type type)
+    {
+      ValidationUtils.ArgumentNotNull(value, "value");
+
+      JToken token = value as JToken;
+      if (token == null)
+        throw new ArgumentException("Value is not a JToken.", "value");
+
+      return _serializer.Deserialize(token.CreateReader(), type);
+    }
+
+    public object Convert(object value, TypeCode typeCode)
+    {
+      ValidationUtils.ArgumentNotNull(value, "value");
+
+      if (value is JValue)
+        value = ((JValue) value).Value;
+
+      return System.Convert.ChangeType(value, typeCode, CultureInfo.InvariantCulture);
+    }
+
+    public bool ToBoolean(object value)
+    {
+      return GetTokenValue<bool>(value);
+    }
+
+    public byte ToByte(object value)
+    {
+      return GetTokenValue<byte>(value);
+    }
+
+    public char ToChar(object value)
+    {
+      return GetTokenValue<char>(value);
+    }
+
+    public DateTime ToDateTime(object value)
+    {
+      return GetTokenValue<DateTime>(value);
+    }
+
+    public decimal ToDecimal(object value)
+    {
+      return GetTokenValue<decimal>(value);
+    }
+
+    public double ToDouble(object value)
+    {
+      return GetTokenValue<double>(value);
+    }
+
+    public short ToInt16(object value)
+    {
+      return GetTokenValue<short>(value);
+    }
+
+    public int ToInt32(object value)
+    {
+      return GetTokenValue<int>(value);
+    }
+
+    public long ToInt64(object value)
+    {
+      return GetTokenValue<long>(value);
+    }
+
+    public sbyte ToSByte(object value)
+    {
+      return GetTokenValue<sbyte>(value);
+    }
+
+    public float ToSingle(object value)
+    {
+      return GetTokenValue<float>(value);
+    }
+
+    public string ToString(object value)
+    {
+      return GetTokenValue<string>(value);
+    }
+
+    public ushort ToUInt16(object value)
+    {
+      return GetTokenValue<ushort>(value);
+    }
+
+    public uint ToUInt32(object value)
+    {
+      return GetTokenValue<uint>(value);
+    }
+
+    public ulong ToUInt64(object value)
+    {
+      return GetTokenValue<ulong>(value);
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonISerializableContract.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonISerializableContract.cs
new file mode 100644 (file)
index 0000000..b943d60
--- /dev/null
@@ -0,0 +1,56 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+#if !SILVERLIGHT && !PocketPC
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Contract details for a <see cref="Type"/> used by the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public class JsonISerializableContract : JsonContract
+  {
+    /// <summary>
+    /// Gets or sets the ISerializable object constructor.
+    /// </summary>
+    /// <value>The ISerializable object constructor.</value>
+    public ObjectConstructor<object> ISerializableCreator { get; set; }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonISerializableContract"/> class.
+    /// </summary>
+    /// <param name="underlyingType">The underlying type for the contract.</param>
+    public JsonISerializableContract(Type underlyingType)
+      : base(underlyingType)
+    {
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonLinqContract.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonLinqContract.cs
new file mode 100644 (file)
index 0000000..212c445
--- /dev/null
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Contract details for a <see cref="Type"/> used by the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public class JsonLinqContract : JsonContract
+  {
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonLinqContract"/> class.
+    /// </summary>
+    /// <param name="underlyingType">The underlying type for the contract.</param>
+    public JsonLinqContract(Type underlyingType)
+      : base(underlyingType)
+    {
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs
new file mode 100644 (file)
index 0000000..61687a9
--- /dev/null
@@ -0,0 +1,72 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Reflection;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Contract details for a <see cref="Type"/> used by the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public class JsonObjectContract : JsonContract
+  {
+    /// <summary>
+    /// Gets or sets the object member serialization.
+    /// </summary>
+    /// <value>The member object serialization.</value>
+    public MemberSerialization MemberSerialization { get; set; }
+
+    /// <summary>
+    /// Gets the object's properties.
+    /// </summary>
+    /// <value>The object's properties.</value>
+    public JsonPropertyCollection Properties { get; private set; }
+
+    /// <summary>
+    /// Gets or sets the override constructor used to create the object.
+    /// This is set when a constructor is marked up using the
+    /// JsonConstructor attribute.
+    /// </summary>
+    /// <value>The override constructor.</value>
+    public ConstructorInfo OverrideConstructor { get; set; }
+
+    /// <summary>
+    /// Gets or sets the parametrized constructor used to create the object.
+    /// </summary>
+    /// <value>The parametrized constructor.</value>
+    public ConstructorInfo ParametrizedConstructor { get; set; }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonObjectContract"/> class.
+    /// </summary>
+    /// <param name="underlyingType">The underlying type for the contract.</param>
+    public JsonObjectContract(Type underlyingType)
+      : base(underlyingType)
+    {
+      Properties = new JsonPropertyCollection(UnderlyingType);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonPrimitiveContract.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonPrimitiveContract.cs
new file mode 100644 (file)
index 0000000..335c090
--- /dev/null
@@ -0,0 +1,44 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Contract details for a <see cref="Type"/> used by the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public class JsonPrimitiveContract : JsonContract
+  {
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonPrimitiveContract"/> class.
+    /// </summary>
+    /// <param name="underlyingType">The underlying type for the contract.</param>
+    public JsonPrimitiveContract(Type underlyingType)
+      : base(underlyingType)
+    {
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonProperty.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonProperty.cs
new file mode 100644 (file)
index 0000000..f1b9a71
--- /dev/null
@@ -0,0 +1,163 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Maps a JSON property to a .NET member.
+  /// </summary>
+  public class JsonProperty
+  {
+    /// <summary>
+    /// Gets the name of the property.
+    /// </summary>
+    /// <value>The name of the property.</value>
+    public string PropertyName { get; set; }
+
+    /// <summary>
+    /// Gets the <see cref="IValueProvider"/> that will get and set the <see cref="JsonProperty"/> during serialization.
+    /// </summary>
+    /// <value>The <see cref="IValueProvider"/> that will get and set the <see cref="JsonProperty"/> during serialization.</value>
+    public IValueProvider ValueProvider { get; set; }
+
+    /// <summary>
+    /// Gets or sets the type of the property.
+    /// </summary>
+    /// <value>The type of the property.</value>
+    public Type PropertyType { get; set; }
+
+    /// <summary>
+    /// Gets or sets the <see cref="JsonConverter" /> for the property.
+    /// If set this converter takes presidence over the contract converter for the property type.
+    /// </summary>
+    /// <value>The converter.</value>
+    public JsonConverter Converter { get; set; }
+
+    /// <summary>
+    /// Gets a value indicating whether this <see cref="JsonProperty"/> is ignored.
+    /// </summary>
+    /// <value><c>true</c> if ignored; otherwise, <c>false</c>.</value>
+    public bool Ignored { get; set; }
+
+    /// <summary>
+    /// Gets a value indicating whether this <see cref="JsonProperty"/> is readable.
+    /// </summary>
+    /// <value><c>true</c> if readable; otherwise, <c>false</c>.</value>
+    public bool Readable { get; set; }
+
+    /// <summary>
+    /// Gets a value indicating whether this <see cref="JsonProperty"/> is writable.
+    /// </summary>
+    /// <value><c>true</c> if writable; otherwise, <c>false</c>.</value>
+    public bool Writable { get; set; }
+
+    /// <summary>
+    /// Gets the member converter.
+    /// </summary>
+    /// <value>The member converter.</value>
+    public JsonConverter MemberConverter { get; set; }
+
+    /// <summary>
+    /// Gets the default value.
+    /// </summary>
+    /// <value>The default value.</value>
+    public object DefaultValue { get; set; }
+
+    /// <summary>
+    /// Gets a value indicating whether this <see cref="JsonProperty"/> is required.
+    /// </summary>
+    /// <value>A value indicating whether this <see cref="JsonProperty"/> is required.</value>
+    public Required Required { get; set; }
+
+    /// <summary>
+    /// Gets a value indicating whether this property preserves object references.
+    /// </summary>
+    /// <value>
+    ///        <c>true</c> if this instance is reference; otherwise, <c>false</c>.
+    /// </value>
+    public bool? IsReference { get; set; }
+
+    /// <summary>
+    /// Gets the property null value handling.
+    /// </summary>
+    /// <value>The null value handling.</value>
+    public NullValueHandling? NullValueHandling { get; set; }
+
+    /// <summary>
+    /// Gets the property default value handling.
+    /// </summary>
+    /// <value>The default value handling.</value>
+    public DefaultValueHandling? DefaultValueHandling { get; set; }
+
+    /// <summary>
+    /// Gets the property reference loop handling.
+    /// </summary>
+    /// <value>The reference loop handling.</value>
+    public ReferenceLoopHandling? ReferenceLoopHandling { get; set; }
+
+    /// <summary>
+    /// Gets the property object creation handling.
+    /// </summary>
+    /// <value>The object creation handling.</value>
+    public ObjectCreationHandling? ObjectCreationHandling { get; set; }
+
+    /// <summary>
+    /// Gets or sets the type name handling.
+    /// </summary>
+    /// <value>The type name handling.</value>
+    public TypeNameHandling? TypeNameHandling { get; set; }
+
+    /// <summary>
+    /// Gets or sets a predicate used to determine whether the property should be serialize.
+    /// </summary>
+    /// <value>A predicate used to determine whether the property should be serialize.</value>
+    public Predicate<object> ShouldSerialize { get; set; }
+
+    /// <summary>
+    /// Gets or sets a predicate used to determine whether the property should be serialized.
+    /// </summary>
+    /// <value>A predicate used to determine whether the property should be serialized.</value>
+    public Predicate<object> GetIsSpecified { get; set; }
+
+    /// <summary>
+    /// Gets or sets an action used to set whether the property has been deserialized.
+    /// </summary>
+    /// <value>An action used to set whether the property has been deserialized.</value>
+    public Action<object, object> SetIsSpecified { get; set; }
+
+    /// <summary>
+    /// Returns a <see cref="String"/> that represents this instance.
+    /// </summary>
+    /// <returns>
+    /// A <see cref="String"/> that represents this instance.
+    /// </returns>
+    public override string ToString()
+    {
+      return PropertyName;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonPropertyCollection.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonPropertyCollection.cs
new file mode 100644 (file)
index 0000000..78e5fdf
--- /dev/null
@@ -0,0 +1,122 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Collections.ObjectModel;
+using Newtonsoft.Json.Utilities;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// A collection of <see cref="JsonProperty"/> objects.
+  /// </summary>
+  public class JsonPropertyCollection : KeyedCollection<string, JsonProperty>
+  {
+    private readonly Type _type;
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonPropertyCollection"/> class.
+    /// </summary>
+    /// <param name="type">The type.</param>
+    public JsonPropertyCollection(Type type)
+    {
+      ValidationUtils.ArgumentNotNull(type, "type");
+      _type = type;
+    }
+
+    /// <summary>
+    /// When implemented in a derived class, extracts the key from the specified element.
+    /// </summary>
+    /// <param name="item">The element from which to extract the key.</param>
+    /// <returns>The key for the specified element.</returns>
+    protected override string GetKeyForItem(JsonProperty item)
+    {
+      return item.PropertyName;
+    }
+
+    /// <summary>
+    /// Adds a <see cref="JsonProperty"/> object.
+    /// </summary>
+    /// <param name="property">The property to add to the collection.</param>
+    public void AddProperty(JsonProperty property)
+    {
+      if (Contains(property.PropertyName))
+      {
+        // don't overwrite existing property with ignored property
+        if (property.Ignored)
+          return;
+
+        JsonProperty existingProperty = this[property.PropertyName];
+
+        if (!existingProperty.Ignored)
+          throw new JsonSerializationException(
+            "A member with the name '{0}' already exists on '{1}'. Use the JsonPropertyAttribute to specify another name.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName, _type));
+
+        // remove ignored property so it can be replaced in collection
+        Remove(existingProperty);
+      }
+
+      Add(property);
+    }
+
+    /// <summary>
+    /// Gets the closest matching <see cref="JsonProperty"/> object.
+    /// First attempts to get an exact case match of propertyName and then
+    /// a case insensitive match.
+    /// </summary>
+    /// <param name="propertyName">Name of the property.</param>
+    /// <returns>A matching property if found.</returns>
+    public JsonProperty GetClosestMatchProperty(string propertyName)
+    {
+      JsonProperty property = GetProperty(propertyName, StringComparison.Ordinal);
+      if (property == null)
+        property = GetProperty(propertyName, StringComparison.OrdinalIgnoreCase);
+
+      return property;
+    }
+
+    /// <summary>
+    /// Gets a property by property name.
+    /// </summary>
+    /// <param name="propertyName">The name of the property to get.</param>
+    /// <param name="comparisonType">Type property name string comparison.</param>
+    /// <returns>A matching property if found.</returns>
+    public JsonProperty GetProperty(string propertyName, StringComparison comparisonType)
+    {
+      foreach (JsonProperty property in this)
+      {
+        if (string.Equals(propertyName, property.PropertyName, comparisonType))
+        {
+          return property;
+        }
+      }
+
+      return null;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalBase.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalBase.cs
new file mode 100644 (file)
index 0000000..5f09aa6
--- /dev/null
@@ -0,0 +1,112 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Runtime.CompilerServices;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Serialization
+{
+  internal abstract class JsonSerializerInternalBase
+  {
+    private class ReferenceEqualsEqualityComparer : IEqualityComparer<object>
+    {
+      bool IEqualityComparer<object>.Equals(object x, object y)
+      {
+        return ReferenceEquals(x, y);
+      }
+
+      int IEqualityComparer<object>.GetHashCode(object obj)
+      {
+#if !PocketPC
+        // put objects in a bucket based on their reference
+        return RuntimeHelpers.GetHashCode(obj);
+#else
+        // put all objects in the same bucket so ReferenceEquals is called on all
+        return -1;
+#endif
+      }
+    }
+
+    private ErrorContext _currentErrorContext;
+    private BidirectionalDictionary<string, object> _mappings;
+
+    internal JsonSerializer Serializer { get; private set; }
+
+    protected JsonSerializerInternalBase(JsonSerializer serializer)
+    {
+      ValidationUtils.ArgumentNotNull(serializer, "serializer");
+
+      Serializer = serializer;
+    }
+
+    internal BidirectionalDictionary<string, object> DefaultReferenceMappings
+    {
+      get
+      {
+        // override equality comparer for object key dictionary
+        // object will be modified as it deserializes and might have mutable hashcode
+        if (_mappings == null)
+          _mappings = new BidirectionalDictionary<string, object>(
+            EqualityComparer<string>.Default,
+            new ReferenceEqualsEqualityComparer());
+
+        return _mappings;
+      }
+    }
+
+    protected ErrorContext GetErrorContext(object currentObject, object member, Exception error)
+    {
+      if (_currentErrorContext == null)
+        _currentErrorContext = new ErrorContext(currentObject, member, error);
+
+      if (_currentErrorContext.Error != error)
+        throw new InvalidOperationException("Current error context error is different to requested error.");
+
+      return _currentErrorContext;
+    }
+
+    protected void ClearErrorContext()
+    {
+      if (_currentErrorContext == null)
+        throw new InvalidOperationException("Could not clear error context. Error context is already null.");
+
+      _currentErrorContext = null;
+    }
+
+    protected bool IsErrorHandled(object currentObject, JsonContract contract, object keyValue, Exception ex)
+    {
+      ErrorContext errorContext = GetErrorContext(currentObject, keyValue, ex);
+      contract.InvokeOnError(currentObject, Serializer.Context, errorContext);
+
+      if (!errorContext.Handled)
+        Serializer.OnError(new ErrorEventArgs(currentObject, errorContext));
+
+      return errorContext.Handled;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs
new file mode 100644 (file)
index 0000000..63dde38
--- /dev/null
@@ -0,0 +1,1082 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+#if !(NET35 || NET20 || WINDOWS_PHONE)
+using System.Dynamic;
+#endif
+using System.Globalization;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.Serialization;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Serialization
+{
+  internal class JsonSerializerInternalReader : JsonSerializerInternalBase
+  {
+    private JsonSerializerProxy _internalSerializer;
+#if !SILVERLIGHT && !PocketPC
+   private JsonFormatterConverter _formatterConverter;
+#endif
+
+    public JsonSerializerInternalReader(JsonSerializer serializer) : base(serializer)
+    {
+    }
+
+    public void Populate(JsonReader reader, object target)
+    {
+      ValidationUtils.ArgumentNotNull(target, "target");
+
+      Type objectType = target.GetType();
+
+      JsonContract contract = Serializer.ContractResolver.ResolveContract(objectType);
+
+      if (reader.TokenType == JsonToken.None)
+        reader.Read();
+
+      if (reader.TokenType == JsonToken.StartArray)
+      {
+        if (contract is JsonArrayContract)
+          PopulateList(CollectionUtils.CreateCollectionWrapper(target), reader, null, (JsonArrayContract)contract);
+        else
+          throw new JsonSerializationException("Cannot populate JSON array onto type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType));
+      }
+      else if (reader.TokenType == JsonToken.StartObject)
+      {
+        CheckedRead(reader);
+
+        string id = null;
+        if (reader.TokenType == JsonToken.PropertyName && string.Equals(reader.Value.ToString(), JsonTypeReflector.IdPropertyName, StringComparison.Ordinal))
+        {
+          CheckedRead(reader);
+          id = reader.Value.ToString();
+          CheckedRead(reader);
+        }
+
+        if (contract is JsonDictionaryContract)
+          PopulateDictionary(CollectionUtils.CreateDictionaryWrapper(target), reader, (JsonDictionaryContract) contract, id);
+        else if (contract is JsonObjectContract)
+          PopulateObject(target, reader, (JsonObjectContract) contract, id);
+        else
+          throw new JsonSerializationException("Cannot populate JSON object onto type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType));
+      }
+      else
+      {
+        throw new JsonSerializationException("Unexpected initial token '{0}' when populating object. Expected JSON object or array.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
+      }
+    }
+
+    private JsonContract GetContractSafe(Type type)
+    {
+      if (type == null)
+        return null;
+
+      return Serializer.ContractResolver.ResolveContract(type);
+    }
+
+    private JsonContract GetContractSafe(Type type, object value)
+    {
+      if (value == null)
+        return GetContractSafe(type);
+
+      return Serializer.ContractResolver.ResolveContract(value.GetType());
+    }
+
+    public object Deserialize(JsonReader reader, Type objectType)
+    {
+      if (reader == null)
+        throw new ArgumentNullException("reader");
+
+      if (reader.TokenType == JsonToken.None && !ReadForType(reader, objectType, null))
+        return null;
+
+      return CreateValueNonProperty(reader, objectType, GetContractSafe(objectType));
+    }
+
+    private JsonSerializerProxy GetInternalSerializer()
+    {
+      if (_internalSerializer == null)
+        _internalSerializer = new JsonSerializerProxy(this);
+
+      return _internalSerializer;
+    }
+
+#if !SILVERLIGHT && !PocketPC
+    private JsonFormatterConverter GetFormatterConverter()
+    {
+      if (_formatterConverter == null)
+        _formatterConverter = new JsonFormatterConverter(GetInternalSerializer());
+
+      return _formatterConverter;
+    }
+#endif
+
+    private JToken CreateJToken(JsonReader reader, JsonContract contract)
+    {
+      ValidationUtils.ArgumentNotNull(reader, "reader");
+
+      if (contract != null && contract.UnderlyingType == typeof(JRaw))
+      {
+        return JRaw.Create(reader);
+      }
+      else
+      {
+        JToken token;
+        using (JTokenWriter writer = new JTokenWriter())
+        {
+          writer.WriteToken(reader);
+          token = writer.Token;
+        }
+
+        return token;
+      }
+    }
+
+    private JToken CreateJObject(JsonReader reader)
+    {
+      ValidationUtils.ArgumentNotNull(reader, "reader");
+
+      // this is needed because we've already read inside the object, looking for special properties
+      JToken token;
+      using (JTokenWriter writer = new JTokenWriter())
+      {
+        writer.WriteStartObject();
+
+        if (reader.TokenType == JsonToken.PropertyName)
+          writer.WriteToken(reader, reader.Depth - 1);
+        else
+          writer.WriteEndObject();
+
+        token = writer.Token;
+      }
+
+      return token;
+    }
+
+    private object CreateValueProperty(JsonReader reader, JsonProperty property, object target, bool gottenCurrentValue, object currentValue)
+    {
+      JsonContract contract = GetContractSafe(property.PropertyType, currentValue);
+      Type objectType = property.PropertyType;
+
+      JsonConverter converter = GetConverter(contract, property.MemberConverter);
+
+      if (converter != null && converter.CanRead)
+      {
+        if (!gottenCurrentValue && target != null && property.Readable)
+          currentValue = property.ValueProvider.GetValue(target);
+
+        return converter.ReadJson(reader, objectType, currentValue, GetInternalSerializer());
+      }
+
+      return CreateValueInternal(reader, objectType, contract, property, currentValue);
+    }
+
+    private object CreateValueNonProperty(JsonReader reader, Type objectType, JsonContract contract)
+    {
+      JsonConverter converter = GetConverter(contract, null);
+
+      if (converter != null && converter.CanRead)
+        return converter.ReadJson(reader, objectType, null, GetInternalSerializer());
+
+      return CreateValueInternal(reader, objectType, contract, null, null);
+    }
+
+    private object CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, object existingValue)
+    {
+      if (contract is JsonLinqContract)
+        return CreateJToken(reader, contract);
+
+      do
+      {
+        switch (reader.TokenType)
+        {
+          // populate a typed object or generic dictionary/array
+          // depending upon whether an objectType was supplied
+          case JsonToken.StartObject:
+            return CreateObject(reader, objectType, contract, member, existingValue);
+          case JsonToken.StartArray:
+            return CreateList(reader, objectType, contract, member, existingValue, null);
+          case JsonToken.Integer:
+          case JsonToken.Float:
+          case JsonToken.Boolean:
+          case JsonToken.Date:
+          case JsonToken.Bytes:
+            return EnsureType(reader.Value, CultureInfo.InvariantCulture, objectType);
+          case JsonToken.String:
+            // convert empty string to null automatically for nullable types
+            if (string.IsNullOrEmpty((string)reader.Value) &&
+              objectType != null &&
+              ReflectionUtils.IsNullableType(objectType))
+              return null;
+
+            // string that needs to be returned as a byte array should be base 64 decoded
+            if (objectType == typeof(byte[]))
+              return Convert.FromBase64String((string)reader.Value);
+
+            return EnsureType(reader.Value, CultureInfo.InvariantCulture, objectType);
+          case JsonToken.StartConstructor:
+          case JsonToken.EndConstructor:
+            string constructorName = reader.Value.ToString();
+
+            return constructorName;
+          case JsonToken.Null:
+          case JsonToken.Undefined:
+            if (objectType == typeof (DBNull))
+              return DBNull.Value;
+
+            return EnsureType(reader.Value, CultureInfo.InvariantCulture, objectType);
+          case JsonToken.Raw:
+            return new JRaw((string)reader.Value);
+          case JsonToken.Comment:
+            // ignore
+            break;
+          default:
+            throw new JsonSerializationException("Unexpected token while deserializing object: " + reader.TokenType);
+        }
+      } while (reader.Read());
+
+      throw new JsonSerializationException("Unexpected end when deserializing object.");
+    }
+
+    private JsonConverter GetConverter(JsonContract contract, JsonConverter memberConverter)
+    {
+      JsonConverter converter = null;
+      if (memberConverter != null)
+      {
+        // member attribute converter
+        converter = memberConverter;
+      }
+      else if (contract != null)
+      {
+        JsonConverter matchingConverter;
+        if (contract.Converter != null)
+          // class attribute converter
+          converter = contract.Converter;
+        else if ((matchingConverter = Serializer.GetMatchingConverter(contract.UnderlyingType)) != null)
+          // passed in converters
+          converter = matchingConverter;
+        else if (contract.InternalConverter != null)
+          // internally specified converter
+          converter = contract.InternalConverter;
+      }
+      return converter;
+    }
+
+    private object CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, object existingValue)
+    {
+      CheckedRead(reader);
+
+      string id = null;
+
+      if (reader.TokenType == JsonToken.PropertyName)
+      {
+        bool specialProperty;
+
+        do
+        {
+          string propertyName = reader.Value.ToString();
+
+          if (string.Equals(propertyName, JsonTypeReflector.RefPropertyName, StringComparison.Ordinal))
+          {
+            CheckedRead(reader);
+            if (reader.TokenType != JsonToken.String)
+              throw new JsonSerializationException("JSON reference {0} property must have a string value.".FormatWith(CultureInfo.InvariantCulture, JsonTypeReflector.RefPropertyName));
+
+            string reference = reader.Value.ToString();
+
+            CheckedRead(reader);
+            if (reader.TokenType == JsonToken.PropertyName)
+              throw new JsonSerializationException("Additional content found in JSON reference object. A JSON reference object should only have a {0} property.".FormatWith(CultureInfo.InvariantCulture, JsonTypeReflector.RefPropertyName));
+
+            return Serializer.ReferenceResolver.ResolveReference(this, reference);
+          }
+          else if (string.Equals(propertyName, JsonTypeReflector.TypePropertyName, StringComparison.Ordinal))
+          {
+            CheckedRead(reader);
+            string qualifiedTypeName = reader.Value.ToString();
+
+            CheckedRead(reader);
+
+            if ((((member != null) ? member.TypeNameHandling : null) ?? Serializer.TypeNameHandling) != TypeNameHandling.None)
+            {
+              string typeName;
+              string assemblyName;
+              ReflectionUtils.SplitFullyQualifiedTypeName(qualifiedTypeName, out typeName, out assemblyName);
+
+              Type specifiedType;
+              try
+              {
+                specifiedType = Serializer.Binder.BindToType(assemblyName, typeName);
+              }
+              catch (Exception ex)
+              {
+                throw new JsonSerializationException("Error resolving type specified in JSON '{0}'.".FormatWith(CultureInfo.InvariantCulture, qualifiedTypeName), ex);
+              }
+
+              if (specifiedType == null)
+                throw new JsonSerializationException("Type specified in JSON '{0}' was not resolved.".FormatWith(CultureInfo.InvariantCulture, qualifiedTypeName));
+
+              if (objectType != null && !objectType.IsAssignableFrom(specifiedType))
+                throw new JsonSerializationException("Type specified in JSON '{0}' is not compatible with '{1}'.".FormatWith(CultureInfo.InvariantCulture, specifiedType.AssemblyQualifiedName, objectType.AssemblyQualifiedName));
+
+              objectType = specifiedType;
+              contract = GetContractSafe(specifiedType);
+            }
+            specialProperty = true;
+          }
+          else if (string.Equals(propertyName, JsonTypeReflector.IdPropertyName, StringComparison.Ordinal))
+          {
+            CheckedRead(reader);
+
+            id = reader.Value.ToString();
+            CheckedRead(reader);
+            specialProperty = true;
+          }
+          else if (string.Equals(propertyName, JsonTypeReflector.ArrayValuesPropertyName, StringComparison.Ordinal))
+          {
+            CheckedRead(reader);
+            object list = CreateList(reader, objectType, contract, member, existingValue, id);
+            CheckedRead(reader);
+            return list;
+          }
+          else
+          {
+            specialProperty = false;
+          }
+        } while (specialProperty
+                 && reader.TokenType == JsonToken.PropertyName);
+      }
+
+      if (!HasDefinedType(objectType))
+        return CreateJObject(reader);
+
+      if (contract == null)
+        throw new JsonSerializationException("Could not resolve type '{0}' to a JsonContract.".FormatWith(CultureInfo.InvariantCulture, objectType));
+
+      JsonDictionaryContract dictionaryContract = contract as JsonDictionaryContract;
+      if (dictionaryContract != null)
+      {
+        if (existingValue == null)
+          return CreateAndPopulateDictionary(reader, dictionaryContract, id);
+
+        return PopulateDictionary(dictionaryContract.CreateWrapper(existingValue), reader, dictionaryContract, id);
+      }
+
+      JsonObjectContract objectContract = contract as JsonObjectContract;
+      if (objectContract != null)
+      {
+        if (existingValue == null)
+          return CreateAndPopulateObject(reader, objectContract, id);
+
+        return PopulateObject(existingValue, reader, objectContract, id);
+      }
+
+#if !SILVERLIGHT && !PocketPC
+      JsonISerializableContract serializableContract = contract as JsonISerializableContract;
+      if (serializableContract != null)
+      {
+        return CreateISerializable(reader, serializableContract, id);
+      }
+#endif
+
+#if !(NET35 || NET20 || WINDOWS_PHONE)
+      JsonDynamicContract dynamicContract = contract as JsonDynamicContract;
+      if (dynamicContract != null)
+      {
+        return CreateDynamic(reader, dynamicContract, id);
+      }
+#endif
+      
+      throw new JsonSerializationException("Cannot deserialize JSON object into type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType));
+    }
+
+    private JsonArrayContract EnsureArrayContract(Type objectType, JsonContract contract)
+    {
+      if (contract == null)
+        throw new JsonSerializationException("Could not resolve type '{0}' to a JsonContract.".FormatWith(CultureInfo.InvariantCulture, objectType));
+
+      JsonArrayContract arrayContract = contract as JsonArrayContract;
+      if (arrayContract == null)
+        throw new JsonSerializationException("Cannot deserialize JSON array into type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType));
+
+      return arrayContract;
+    }
+
+    private void CheckedRead(JsonReader reader)
+    {
+      if (!reader.Read())
+        throw new JsonSerializationException("Unexpected end when deserializing object.");
+    }
+
+    private object CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, object existingValue, string reference)
+    {
+      object value;
+      if (HasDefinedType(objectType))
+      {
+        JsonArrayContract arrayContract = EnsureArrayContract(objectType, contract);
+
+        if (existingValue == null)
+          value = CreateAndPopulateList(reader, reference, arrayContract);
+        else
+          value = PopulateList(arrayContract.CreateWrapper(existingValue), reader, reference, arrayContract);
+      }
+      else
+      {
+        value = CreateJToken(reader, contract);
+      }
+      return value;
+    }
+
+    private bool HasDefinedType(Type type)
+    {
+      return (type != null && type != typeof (object) && !typeof(JToken).IsAssignableFrom(type)
+#if !(NET35 || NET20 || WINDOWS_PHONE)
+        && type != typeof(IDynamicMetaObjectProvider)
+#endif
+        );
+    }
+
+    private object EnsureType(object value, CultureInfo culture, Type targetType)
+    {
+      if (targetType == null)
+        return value;
+
+      Type valueType = ReflectionUtils.GetObjectType(value);
+
+      // type of value and type of target don't match
+      // attempt to convert value's type to target's type
+      if (valueType != targetType)
+      {
+        try
+        {
+          return ConvertUtils.ConvertOrCast(value, culture, targetType);
+        }
+        catch (Exception ex)
+        {
+          throw new JsonSerializationException("Error converting value {0} to type '{1}'.".FormatWith(CultureInfo.InvariantCulture, FormatValueForPrint(value), targetType), ex);
+        }
+      }
+
+      return value;
+    }
+
+    private string FormatValueForPrint(object value)
+    {
+      if (value == null)
+        return "{null}";
+
+      if (value is string)
+        return @"""" + value + @"""";
+
+      return value.ToString();
+    }
+
+    private void SetPropertyValue(JsonProperty property, JsonReader reader, object target)
+    {
+      if (property.Ignored)
+      {
+        reader.Skip();
+        return;
+      }
+
+      object currentValue = null;
+      bool useExistingValue = false;
+      bool gottenCurrentValue = false;
+
+      ObjectCreationHandling objectCreationHandling =
+        property.ObjectCreationHandling.GetValueOrDefault(Serializer.ObjectCreationHandling);
+
+      if ((objectCreationHandling == ObjectCreationHandling.Auto || objectCreationHandling == ObjectCreationHandling.Reuse)
+        && (reader.TokenType == JsonToken.StartArray || reader.TokenType == JsonToken.StartObject)
+        && property.Readable)
+      {
+        currentValue = property.ValueProvider.GetValue(target);
+        gottenCurrentValue = true;
+
+        useExistingValue = (currentValue != null
+          && !property.PropertyType.IsArray
+          && !ReflectionUtils.InheritsGenericDefinition(property.PropertyType, typeof(ReadOnlyCollection<>))
+          && !property.PropertyType.IsValueType);
+      }
+
+      if (!property.Writable && !useExistingValue)
+      {
+        reader.Skip();
+        return;
+      }
+
+      // test tokentype here because null might not be convertable to some types, e.g. ignoring null when applied to DateTime
+      if (property.NullValueHandling.GetValueOrDefault(Serializer.NullValueHandling) == NullValueHandling.Ignore && reader.TokenType == JsonToken.Null)
+      {
+        reader.Skip();
+        return;
+      }
+
+      // test tokentype here because default value might not be convertable to actual type, e.g. default of "" for DateTime
+      if (property.DefaultValueHandling.GetValueOrDefault(Serializer.DefaultValueHandling) == DefaultValueHandling.Ignore
+        && JsonReader.IsPrimitiveToken(reader.TokenType)
+        && Equals(reader.Value, property.DefaultValue))
+      {
+        reader.Skip();
+        return;
+      }
+
+      object existingValue = (useExistingValue) ? currentValue : null;
+      object value = CreateValueProperty(reader, property, target, gottenCurrentValue, existingValue);
+
+      // always set the value if useExistingValue is false,
+      // otherwise also set it if CreateValue returns a new value compared to the currentValue
+      // this could happen because of a JsonConverter against the type
+      if ((!useExistingValue || value != currentValue)
+        && ShouldSetPropertyValue(property, value))
+      {
+        property.ValueProvider.SetValue(target, value);
+
+        if (property.SetIsSpecified != null)
+          property.SetIsSpecified(target, true);
+      }
+    }
+
+    private bool ShouldSetPropertyValue(JsonProperty property, object value)
+    {
+      if (property.NullValueHandling.GetValueOrDefault(Serializer.NullValueHandling) == NullValueHandling.Ignore && value == null)
+        return false;
+
+      if (property.DefaultValueHandling.GetValueOrDefault(Serializer.DefaultValueHandling) == DefaultValueHandling.Ignore && MiscellaneousUtils.ValueEquals(value, property.DefaultValue))
+        return false;
+
+      if (!property.Writable)
+        return false;
+
+      return true;
+    }
+
+    private object CreateAndPopulateDictionary(JsonReader reader, JsonDictionaryContract contract, string id)
+    {
+      object dictionary;
+
+      if (contract.DefaultCreator != null &&
+        (!contract.DefaultCreatorNonPublic || Serializer.ConstructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor))
+        dictionary = contract.DefaultCreator();
+      else
+        throw new JsonSerializationException("Unable to find a default constructor to use for type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
+
+      IWrappedDictionary dictionaryWrapper = contract.CreateWrapper(dictionary);
+
+      PopulateDictionary(dictionaryWrapper, reader, contract, id);
+
+      return dictionaryWrapper.UnderlyingDictionary;
+    }
+
+    private object PopulateDictionary(IWrappedDictionary dictionary, JsonReader reader, JsonDictionaryContract contract, string id)
+    {
+      if (id != null)
+        Serializer.ReferenceResolver.AddReference(this, id, dictionary.UnderlyingDictionary);
+
+      contract.InvokeOnDeserializing(dictionary.UnderlyingDictionary, Serializer.Context);
+
+      int initialDepth = reader.Depth;
+
+      do
+      {
+        switch (reader.TokenType)
+        {
+          case JsonToken.PropertyName:
+            object keyValue;
+            try
+            {
+              keyValue = EnsureType(reader.Value, CultureInfo.InvariantCulture, contract.DictionaryKeyType);
+            }
+            catch (Exception ex)
+            {
+              throw new JsonSerializationException("Could not convert string '{0}' to dictionary key type '{1}'. Create a TypeConverter to convert from the string to the key type object.".FormatWith(CultureInfo.InvariantCulture, reader.Value, contract.DictionaryKeyType), ex);
+            }
+
+            if (!ReadForType(reader, contract.DictionaryValueType, null))
+              throw new JsonSerializationException("Unexpected end when deserializing object.");
+
+            try
+            {
+              dictionary[keyValue] = CreateValueNonProperty(reader, contract.DictionaryValueType, GetContractSafe(contract.DictionaryValueType));
+            }
+            catch (Exception ex)
+            {
+              if (IsErrorHandled(dictionary, contract, keyValue, ex))
+                HandleError(reader, initialDepth);
+              else
+                throw;
+            }
+            break;
+          case JsonToken.Comment:
+            break;
+          case JsonToken.EndObject:
+            contract.InvokeOnDeserialized(dictionary.UnderlyingDictionary, Serializer.Context);
+            
+            return dictionary.UnderlyingDictionary;
+          default:
+            throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType);
+        }
+      } while (reader.Read());
+
+      throw new JsonSerializationException("Unexpected end when deserializing object.");
+    }
+
+    private object CreateAndPopulateList(JsonReader reader, string reference, JsonArrayContract contract)
+    {
+      return CollectionUtils.CreateAndPopulateList(contract.CreatedType, (l, isTemporaryListReference) =>
+        {
+          if (reference != null && isTemporaryListReference)
+            throw new JsonSerializationException("Cannot preserve reference to array or readonly list: {0}".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
+
+#if !PocketPC
+          if (contract.OnSerializing != null && isTemporaryListReference)
+            throw new JsonSerializationException("Cannot call OnSerializing on an array or readonly list: {0}".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
+#endif
+          if (contract.OnError != null && isTemporaryListReference)
+            throw new JsonSerializationException("Cannot call OnError on an array or readonly list: {0}".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
+
+          PopulateList(contract.CreateWrapper(l), reader, reference, contract);
+        });
+    }
+
+    private bool ReadForTypeArrayHack(JsonReader reader, Type t)
+    {
+      // this is a nasty hack because calling ReadAsDecimal for example will error when we hit the end of the array
+      // need to think of a better way of doing this
+      try
+      {
+        return ReadForType(reader, t, null);
+      }
+      catch (JsonReaderException)
+      {
+        if (reader.TokenType == JsonToken.EndArray)
+          return true;
+
+        throw;
+      }
+    }
+
+    private object PopulateList(IWrappedCollection wrappedList, JsonReader reader, string reference, JsonArrayContract contract)
+    {
+      object list = wrappedList.UnderlyingCollection;
+
+      if (reference != null)
+        Serializer.ReferenceResolver.AddReference(this, reference, list);
+
+      contract.InvokeOnDeserializing(list, Serializer.Context);
+
+      int initialDepth = reader.Depth;
+
+      while (ReadForTypeArrayHack(reader, contract.CollectionItemType))
+      {
+        switch (reader.TokenType)
+        {
+          case JsonToken.EndArray:
+            contract.InvokeOnDeserialized(list, Serializer.Context);
+
+            return wrappedList.UnderlyingCollection;
+          case JsonToken.Comment:
+            break;
+          default:
+            try
+            {
+              object value = CreateValueNonProperty(reader, contract.CollectionItemType, GetContractSafe(contract.CollectionItemType));
+
+              wrappedList.Add(value);
+            }
+            catch (Exception ex)
+            {
+              if (IsErrorHandled(list, contract, wrappedList.Count, ex))
+                HandleError(reader, initialDepth);
+              else
+                throw;
+            }
+            break;
+        }
+      }
+
+      throw new JsonSerializationException("Unexpected end when deserializing array.");
+    }
+
+#if !SILVERLIGHT && !PocketPC
+    private object CreateISerializable(JsonReader reader, JsonISerializableContract contract, string id)
+    {
+      Type objectType = contract.UnderlyingType;
+
+      SerializationInfo serializationInfo = new SerializationInfo(contract.UnderlyingType, GetFormatterConverter());
+
+      bool exit = false;
+      do
+      {
+        switch (reader.TokenType)
+        {
+          case JsonToken.PropertyName:
+            string memberName = reader.Value.ToString();
+            if (!reader.Read())
+              throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));
+
+            serializationInfo.AddValue(memberName, JToken.ReadFrom(reader));
+            break;
+          case JsonToken.Comment:
+            break;
+          case JsonToken.EndObject:
+            exit = true;
+            break;
+          default:
+            throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType);
+        }
+      } while (!exit && reader.Read());
+
+      if (contract.ISerializableCreator == null)
+        throw new JsonSerializationException("ISerializable type '{0}' does not have a valid constructor.".FormatWith(CultureInfo.InvariantCulture, objectType));
+
+      object createdObject = contract.ISerializableCreator(serializationInfo, Serializer.Context);
+
+      if (id != null)
+        Serializer.ReferenceResolver.AddReference(this, id, createdObject);
+
+      // these are together because OnDeserializing takes an object but for an ISerializable the object is full created in the constructor
+      contract.InvokeOnDeserializing(createdObject, Serializer.Context);
+      contract.InvokeOnDeserialized(createdObject, Serializer.Context);
+
+      return createdObject;
+    }
+#endif
+
+#if !(NET35 || NET20 || WINDOWS_PHONE)
+    private object CreateDynamic(JsonReader reader, JsonDynamicContract contract, string id)
+    {
+      IDynamicMetaObjectProvider newObject = null;
+
+      if (contract.UnderlyingType.IsInterface || contract.UnderlyingType.IsAbstract)
+        throw new JsonSerializationException("Could not create an instance of type {0}. Type is an interface or abstract class and cannot be instantated.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
+
+      if (contract.DefaultCreator != null &&
+        (!contract.DefaultCreatorNonPublic || Serializer.ConstructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor))
+        newObject = (IDynamicMetaObjectProvider)contract.DefaultCreator();
+      else
+        throw new JsonSerializationException("Unable to find a default constructor to use for type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
+
+      if (id != null)
+        Serializer.ReferenceResolver.AddReference(this, id, newObject);
+
+      contract.InvokeOnDeserializing(newObject, Serializer.Context);
+      
+      bool exit = false;
+      do
+      {
+        switch (reader.TokenType)
+        {
+          case JsonToken.PropertyName:
+            string memberName = reader.Value.ToString();
+            if (!reader.Read())
+              throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));
+
+            // first attempt to find a settable property, otherwise fall back to a dynamic set without type
+            JsonProperty property = contract.Properties.GetClosestMatchProperty(memberName);
+            if (property != null && property.Writable && !property.Ignored)
+            {
+              SetPropertyValue(property, reader, newObject);
+            }
+            else
+            {
+              Type t = (JsonReader.IsPrimitiveToken(reader.TokenType)) ? reader.ValueType : typeof (IDynamicMetaObjectProvider);
+
+              object value = CreateValueNonProperty(reader, t, GetContractSafe(t, null));
+
+              newObject.TrySetMember(memberName, value);
+            }
+            break;
+          case JsonToken.EndObject:
+            exit = true;
+            break;
+          default:
+            throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType);
+        }
+      } while (!exit && reader.Read());
+
+      contract.InvokeOnDeserialized(newObject, Serializer.Context);
+
+      return newObject;
+    }
+#endif
+
+    private object CreateAndPopulateObject(JsonReader reader, JsonObjectContract contract, string id)
+    {
+      object newObject = null;
+
+      if (contract.UnderlyingType.IsInterface || contract.UnderlyingType.IsAbstract)
+        throw new JsonSerializationException("Could not create an instance of type {0}. Type is an interface or abstract class and cannot be instantated.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
+
+      if (contract.OverrideConstructor != null)
+      {
+        if (contract.OverrideConstructor.GetParameters().Length > 0)
+          return CreateObjectFromNonDefaultConstructor(reader, contract, contract.OverrideConstructor, id);
+
+        newObject = contract.OverrideConstructor.Invoke(null);
+      }
+      else if (contract.DefaultCreator != null &&
+        (!contract.DefaultCreatorNonPublic || Serializer.ConstructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor))
+      {
+        newObject = contract.DefaultCreator();
+      }
+      else if (contract.ParametrizedConstructor != null)
+      {
+        return CreateObjectFromNonDefaultConstructor(reader, contract, contract.ParametrizedConstructor, id);
+      }
+
+      if (newObject == null)
+        throw new JsonSerializationException("Unable to find a constructor to use for type {0}. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
+
+      PopulateObject(newObject, reader, contract, id);
+      return newObject;
+    }
+
+    private object CreateObjectFromNonDefaultConstructor(JsonReader reader, JsonObjectContract contract, ConstructorInfo constructorInfo, string id)
+    {
+      ValidationUtils.ArgumentNotNull(constructorInfo, "constructorInfo");
+
+      Type objectType = contract.UnderlyingType;
+
+      IDictionary<JsonProperty, object> propertyValues = new Dictionary<JsonProperty, object>();
+
+      bool exit = false;
+      do
+      {
+        switch (reader.TokenType)
+        {
+          case JsonToken.PropertyName:
+            string memberName = reader.Value.ToString();
+
+            // attempt exact case match first
+            // then try match ignoring case
+            JsonProperty property = contract.Properties.GetClosestMatchProperty(memberName);
+
+            if (property != null)
+            {
+              if (!ReadForType(reader, property.PropertyType, property.Converter))
+                throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));
+
+              if (!property.Ignored)
+                propertyValues[property] = CreateValueProperty(reader, property, null, true, null);
+              else
+                reader.Skip();
+            }
+            else
+            {
+              if (!reader.Read())
+                throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));
+
+              if (Serializer.MissingMemberHandling == MissingMemberHandling.Error)
+                throw new JsonSerializationException("Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, objectType.Name));
+
+              reader.Skip();
+            }
+            break;
+          case JsonToken.Comment:
+            break;
+          case JsonToken.EndObject:
+            exit = true;
+            break;
+          default:
+            throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType);
+        }
+      } while (!exit && reader.Read());
+
+      IDictionary<ParameterInfo, object> constructorParameters = constructorInfo.GetParameters().ToDictionary(p => p, p => (object)null);
+      IDictionary<JsonProperty, object> remainingPropertyValues = new Dictionary<JsonProperty, object>();
+
+      foreach (KeyValuePair<JsonProperty, object> propertyValue in propertyValues)
+      {
+        ParameterInfo matchingConstructorParameter = constructorParameters.ForgivingCaseSensitiveFind(kv => kv.Key.Name, propertyValue.Key.PropertyName).Key;
+        if (matchingConstructorParameter != null)
+          constructorParameters[matchingConstructorParameter] = propertyValue.Value;
+        else
+          remainingPropertyValues.Add(propertyValue);
+      }
+
+      object createdObject = constructorInfo.Invoke(constructorParameters.Values.ToArray());
+
+      if (id != null)
+        Serializer.ReferenceResolver.AddReference(this, id, createdObject);
+
+      contract.InvokeOnDeserializing(createdObject, Serializer.Context);
+
+      // go through unused values and set the newly created object's properties
+      foreach (KeyValuePair<JsonProperty, object> remainingPropertyValue in remainingPropertyValues)
+      {
+        JsonProperty property = remainingPropertyValue.Key;
+        object value = remainingPropertyValue.Value;
+
+        if (ShouldSetPropertyValue(remainingPropertyValue.Key, remainingPropertyValue.Value))
+          property.ValueProvider.SetValue(createdObject, value);
+      }
+
+      contract.InvokeOnDeserialized(createdObject, Serializer.Context);
+      return createdObject;
+    }
+
+    private bool ReadForType(JsonReader reader, Type t, JsonConverter propertyConverter)
+    {
+      // don't read properties with converters as a specific value
+      // the value might be a string which will then get converted which will error if read as date for example
+      bool hasConverter = (GetConverter(GetContractSafe(t), propertyConverter) != null);
+
+      if (hasConverter)
+        return reader.Read();
+
+      if (t == typeof(byte[]))
+      {
+        reader.ReadAsBytes();
+        return true;
+      }
+      else if ((t == typeof(decimal) || t == typeof(decimal?)))
+      {
+        reader.ReadAsDecimal();
+        return true;
+      }
+#if !NET20
+      else if ((t == typeof(DateTimeOffset) || t == typeof(DateTimeOffset?)))
+      {
+        reader.ReadAsDateTimeOffset();
+        return true;
+      }
+#endif
+
+      do
+      {
+        if (!reader.Read())
+          return false;
+      } while (reader.TokenType == JsonToken.Comment);
+
+      return true;
+    }
+
+    private object PopulateObject(object newObject, JsonReader reader, JsonObjectContract contract, string id)
+    {
+      contract.InvokeOnDeserializing(newObject, Serializer.Context);
+
+      Dictionary<JsonProperty, RequiredValue> requiredProperties =
+        contract.Properties.Where(m => m.Required != Required.Default).ToDictionary(m => m, m => RequiredValue.None);
+
+      if (id != null)
+        Serializer.ReferenceResolver.AddReference(this, id, newObject);
+
+      int initialDepth = reader.Depth;
+
+      do
+      {
+        switch (reader.TokenType)
+        {
+          case JsonToken.PropertyName:
+            string memberName = reader.Value.ToString();
+
+            // attempt exact case match first
+            // then try match ignoring case
+            JsonProperty property = contract.Properties.GetClosestMatchProperty(memberName);
+
+            if (property == null)
+            {
+              if (Serializer.MissingMemberHandling == MissingMemberHandling.Error)
+                throw new JsonSerializationException("Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, contract.UnderlyingType.Name));
+
+              reader.Skip();
+              continue;
+            }
+
+            if (!ReadForType(reader, property.PropertyType, property.Converter))
+              throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));
+
+            SetRequiredProperty(reader, property, requiredProperties);
+
+            try
+            {
+              SetPropertyValue(property, reader, newObject);
+            }
+            catch (Exception ex)
+            {
+              if (IsErrorHandled(newObject, contract, memberName, ex))
+                HandleError(reader, initialDepth);
+              else
+                throw;
+            }
+            break;
+          case JsonToken.EndObject:
+            foreach (KeyValuePair<JsonProperty, RequiredValue> requiredProperty in requiredProperties)
+            {
+              if (requiredProperty.Value == RequiredValue.None)
+                throw new JsonSerializationException("Required property '{0}' not found in JSON.".FormatWith(CultureInfo.InvariantCulture, requiredProperty.Key.PropertyName));
+              if (requiredProperty.Key.Required == Required.Always && requiredProperty.Value == RequiredValue.Null)
+                throw new JsonSerializationException("Required property '{0}' expects a value but got null.".FormatWith(CultureInfo.InvariantCulture, requiredProperty.Key.PropertyName));
+            }
+
+            contract.InvokeOnDeserialized(newObject, Serializer.Context);
+            return newObject;
+          case JsonToken.Comment:
+            // ignore
+            break;
+          default:
+            throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType);
+        }
+      } while (reader.Read());
+
+      throw new JsonSerializationException("Unexpected end when deserializing object.");
+    }
+
+    private void SetRequiredProperty(JsonReader reader, JsonProperty property, Dictionary<JsonProperty, RequiredValue> requiredProperties)
+    {
+      if (property != null)
+      {
+        requiredProperties[property] = (reader.TokenType == JsonToken.Null || reader.TokenType == JsonToken.Undefined)
+          ? RequiredValue.Null
+          : RequiredValue.Value;
+      }
+    }
+
+    private void HandleError(JsonReader reader, int initialDepth)
+    {
+      ClearErrorContext();
+
+      reader.Skip();
+
+      while (reader.Depth > (initialDepth + 1))
+      {
+        reader.Read();
+      }
+    }
+
+    internal enum RequiredValue
+    {
+      None,
+      Null,
+      Value
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs
new file mode 100644 (file)
index 0000000..b929840
--- /dev/null
@@ -0,0 +1,637 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+#if !(NET35 || NET20 || WINDOWS_PHONE)
+using System.Dynamic;
+#endif
+using System.Globalization;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.Serialization.Formatters;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Utilities;
+using System.Runtime.Serialization;
+using System.Security;
+
+namespace Newtonsoft.Json.Serialization
+{
+  internal class JsonSerializerInternalWriter : JsonSerializerInternalBase
+  {
+    private JsonSerializerProxy _internalSerializer;
+    private List<object> _serializeStack;
+
+    private List<object> SerializeStack
+    {
+      get
+      {
+        if (_serializeStack == null)
+          _serializeStack = new List<object>();
+
+        return _serializeStack;
+      }
+    }
+
+    public JsonSerializerInternalWriter(JsonSerializer serializer)
+      : base(serializer)
+    {
+    }
+
+    public void Serialize(JsonWriter jsonWriter, object value)
+    {
+      if (jsonWriter == null)
+        throw new ArgumentNullException("jsonWriter");
+
+      SerializeValue(jsonWriter, value, GetContractSafe(value), null, null);
+    }
+
+    private JsonSerializerProxy GetInternalSerializer()
+    {
+      if (_internalSerializer == null)
+        _internalSerializer = new JsonSerializerProxy(this);
+
+      return _internalSerializer;
+    }
+
+    private JsonContract GetContractSafe(object value)
+    {
+      if (value == null)
+        return null;
+
+      return Serializer.ContractResolver.ResolveContract(value.GetType());
+    }
+
+    private void SerializeValue(JsonWriter writer, object value, JsonContract valueContract, JsonProperty member, JsonContract collectionValueContract)
+    {
+      JsonConverter converter = (member != null) ? member.Converter : null;
+
+      if (value == null)
+      {
+        writer.WriteNull();
+        return;
+      }
+
+      if ((converter != null
+          || ((converter = valueContract.Converter) != null)
+          || ((converter = Serializer.GetMatchingConverter(valueContract.UnderlyingType)) != null)
+          || ((converter = valueContract.InternalConverter) != null))
+        && converter.CanWrite)
+      {
+        SerializeConvertable(writer, converter, value, valueContract);
+      }
+      else if (valueContract is JsonPrimitiveContract)
+      {
+        writer.WriteValue(value);
+      }
+      else if (valueContract is JsonStringContract)
+      {
+        SerializeString(writer, value, (JsonStringContract)valueContract);
+      }
+      else if (valueContract is JsonObjectContract)
+      {
+        SerializeObject(writer, value, (JsonObjectContract)valueContract, member, collectionValueContract);
+      }
+      else if (valueContract is JsonDictionaryContract)
+      {
+        JsonDictionaryContract dictionaryContract = (JsonDictionaryContract)valueContract;
+        SerializeDictionary(writer, dictionaryContract.CreateWrapper(value), dictionaryContract, member, collectionValueContract);
+      }
+      else if (valueContract is JsonArrayContract)
+      {
+        JsonArrayContract arrayContract = (JsonArrayContract)valueContract;
+        SerializeList(writer, arrayContract.CreateWrapper(value), arrayContract, member, collectionValueContract);
+      }
+      else if (valueContract is JsonLinqContract)
+      {
+        ((JToken)value).WriteTo(writer, (Serializer.Converters != null) ? Serializer.Converters.ToArray() : null);
+      }
+#if !SILVERLIGHT && !PocketPC
+      else if (valueContract is JsonISerializableContract)
+      {
+        SerializeISerializable(writer, (ISerializable)value, (JsonISerializableContract)valueContract);
+      }
+#endif
+#if !(NET35 || NET20 || WINDOWS_PHONE)
+      else if (valueContract is JsonDynamicContract)
+      {
+        SerializeDynamic(writer, (IDynamicMetaObjectProvider)value, (JsonDynamicContract)valueContract);
+      }
+#endif
+    }
+
+    private bool ShouldWriteReference(object value, JsonProperty property, JsonContract contract)
+    {
+      if (value == null)
+        return false;
+      if (contract is JsonPrimitiveContract)
+        return false;
+
+      bool? isReference = null;
+
+      // value could be coming from a dictionary or array and not have a property
+      if (property != null)
+        isReference = property.IsReference;
+
+      if (isReference == null)
+        isReference = contract.IsReference;
+
+      if (isReference == null)
+      {
+        if (contract is JsonArrayContract)
+          isReference = HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Arrays);
+        else
+          isReference = HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects);
+      }
+
+      if (!isReference.Value)
+        return false;
+
+      return Serializer.ReferenceResolver.IsReferenced(this, value);
+    }
+
+    private void WriteMemberInfoProperty(JsonWriter writer, object memberValue, JsonProperty property, JsonContract contract)
+    {
+      string propertyName = property.PropertyName;
+      object defaultValue = property.DefaultValue;
+
+      if (property.NullValueHandling.GetValueOrDefault(Serializer.NullValueHandling) == NullValueHandling.Ignore &&
+          memberValue == null)
+        return;
+
+      if (property.DefaultValueHandling.GetValueOrDefault(Serializer.DefaultValueHandling) ==
+          DefaultValueHandling.Ignore && MiscellaneousUtils.ValueEquals(memberValue, defaultValue))
+        return;
+
+      if (ShouldWriteReference(memberValue, property, contract))
+      {
+        writer.WritePropertyName(propertyName);
+        WriteReference(writer, memberValue);
+        return;
+      }
+
+      if (!CheckForCircularReference(memberValue, property.ReferenceLoopHandling, contract))
+        return;
+
+      if (memberValue == null && property.Required == Required.Always)
+        throw new JsonSerializationException("Cannot write a null value for property '{0}'. Property requires a value.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName));
+
+      writer.WritePropertyName(propertyName);
+      SerializeValue(writer, memberValue, contract, property, null);
+    }
+
+    private bool CheckForCircularReference(object value, ReferenceLoopHandling? referenceLoopHandling, JsonContract contract)
+    {
+      if (value == null || contract is JsonPrimitiveContract)
+        return true;
+
+      if (SerializeStack.IndexOf(value) != -1)
+      {
+        switch (referenceLoopHandling.GetValueOrDefault(Serializer.ReferenceLoopHandling))
+        {
+          case ReferenceLoopHandling.Error:
+            throw new JsonSerializationException("Self referencing loop detected for type '{0}'.".FormatWith(CultureInfo.InvariantCulture, value.GetType()));
+          case ReferenceLoopHandling.Ignore:
+            return false;
+          case ReferenceLoopHandling.Serialize:
+            return true;
+          default:
+            throw new InvalidOperationException("Unexpected ReferenceLoopHandling value: '{0}'".FormatWith(CultureInfo.InvariantCulture, Serializer.ReferenceLoopHandling));
+        }
+      }
+
+      return true;
+    }
+
+    private void WriteReference(JsonWriter writer, object value)
+    {
+      writer.WriteStartObject();
+      writer.WritePropertyName(JsonTypeReflector.RefPropertyName);
+      writer.WriteValue(Serializer.ReferenceResolver.GetReference(this, value));
+      writer.WriteEndObject();
+    }
+
+    internal static bool TryConvertToString(object value, Type type, out string s)
+    {
+#if !PocketPC
+      TypeConverter converter = ConvertUtils.GetConverter(type);
+
+      // use the objectType's TypeConverter if it has one and can convert to a string
+      if (converter != null
+#if !SILVERLIGHT
+ && !(converter is ComponentConverter)
+#endif
+ && converter.GetType() != typeof(TypeConverter))
+      {
+        if (converter.CanConvertTo(typeof(string)))
+        {
+#if !SILVERLIGHT
+          s = converter.ConvertToInvariantString(value);
+#else
+          s = converter.ConvertToString(value);
+#endif
+          return true;
+        }
+      }
+#endif
+
+#if SILVERLIGHT || PocketPC
+      if (value is Guid || value is Uri || value is TimeSpan)
+      {
+        s = value.ToString();
+        return true;
+      }
+#endif
+
+      if (value is Type)
+      {
+        s = ((Type)value).AssemblyQualifiedName;
+        return true;
+      }
+
+      s = null;
+      return false;
+    }
+
+    private void SerializeString(JsonWriter writer, object value, JsonStringContract contract)
+    {
+      contract.InvokeOnSerializing(value, Serializer.Context);
+
+      string s;
+      TryConvertToString(value, contract.UnderlyingType, out s);
+      writer.WriteValue(s);
+
+      contract.InvokeOnSerialized(value, Serializer.Context);
+    }
+
+    private void SerializeObject(JsonWriter writer, object value, JsonObjectContract contract, JsonProperty member, JsonContract collectionValueContract)
+    {
+      contract.InvokeOnSerializing(value, Serializer.Context);
+
+      SerializeStack.Add(value);
+      writer.WriteStartObject();
+
+      bool isReference = contract.IsReference ?? HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects);
+      if (isReference)
+      {
+        writer.WritePropertyName(JsonTypeReflector.IdPropertyName);
+        writer.WriteValue(Serializer.ReferenceResolver.GetReference(this, value));
+      }
+      if (ShouldWriteType(TypeNameHandling.Objects, contract, member, collectionValueContract))
+      {
+        WriteTypeProperty(writer, contract.UnderlyingType);
+      }
+
+      int initialDepth = writer.Top;
+
+      foreach (JsonProperty property in contract.Properties)
+      {
+        try
+        {
+          if (!property.Ignored && property.Readable && ShouldSerialize(property, value) && IsSpecified(property, value))
+          {
+            object memberValue = property.ValueProvider.GetValue(value);
+            JsonContract memberContract = GetContractSafe(memberValue);
+
+            WriteMemberInfoProperty(writer, memberValue, property, memberContract);
+          }
+        }
+        catch (Exception ex)
+        {
+          if (IsErrorHandled(value, contract, property.PropertyName, ex))
+            HandleError(writer, initialDepth);
+          else
+            throw;
+        }
+      }
+
+      writer.WriteEndObject();
+      SerializeStack.RemoveAt(SerializeStack.Count - 1);
+
+      contract.InvokeOnSerialized(value, Serializer.Context);
+    }
+
+    private void WriteTypeProperty(JsonWriter writer, Type type)
+    {
+      writer.WritePropertyName(JsonTypeReflector.TypePropertyName);
+      writer.WriteValue(ReflectionUtils.GetTypeName(type, Serializer.TypeNameAssemblyFormat));
+    }
+
+    private bool HasFlag(PreserveReferencesHandling value, PreserveReferencesHandling flag)
+    {
+      return ((value & flag) == flag);
+    }
+
+    private bool HasFlag(TypeNameHandling value, TypeNameHandling flag)
+    {
+      return ((value & flag) == flag);
+    }
+
+    private void SerializeConvertable(JsonWriter writer, JsonConverter converter, object value, JsonContract contract)
+    {
+      if (ShouldWriteReference(value, null, contract))
+      {
+        WriteReference(writer, value);
+      }
+      else
+      {
+        if (!CheckForCircularReference(value, null, contract))
+          return;
+
+        SerializeStack.Add(value);
+
+        converter.WriteJson(writer, value, GetInternalSerializer());
+
+        SerializeStack.RemoveAt(SerializeStack.Count - 1);
+      }
+    }
+
+    private void SerializeList(JsonWriter writer, IWrappedCollection values, JsonArrayContract contract, JsonProperty member, JsonContract collectionValueContract)
+    {
+      contract.InvokeOnSerializing(values.UnderlyingCollection, Serializer.Context);
+
+      SerializeStack.Add(values.UnderlyingCollection);
+
+      bool isReference = contract.IsReference ?? HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Arrays);
+      bool includeTypeDetails = ShouldWriteType(TypeNameHandling.Arrays, contract, member, collectionValueContract);
+
+      if (isReference || includeTypeDetails)
+      {
+        writer.WriteStartObject();
+
+        if (isReference)
+        {
+          writer.WritePropertyName(JsonTypeReflector.IdPropertyName);
+          writer.WriteValue(Serializer.ReferenceResolver.GetReference(this, values.UnderlyingCollection));
+        }
+        if (includeTypeDetails)
+        {
+          WriteTypeProperty(writer, values.UnderlyingCollection.GetType());
+        }
+        writer.WritePropertyName(JsonTypeReflector.ArrayValuesPropertyName);
+      }
+
+      JsonContract childValuesContract = Serializer.ContractResolver.ResolveContract(contract.CollectionItemType ?? typeof(object));
+
+      writer.WriteStartArray();
+
+      int initialDepth = writer.Top;
+
+      int index = 0;
+      // note that an error in the IEnumerable won't be caught
+      foreach (object value in values)
+      {
+        try
+        {
+          JsonContract valueContract = GetContractSafe(value);
+
+          if (ShouldWriteReference(value, null, valueContract))
+          {
+            WriteReference(writer, value);
+          }
+          else
+          {
+            if (CheckForCircularReference(value, null, contract))
+            {
+              SerializeValue(writer, value, valueContract, null, childValuesContract);
+            }
+          }
+        }
+        catch (Exception ex)
+        {
+          if (IsErrorHandled(values.UnderlyingCollection, contract, index, ex))
+            HandleError(writer, initialDepth);
+          else
+            throw;
+        }
+        finally
+        {
+          index++;
+        }
+      }
+
+      writer.WriteEndArray();
+
+      if (isReference || includeTypeDetails)
+      {
+        writer.WriteEndObject();
+      }
+
+      SerializeStack.RemoveAt(SerializeStack.Count - 1);
+
+      contract.InvokeOnSerialized(values.UnderlyingCollection, Serializer.Context);
+    }
+
+#if !SILVERLIGHT && !PocketPC
+#if !NET20
+    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Portability", "CA1903:UseOnlyApiFromTargetedFramework", MessageId = "System.Security.SecuritySafeCriticalAttribute")]
+    [SecuritySafeCritical]
+#endif
+    private void SerializeISerializable(JsonWriter writer, ISerializable value, JsonISerializableContract contract)
+    {
+      contract.InvokeOnSerializing(value, Serializer.Context);
+      SerializeStack.Add(value);
+
+      writer.WriteStartObject();
+
+      SerializationInfo serializationInfo = new SerializationInfo(contract.UnderlyingType, new FormatterConverter());
+      value.GetObjectData(serializationInfo, Serializer.Context);
+
+      foreach (SerializationEntry serializationEntry in serializationInfo)
+      {
+        writer.WritePropertyName(serializationEntry.Name);
+        SerializeValue(writer, serializationEntry.Value, GetContractSafe(serializationEntry.Value), null, null);
+      }
+
+      writer.WriteEndObject();
+
+      SerializeStack.RemoveAt(SerializeStack.Count - 1);
+      contract.InvokeOnSerialized(value, Serializer.Context);
+    }
+#endif
+
+#if !(NET35 || NET20 || WINDOWS_PHONE)
+    /// <summary>
+    /// Serializes the dynamic.
+    /// </summary>
+    /// <param name="writer">The writer.</param>
+    /// <param name="value">The value.</param>
+    /// <param name="contract">The contract.</param>
+    private void SerializeDynamic(JsonWriter writer, IDynamicMetaObjectProvider value, JsonDynamicContract contract)
+    {
+      contract.InvokeOnSerializing(value, Serializer.Context);
+      SerializeStack.Add(value);
+
+      writer.WriteStartObject();
+
+      foreach (string memberName in value.GetDynamicMemberNames())
+      {
+        object memberValue;
+        if (DynamicUtils.TryGetMember(value, memberName, out memberValue))
+        {
+          string resolvedPropertyName = (contract.PropertyNameResolver != null)
+            ? contract.PropertyNameResolver(memberName)
+            : memberName;
+          
+          writer.WritePropertyName(resolvedPropertyName);
+          SerializeValue(writer, memberValue, GetContractSafe(memberValue), null, null);
+        }
+      }
+
+      writer.WriteEndObject();
+
+      SerializeStack.RemoveAt(SerializeStack.Count - 1);
+      contract.InvokeOnSerialized(value, Serializer.Context);
+    }
+#endif
+
+    private bool ShouldWriteType(TypeNameHandling typeNameHandlingFlag, JsonContract contract, JsonProperty member, JsonContract collectionValueContract)
+    {
+      if (HasFlag(((member != null) ? member.TypeNameHandling : null) ?? Serializer.TypeNameHandling, typeNameHandlingFlag))
+        return true;
+
+      if (member != null)
+      {
+        if ((member.TypeNameHandling ?? Serializer.TypeNameHandling) == TypeNameHandling.Auto && contract.UnderlyingType != member.PropertyType)
+          return true;
+      }
+      else if (collectionValueContract != null)
+      {
+        if (Serializer.TypeNameHandling == TypeNameHandling.Auto && contract.UnderlyingType != collectionValueContract.UnderlyingType)
+          return true;
+      }
+
+      return false;
+    }
+
+    private void SerializeDictionary(JsonWriter writer, IWrappedDictionary values, JsonDictionaryContract contract, JsonProperty member, JsonContract collectionValueContract)
+    {
+      contract.InvokeOnSerializing(values.UnderlyingDictionary, Serializer.Context);
+
+      SerializeStack.Add(values.UnderlyingDictionary);
+      writer.WriteStartObject();
+
+      bool isReference = contract.IsReference ?? HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects);
+      if (isReference)
+      {
+        writer.WritePropertyName(JsonTypeReflector.IdPropertyName);
+        writer.WriteValue(Serializer.ReferenceResolver.GetReference(this, values.UnderlyingDictionary));
+      }
+      if (ShouldWriteType(TypeNameHandling.Objects, contract, member, collectionValueContract))
+      {
+        WriteTypeProperty(writer, values.UnderlyingDictionary.GetType());
+      }
+
+      JsonContract childValuesContract = Serializer.ContractResolver.ResolveContract(contract.DictionaryValueType ?? typeof(object));
+
+      int initialDepth = writer.Top;
+
+      // Mono Unity 3.0 fix
+      IDictionary d = values;
+
+      foreach (DictionaryEntry entry in d)
+      {
+        string propertyName = GetPropertyName(entry);
+
+        propertyName = (contract.PropertyNameResolver != null)
+                         ? contract.PropertyNameResolver(propertyName)
+                         : propertyName;
+
+        try
+        {
+          object value = entry.Value;
+          JsonContract valueContract = GetContractSafe(value);
+
+          if (ShouldWriteReference(value, null, valueContract))
+          {
+            writer.WritePropertyName(propertyName);
+            WriteReference(writer, value);
+          }
+          else
+          {
+            if (!CheckForCircularReference(value, null, contract))
+              continue;
+
+            writer.WritePropertyName(propertyName);
+
+            SerializeValue(writer, value, valueContract, null, childValuesContract);
+          }
+        }
+        catch (Exception ex)
+        {
+          if (IsErrorHandled(values.UnderlyingDictionary, contract, propertyName, ex))
+            HandleError(writer, initialDepth);
+          else
+            throw;
+        }
+      }
+
+      writer.WriteEndObject();
+      SerializeStack.RemoveAt(SerializeStack.Count - 1);
+
+      contract.InvokeOnSerialized(values.UnderlyingDictionary, Serializer.Context);
+    }
+
+    private string GetPropertyName(DictionaryEntry entry)
+    {
+      string propertyName;
+
+      if (entry.Key is IConvertible)
+        return Convert.ToString(entry.Key, CultureInfo.InvariantCulture);
+      else if (TryConvertToString(entry.Key, entry.Key.GetType(), out propertyName))
+        return propertyName;
+      else
+        return entry.Key.ToString();
+    }
+
+    private void HandleError(JsonWriter writer, int initialDepth)
+    {
+      ClearErrorContext();
+
+      while (writer.Top > initialDepth)
+      {
+        writer.WriteEnd();
+      }
+    }
+
+    private bool ShouldSerialize(JsonProperty property, object target)
+    {
+      if (property.ShouldSerialize == null)
+        return true;
+
+      return property.ShouldSerialize(target);
+    }
+
+    private bool IsSpecified(JsonProperty property, object target)
+    {
+      if (property.GetIsSpecified == null)
+        return true;
+
+      return property.GetIsSpecified(target);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonSerializerProxy.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonSerializerProxy.cs
new file mode 100644 (file)
index 0000000..304da80
--- /dev/null
@@ -0,0 +1,176 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Runtime.Serialization.Formatters;
+using Newtonsoft.Json.Utilities;
+using System.Runtime.Serialization;
+
+namespace Newtonsoft.Json.Serialization
+{
+  internal class JsonSerializerProxy : JsonSerializer
+  {
+    private readonly JsonSerializerInternalReader _serializerReader;
+    private readonly JsonSerializerInternalWriter _serializerWriter;
+    private readonly JsonSerializer _serializer;
+
+    public override event EventHandler<ErrorEventArgs> Error
+    {
+      add { _serializer.Error += value; }
+      remove { _serializer.Error -= value; }
+    }
+
+    public override IReferenceResolver ReferenceResolver
+    {
+      get { return _serializer.ReferenceResolver; }
+      set { _serializer.ReferenceResolver = value; }
+    }
+
+    public override JsonConverterCollection Converters
+    {
+      get { return _serializer.Converters; }
+    }
+
+    public override DefaultValueHandling DefaultValueHandling
+    {
+      get { return _serializer.DefaultValueHandling; }
+      set { _serializer.DefaultValueHandling = value; }
+    }
+
+    public override IContractResolver ContractResolver
+    {
+      get { return _serializer.ContractResolver; }
+      set { _serializer.ContractResolver = value; }
+    }
+
+    public override MissingMemberHandling MissingMemberHandling
+    {
+      get { return _serializer.MissingMemberHandling; }
+      set { _serializer.MissingMemberHandling = value; }
+    }
+
+    public override NullValueHandling NullValueHandling
+    {
+      get { return _serializer.NullValueHandling; }
+      set { _serializer.NullValueHandling = value; }
+    }
+
+    public override ObjectCreationHandling ObjectCreationHandling
+    {
+      get { return _serializer.ObjectCreationHandling; }
+      set { _serializer.ObjectCreationHandling = value; }
+    }
+
+    public override ReferenceLoopHandling ReferenceLoopHandling
+    {
+      get { return _serializer.ReferenceLoopHandling; }
+      set { _serializer.ReferenceLoopHandling = value; }
+    }
+
+    public override PreserveReferencesHandling PreserveReferencesHandling
+    {
+      get { return _serializer.PreserveReferencesHandling; }
+      set { _serializer.PreserveReferencesHandling = value; }
+    }
+
+    public override TypeNameHandling TypeNameHandling
+    {
+      get { return _serializer.TypeNameHandling; }
+      set { _serializer.TypeNameHandling = value; }
+    }
+
+    public override FormatterAssemblyStyle TypeNameAssemblyFormat
+    {
+      get { return _serializer.TypeNameAssemblyFormat; }
+      set { _serializer.TypeNameAssemblyFormat = value; }
+    }
+
+    public override ConstructorHandling ConstructorHandling
+    {
+      get { return _serializer.ConstructorHandling; }
+      set { _serializer.ConstructorHandling = value; }
+    }
+
+    public override SerializationBinder Binder
+    {
+      get { return _serializer.Binder; }
+      set { _serializer.Binder = value; }
+    }
+
+    public override StreamingContext Context
+    {
+      get { return _serializer.Context; }
+      set { _serializer.Context = value; }
+    }
+
+    internal JsonSerializerInternalBase GetInternalSerializer()
+    {
+      if (_serializerReader != null)
+        return _serializerReader;
+      else
+        return _serializerWriter;
+    }
+
+    public JsonSerializerProxy(JsonSerializerInternalReader serializerReader)
+    {
+      ValidationUtils.ArgumentNotNull(serializerReader, "serializerReader");
+
+      _serializerReader = serializerReader;
+      _serializer = serializerReader.Serializer;
+    }
+
+    public JsonSerializerProxy(JsonSerializerInternalWriter serializerWriter)
+    {
+      ValidationUtils.ArgumentNotNull(serializerWriter, "serializerWriter");
+
+      _serializerWriter = serializerWriter;
+      _serializer = serializerWriter.Serializer;
+    }
+
+    internal override object DeserializeInternal(JsonReader reader, Type objectType)
+    {
+      if (_serializerReader != null)
+        return _serializerReader.Deserialize(reader, objectType);
+      else
+        return _serializer.Deserialize(reader, objectType);
+    }
+
+    internal override void PopulateInternal(JsonReader reader, object target)
+    {
+      if (_serializerReader != null)
+        _serializerReader.Populate(reader, target);
+      else
+        _serializer.Populate(reader, target);
+    }
+
+    internal override void SerializeInternal(JsonWriter jsonWriter, object value)
+    {
+      if (_serializerWriter != null)
+        _serializerWriter.Serialize(jsonWriter, value);
+      else
+        _serializer.Serialize(jsonWriter, value);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonStringContract.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonStringContract.cs
new file mode 100644 (file)
index 0000000..4a0c5fb
--- /dev/null
@@ -0,0 +1,47 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Contract details for a <see cref="Type"/> used by the <see cref="JsonSerializer"/>.
+  /// </summary>
+  public class JsonStringContract : JsonContract
+  {
+    /// <summary>
+    /// Initializes a new instance of the <see cref="JsonStringContract"/> class.
+    /// </summary>
+    /// <param name="underlyingType">The underlying type for the contract.</param>
+    public JsonStringContract(Type underlyingType)
+      : base(underlyingType)
+    {
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs
new file mode 100644 (file)
index 0000000..93936cf
--- /dev/null
@@ -0,0 +1,301 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.ComponentModel;
+using System.Globalization;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.Serialization;
+using System.Security.Permissions;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Serialization
+{
+#if !SILVERLIGHT && !PocketPC && !NET20
+  internal interface IMetadataTypeAttribute
+  {
+    Type MetadataClassType { get; }
+  }
+#endif
+
+  internal static class JsonTypeReflector
+  {
+    public const string IdPropertyName = "$id";
+    public const string RefPropertyName = "$ref";
+    public const string TypePropertyName = "$type";
+    public const string ArrayValuesPropertyName = "$values";
+
+    public const string ShouldSerializePrefix = "ShouldSerialize";
+    public const string SpecifiedPostfix = "Specified";
+
+    private static readonly ThreadSafeStore<ICustomAttributeProvider, Type> JsonConverterTypeCache = new ThreadSafeStore<ICustomAttributeProvider, Type>(GetJsonConverterTypeFromAttribute);
+#if !SILVERLIGHT && !PocketPC && !NET20
+    private static readonly ThreadSafeStore<Type, Type> AssociatedMetadataTypesCache = new ThreadSafeStore<Type, Type>(GetAssociateMetadataTypeFromAttribute);
+
+    private const string MetadataTypeAttributeTypeName =
+      "System.ComponentModel.DataAnnotations.MetadataTypeAttribute, System.ComponentModel.DataAnnotations, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";
+    private static Type _cachedMetadataTypeAttributeType;
+#endif
+#if SILVERLIGHT
+    private static readonly ThreadSafeStore<ICustomAttributeProvider, Type> TypeConverterTypeCache = new ThreadSafeStore<ICustomAttributeProvider, Type>(GetTypeConverterTypeFromAttribute);
+
+    private static Type GetTypeConverterTypeFromAttribute(ICustomAttributeProvider attributeProvider)
+    {
+      TypeConverterAttribute converterAttribute = GetAttribute<TypeConverterAttribute>(attributeProvider);
+      if (converterAttribute == null)
+        return null;
+
+      return Type.GetType(converterAttribute.ConverterTypeName);
+    }
+
+    private static Type GetTypeConverterType(ICustomAttributeProvider attributeProvider)
+    {
+      return TypeConverterTypeCache.Get(attributeProvider);
+    }
+#endif
+
+    public static JsonContainerAttribute GetJsonContainerAttribute(Type type)
+    {
+      return CachedAttributeGetter<JsonContainerAttribute>.GetAttribute(type);
+    }
+
+    public static JsonObjectAttribute GetJsonObjectAttribute(Type type)
+    {
+      return GetJsonContainerAttribute(type) as JsonObjectAttribute;
+    }
+
+    public static JsonArrayAttribute GetJsonArrayAttribute(Type type)
+    {
+      return GetJsonContainerAttribute(type) as JsonArrayAttribute;
+    }
+
+#if !PocketPC && !NET20
+    public static DataContractAttribute GetDataContractAttribute(Type type)
+    {
+      return CachedAttributeGetter<DataContractAttribute>.GetAttribute(type);
+    }
+#endif
+
+    public static MemberSerialization GetObjectMemberSerialization(Type objectType)
+    {
+      JsonObjectAttribute objectAttribute = GetJsonObjectAttribute(objectType);
+
+      if (objectAttribute == null)
+      {
+#if !PocketPC && !NET20
+        DataContractAttribute dataContractAttribute = GetDataContractAttribute(objectType);
+
+        if (dataContractAttribute != null)
+          return MemberSerialization.OptIn;
+#endif
+
+        return MemberSerialization.OptOut;
+      }
+
+      return objectAttribute.MemberSerialization;
+    }
+
+    private static Type GetJsonConverterType(ICustomAttributeProvider attributeProvider)
+    {
+      return JsonConverterTypeCache.Get(attributeProvider);
+    }
+
+    private static Type GetJsonConverterTypeFromAttribute(ICustomAttributeProvider attributeProvider)
+    {
+      JsonConverterAttribute converterAttribute = GetAttribute<JsonConverterAttribute>(attributeProvider);
+      return (converterAttribute != null)
+        ? converterAttribute.ConverterType
+        : null;
+    }
+
+    public static JsonConverter GetJsonConverter(ICustomAttributeProvider attributeProvider, Type targetConvertedType)
+    {
+      Type converterType = GetJsonConverterType(attributeProvider);
+
+      if (converterType != null)
+      {
+        JsonConverter memberConverter = JsonConverterAttribute.CreateJsonConverterInstance(converterType);
+
+        if (!memberConverter.CanConvert(targetConvertedType))
+          throw new JsonSerializationException("JsonConverter {0} on {1} is not compatible with member type {2}.".FormatWith(CultureInfo.InvariantCulture, memberConverter.GetType().Name, attributeProvider, targetConvertedType.Name));
+
+        return memberConverter;
+      }
+
+      return null;
+    }
+
+#if !PocketPC
+    public static TypeConverter GetTypeConverter(Type type)
+    {
+#if !SILVERLIGHT
+      return TypeDescriptor.GetConverter(type);
+#else
+      Type converterType = GetTypeConverterType(type);
+
+      if (converterType != null)
+        return (TypeConverter)ReflectionUtils.CreateInstance(converterType);
+
+      return null;
+#endif
+    }
+#endif
+
+#if !SILVERLIGHT && !PocketPC && !NET20
+    private static Type GetAssociatedMetadataType(Type type)
+    {
+      return AssociatedMetadataTypesCache.Get(type);
+    }
+
+    private static Type GetAssociateMetadataTypeFromAttribute(Type type)
+    {
+      Type metadataTypeAttributeType = GetMetadataTypeAttributeType();
+      if (metadataTypeAttributeType == null)
+        return null;
+
+      object attribute = type.GetCustomAttributes(metadataTypeAttributeType, true).SingleOrDefault();
+      if (attribute == null)
+        return null;
+
+      IMetadataTypeAttribute metadataTypeAttribute = (DynamicCodeGeneration)
+                                                       ? DynamicWrapper.CreateWrapper<IMetadataTypeAttribute>(attribute)
+                                                       : new LateBoundMetadataTypeAttribute(attribute);
+
+      return metadataTypeAttribute.MetadataClassType;
+    }
+
+    private static Type GetMetadataTypeAttributeType()
+    {
+      // always attempt to get the metadata type attribute type
+      // the assembly may have been loaded since last time
+      if (_cachedMetadataTypeAttributeType == null)
+      {
+        Type metadataTypeAttributeType = Type.GetType(MetadataTypeAttributeTypeName);
+
+        if (metadataTypeAttributeType != null)
+          _cachedMetadataTypeAttributeType = metadataTypeAttributeType;
+        else
+          return null;
+      }
+      
+      return _cachedMetadataTypeAttributeType;
+    }
+
+    private static T GetAttribute<T>(Type type) where T : Attribute
+    {
+      Type metadataType = GetAssociatedMetadataType(type);
+      if (metadataType != null)
+      {
+        T attribute = ReflectionUtils.GetAttribute<T>(metadataType, true);
+        if (attribute != null)
+          return attribute;
+      }
+
+      return ReflectionUtils.GetAttribute<T>(type, true);
+    }
+
+    private static T GetAttribute<T>(MemberInfo memberInfo) where T : Attribute
+    {
+      Type metadataType = GetAssociatedMetadataType(memberInfo.DeclaringType);
+      if (metadataType != null)
+      {
+        MemberInfo metadataTypeMemberInfo = metadataType.GetMember(memberInfo.Name,
+          memberInfo.MemberType,
+          BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance).SingleOrDefault();
+
+        if (metadataTypeMemberInfo != null)
+        {
+          T attribute = ReflectionUtils.GetAttribute<T>(metadataTypeMemberInfo, true);
+          if (attribute != null)
+            return attribute;
+        }
+      }
+
+      return ReflectionUtils.GetAttribute<T>(memberInfo, true);
+    }
+
+    public static T GetAttribute<T>(ICustomAttributeProvider attributeProvider) where T : Attribute
+    {
+      Type type = attributeProvider as Type;
+      if (type != null)
+        return GetAttribute<T>(type);
+
+      MemberInfo memberInfo = attributeProvider as MemberInfo;
+      if (memberInfo != null)
+        return GetAttribute<T>(memberInfo);
+
+      return ReflectionUtils.GetAttribute<T>(attributeProvider, true);
+    }
+#else
+    public static T GetAttribute<T>(ICustomAttributeProvider attributeProvider) where T : Attribute
+    {
+      return ReflectionUtils.GetAttribute<T>(attributeProvider, true);
+    }
+#endif
+
+    private static bool? _dynamicCodeGeneration;
+
+    public static bool DynamicCodeGeneration
+    {
+      get
+      {
+        if (_dynamicCodeGeneration == null)
+        {
+#if !PocketPC && !SILVERLIGHT
+          try
+          {
+            new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand();
+            new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess).Demand();
+            new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
+            _dynamicCodeGeneration = true;
+          }
+          catch (Exception)
+          {
+            _dynamicCodeGeneration = false;
+          }
+#else
+          _dynamicCodeGeneration = false;
+#endif
+        }
+
+        return _dynamicCodeGeneration.Value;
+      }
+    }
+
+    public static ReflectionDelegateFactory ReflectionDelegateFactory
+    {
+      get
+      {
+#if !PocketPC && !SILVERLIGHT
+        if (DynamicCodeGeneration)
+          return DynamicReflectionDelegateFactory.Instance;
+#endif
+
+        return LateBoundReflectionDelegateFactory.Instance;
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/LateBoundMetadataTypeAttribute.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/LateBoundMetadataTypeAttribute.cs
new file mode 100644 (file)
index 0000000..106f854
--- /dev/null
@@ -0,0 +1,59 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+#if !SILVERLIGHT && !PocketPC && !NET20
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Utilities;
+using System.Reflection;
+
+namespace Newtonsoft.Json.Serialization
+{
+  internal class LateBoundMetadataTypeAttribute : IMetadataTypeAttribute
+  {
+    private static PropertyInfo _metadataClassTypeProperty;
+
+    private readonly object _attribute;
+
+    public LateBoundMetadataTypeAttribute(object attribute)
+    {
+      _attribute = attribute;
+    }
+
+    public Type MetadataClassType
+    {
+      get
+      {
+        if (_metadataClassTypeProperty == null)
+          _metadataClassTypeProperty = _attribute.GetType().GetProperty("MetadataClassType");
+
+        return (Type)ReflectionUtils.GetMemberValue(_metadataClassTypeProperty, _attribute);
+      }
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/ObjectConstructor.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/ObjectConstructor.cs
new file mode 100644 (file)
index 0000000..75f5387
--- /dev/null
@@ -0,0 +1,32 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Represents a method that constructs an object.
+  /// </summary>
+  public delegate object ObjectConstructor<T>(params object[] args);
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/OnErrorAttribute.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/OnErrorAttribute.cs
new file mode 100644 (file)
index 0000000..73e2df0
--- /dev/null
@@ -0,0 +1,37 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// When applied to a method, specifies that the method is called when an error occurs serializing an object.
+  /// </summary>
+  [AttributeUsage(AttributeTargets.Method, Inherited = false)]
+  public sealed class OnErrorAttribute : Attribute
+  {
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/ReflectionValueProvider.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Serialization/ReflectionValueProvider.cs
new file mode 100644 (file)
index 0000000..148c98a
--- /dev/null
@@ -0,0 +1,87 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using Newtonsoft.Json.Utilities;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Serialization
+{
+  /// <summary>
+  /// Get and set values for a <see cref="MemberInfo"/> using reflection.
+  /// </summary>
+  public class ReflectionValueProvider : IValueProvider
+  {
+    private readonly MemberInfo _memberInfo;
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="ReflectionValueProvider"/> class.
+    /// </summary>
+    /// <param name="memberInfo">The member info.</param>
+    public ReflectionValueProvider(MemberInfo memberInfo)
+    {
+      ValidationUtils.ArgumentNotNull(memberInfo, "memberInfo");
+      _memberInfo = memberInfo;
+    }
+
+    /// <summary>
+    /// Sets the value.
+    /// </summary>
+    /// <param name="target">The target to set the value on.</param>
+    /// <param name="value">The value to set on the target.</param>
+    public void SetValue(object target, object value)
+    {
+      try
+      {
+        ReflectionUtils.SetMemberValue(_memberInfo, target, value);
+      }
+      catch (Exception ex)
+      {
+        throw new JsonSerializationException("Error setting value to '{0}' on '{1}'.".FormatWith(CultureInfo.InvariantCulture, _memberInfo.Name, target.GetType()), ex);
+      }
+    }
+
+    /// <summary>
+    /// Gets the value.
+    /// </summary>
+    /// <param name="target">The target to get the value from.</param>
+    /// <returns>The value.</returns>
+    public object GetValue(object target)
+    {
+      try
+      {
+        return ReflectionUtils.GetMemberValue(_memberInfo, target);
+      }
+      catch (Exception ex)
+      {
+        throw new JsonSerializationException("Error getting value from '{0}' on '{1}'.".FormatWith(CultureInfo.InvariantCulture, _memberInfo.Name, target.GetType()), ex);
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/SerializationBinder.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/SerializationBinder.cs
new file mode 100644 (file)
index 0000000..b112db5
--- /dev/null
@@ -0,0 +1,21 @@
+#if SILVERLIGHT || PocketPC
+using System;
+using System.Reflection;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Allows users to control class loading and mandate what class to load.
+  /// </summary>
+  public abstract class SerializationBinder
+  {
+    /// <summary>
+    /// When overridden in a derived class, controls the binding of a serialized object to a type.
+    /// </summary>
+    /// <param name="assemblyName">Specifies the <see cref="Assembly"/> name of the serialized object.</param>
+    /// <param name="typeName">Specifies the <see cref="Type"/> name of the serialized object</param>
+    /// <returns></returns>
+    public abstract Type BindToType(string assemblyName, string typeName);
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/StreamingContext.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/StreamingContext.cs
new file mode 100644 (file)
index 0000000..a602d16
--- /dev/null
@@ -0,0 +1,64 @@
+#if PocketPC
+#pragma warning disable 1591
+
+// This class is... borrowed from .NET and Microsoft for a short time.
+// Hopefully Microsoft will add DateTimeOffset to the compact framework
+// or I will rewrite a striped down version of this file myself
+
+namespace System.Runtime.Serialization
+{
+  public enum StreamingContextStates
+  {
+    All = 255,
+    Clone = 64,
+    CrossAppDomain = 128,
+    CrossMachine = 2,
+    CrossProcess = 1,
+    File = 4,
+    Other = 32,
+    Persistence = 8,
+    Remoting = 16
+  }
+
+  public struct StreamingContext
+  {
+    internal object m_additionalContext;
+    internal StreamingContextStates m_state;
+    public StreamingContext(StreamingContextStates state)
+      : this(state, null)
+    {
+    }
+
+    public StreamingContext(StreamingContextStates state, object additional)
+    {
+      this.m_state = state;
+      this.m_additionalContext = additional;
+    }
+
+    public object Context
+    {
+      get
+      {
+        return this.m_additionalContext;
+      }
+    }
+    public override bool Equals(object obj)
+    {
+      return ((obj is StreamingContext) && ((((StreamingContext)obj).m_additionalContext == this.m_additionalContext) && (((StreamingContext)obj).m_state == this.m_state)));
+    }
+
+    public override int GetHashCode()
+    {
+      return (int)this.m_state;
+    }
+
+    public StreamingContextStates State
+    {
+      get
+      {
+        return this.m_state;
+      }
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/TypeNameHandling.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/TypeNameHandling.cs
new file mode 100644 (file)
index 0000000..9a70ab6
--- /dev/null
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json
+{
+  /// <summary>
+  /// Specifies type name handling options for the <see cref="JsonSerializer"/>.
+  /// </summary>
+  [Flags]
+  public enum TypeNameHandling
+  {
+    /// <summary>
+    /// Do not include the .NET type name when serializing types.
+    /// </summary>
+    None = 0,
+    /// <summary>
+    /// Include the .NET type name when serializing into a JSON object structure.
+    /// </summary>
+    Objects = 1,
+    /// <summary>
+    /// Include the .NET type name when serializing into a JSON array structure.
+    /// </summary>
+    Arrays = 2,
+    /// <summary>
+    /// Include the .NET type name when the type of the object being serialized is not the same as its declared type.
+    /// </summary>
+    Auto = 4,
+    /// <summary>
+    /// Always include the .NET type name when serializing.
+    /// </summary>
+    All = Objects | Arrays
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/Base64Encoder.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/Base64Encoder.cs
new file mode 100644 (file)
index 0000000..af83816
--- /dev/null
@@ -0,0 +1,95 @@
+using System;
+using System.IO;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal class Base64Encoder
+  {
+    private const int Base64LineSize = 76;
+    private const int LineSizeInBytes = 57;
+
+    private readonly char[] _charsLine = new char[Base64LineSize];
+    private readonly TextWriter _writer;
+
+    private byte[] _leftOverBytes;
+    private int _leftOverBytesCount;
+
+    public Base64Encoder(TextWriter writer)
+    {
+      ValidationUtils.ArgumentNotNull(writer, "writer");
+      _writer = writer;
+    }
+
+    public void Encode(byte[] buffer, int index, int count)
+    {
+      if (buffer == null)
+        throw new ArgumentNullException("buffer");
+
+      if (index < 0)
+        throw new ArgumentOutOfRangeException("index");
+
+      if (count < 0)
+        throw new ArgumentOutOfRangeException("count");
+
+      if (count > (buffer.Length - index))
+        throw new ArgumentOutOfRangeException("count");
+
+      if (_leftOverBytesCount > 0)
+      {
+        int leftOverBytesCount = _leftOverBytesCount;
+        while (leftOverBytesCount < 3 && count > 0)
+        {
+          _leftOverBytes[leftOverBytesCount++] = buffer[index++];
+          count--;
+        }
+        if (count == 0 && leftOverBytesCount < 3)
+        {
+          _leftOverBytesCount = leftOverBytesCount;
+          return;
+        }
+        int num2 = Convert.ToBase64CharArray(_leftOverBytes, 0, 3, _charsLine, 0);
+        WriteChars(_charsLine, 0, num2);
+      }
+      _leftOverBytesCount = count % 3;
+      if (_leftOverBytesCount > 0)
+      {
+        count -= _leftOverBytesCount;
+        if (_leftOverBytes == null)
+        {
+          _leftOverBytes = new byte[3];
+        }
+        for (int i = 0; i < _leftOverBytesCount; i++)
+        {
+          _leftOverBytes[i] = buffer[(index + count) + i];
+        }
+      }
+      int num4 = index + count;
+      int length = LineSizeInBytes;
+      while (index < num4)
+      {
+        if ((index + length) > num4)
+        {
+          length = num4 - index;
+        }
+        int num6 = Convert.ToBase64CharArray(buffer, index, length, _charsLine, 0);
+        WriteChars(_charsLine, 0, num6);
+        index += length;
+      }
+    }
+
+    public void Flush()
+    {
+      if (_leftOverBytesCount > 0)
+      {
+        int count = Convert.ToBase64CharArray(_leftOverBytes, 0, _leftOverBytesCount, _charsLine, 0);
+        WriteChars(_charsLine, 0, count);
+        _leftOverBytesCount = 0;
+      }
+    }
+
+    private void WriteChars(char[] chars, int index, int count)
+    {
+      _writer.Write(chars, index, count);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/BidirectionalDictionary.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/BidirectionalDictionary.cs
new file mode 100644 (file)
index 0000000..9a17023
--- /dev/null
@@ -0,0 +1,69 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal class BidirectionalDictionary<TFirst, TSecond>
+  {
+    private readonly IDictionary<TFirst, TSecond> _firstToSecond;
+    private readonly IDictionary<TSecond, TFirst> _secondToFirst;
+
+    public BidirectionalDictionary()
+      : this(EqualityComparer<TFirst>.Default, EqualityComparer<TSecond>.Default)
+    {
+    }
+
+    public BidirectionalDictionary(IEqualityComparer<TFirst> firstEqualityComparer, IEqualityComparer<TSecond> secondEqualityComparer)
+    {
+      _firstToSecond = new Dictionary<TFirst, TSecond>(firstEqualityComparer);
+      _secondToFirst = new Dictionary<TSecond, TFirst>(secondEqualityComparer);
+    }
+
+    public void Add(TFirst first, TSecond second)
+    {
+      if (_firstToSecond.ContainsKey(first) || _secondToFirst.ContainsKey(second))
+      {
+        throw new ArgumentException("Duplicate first or second");
+      }
+      _firstToSecond.Add(first, second);
+      _secondToFirst.Add(second, first);
+    }
+
+    public bool TryGetByFirst(TFirst first, out TSecond second)
+    {
+      return _firstToSecond.TryGetValue(first, out second);
+    }
+
+    public bool TryGetBySecond(TSecond second, out TFirst first)
+    {
+      return _secondToFirst.TryGetValue(second, out first);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/CollectionUtils.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/CollectionUtils.cs
new file mode 100644 (file)
index 0000000..8050053
--- /dev/null
@@ -0,0 +1,635 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Reflection;
+using System.Text;
+using System.Collections;
+using System.Linq;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal static class CollectionUtils
+  {
+    public static IEnumerable<T> CastValid<T>(this IEnumerable enumerable)
+    {
+      ValidationUtils.ArgumentNotNull(enumerable, "enumerable");
+
+      return enumerable.Cast<object>().Where(o => o is T).Cast<T>();
+    }
+
+    public static List<T> CreateList<T>(params T[] values)
+    {
+      return new List<T>(values);
+    }
+
+    /// <summary>
+    /// Determines whether the collection is null or empty.
+    /// </summary>
+    /// <param name="collection">The collection.</param>
+    /// <returns>
+    ///        <c>true</c> if the collection is null or empty; otherwise, <c>false</c>.
+    /// </returns>
+    public static bool IsNullOrEmpty(ICollection collection)
+    {
+      if (collection != null)
+      {
+        return (collection.Count == 0);
+      }
+      return true;
+    }
+
+    /// <summary>
+    /// Determines whether the collection is null or empty.
+    /// </summary>
+    /// <param name="collection">The collection.</param>
+    /// <returns>
+    ///        <c>true</c> if the collection is null or empty; otherwise, <c>false</c>.
+    /// </returns>
+    public static bool IsNullOrEmpty<T>(ICollection<T> collection)
+    {
+      if (collection != null)
+      {
+        return (collection.Count == 0);
+      }
+      return true;
+    }
+
+    /// <summary>
+    /// Determines whether the collection is null, empty or its contents are uninitialized values.
+    /// </summary>
+    /// <param name="list">The list.</param>
+    /// <returns>
+    ///        <c>true</c> if the collection is null or empty or its contents are uninitialized values; otherwise, <c>false</c>.
+    /// </returns>
+    public static bool IsNullOrEmptyOrDefault<T>(IList<T> list)
+    {
+      if (IsNullOrEmpty<T>(list))
+        return true;
+
+      return ReflectionUtils.ItemsUnitializedValue<T>(list);
+    }
+
+    /// <summary>
+    /// Makes a slice of the specified list in between the start and end indexes.
+    /// </summary>
+    /// <param name="list">The list.</param>
+    /// <param name="start">The start index.</param>
+    /// <param name="end">The end index.</param>
+    /// <returns>A slice of the list.</returns>
+    public static IList<T> Slice<T>(IList<T> list, int? start, int? end)
+    {
+      return Slice<T>(list, start, end, null);
+    }
+
+    /// <summary>
+    /// Makes a slice of the specified list in between the start and end indexes,
+    /// getting every so many items based upon the step.
+    /// </summary>
+    /// <param name="list">The list.</param>
+    /// <param name="start">The start index.</param>
+    /// <param name="end">The end index.</param>
+    /// <param name="step">The step.</param>
+    /// <returns>A slice of the list.</returns>
+    public static IList<T> Slice<T>(IList<T> list, int? start, int? end, int? step)
+    {
+      if (list == null)
+        throw new ArgumentNullException("list");
+
+      if (step == 0)
+        throw new ArgumentException("Step cannot be zero.", "step");
+
+      List<T> slicedList = new List<T>();
+
+      // nothing to slice
+      if (list.Count == 0)
+        return slicedList;
+
+      // set defaults for null arguments
+      int s = step ?? 1;
+      int startIndex = start ?? 0;
+      int endIndex = end ?? list.Count;
+
+      // start from the end of the list if start is negitive
+      startIndex = (startIndex < 0) ? list.Count + startIndex : startIndex;
+
+      // end from the start of the list if end is negitive
+      endIndex = (endIndex < 0) ? list.Count + endIndex : endIndex;
+
+      // ensure indexes keep within collection bounds
+      startIndex = Math.Max(startIndex, 0);
+      endIndex = Math.Min(endIndex, list.Count - 1);
+
+      // loop between start and end indexes, incrementing by the step
+      for (int i = startIndex; i < endIndex; i += s)
+      {
+        slicedList.Add(list[i]);
+      }
+
+      return slicedList;
+    }
+
+
+    /// <summary>
+    /// Group the collection using a function which returns the key.
+    /// </summary>
+    /// <param name="source">The source collection to group.</param>
+    /// <param name="keySelector">The key selector.</param>
+    /// <returns>A Dictionary with each key relating to a list of objects in a list grouped under it.</returns>
+    public static Dictionary<K, List<V>> GroupBy<K, V>(ICollection<V> source, Func<V, K> keySelector)
+    {
+      if (keySelector == null)
+        throw new ArgumentNullException("keySelector");
+
+      Dictionary<K, List<V>> groupedValues = new Dictionary<K, List<V>>();
+
+      foreach (V value in source)
+      {
+        // using delegate to get the value's key
+        K key = keySelector(value);
+        List<V> groupedValueList;
+
+        // add a list for grouped values if the key is not already in Dictionary
+        if (!groupedValues.TryGetValue(key, out groupedValueList))
+        {
+          groupedValueList = new List<V>();
+          groupedValues.Add(key, groupedValueList);
+        }
+
+        groupedValueList.Add(value);
+      }
+
+      return groupedValues;
+    }
+
+    /// <summary>
+    /// Adds the elements of the specified collection to the specified generic IList.
+    /// </summary>
+    /// <param name="initial">The list to add to.</param>
+    /// <param name="collection">The collection of elements to add.</param>
+    public static void AddRange<T>(this IList<T> initial, IEnumerable<T> collection)
+    {
+      if (initial == null)
+        throw new ArgumentNullException("initial");
+
+      if (collection == null)
+        return;
+
+      foreach (T value in collection)
+      {
+        initial.Add(value);
+      }
+    }
+
+    public static void AddRange(this IList initial, IEnumerable collection)
+    {
+      ValidationUtils.ArgumentNotNull(initial, "initial");
+
+      ListWrapper<object> wrapper = new ListWrapper<object>(initial);
+      wrapper.AddRange(collection.Cast<object>());
+    }
+
+    public static List<T> Distinct<T>(List<T> collection)
+    {
+      List<T> distinctList = new List<T>();
+
+      foreach (T value in collection)
+      {
+        if (!distinctList.Contains(value))
+          distinctList.Add(value);
+      }
+
+      return distinctList;
+    }
+
+    public static List<List<T>> Flatten<T>(params IList<T>[] lists)
+    {
+      List<List<T>> flattened = new List<List<T>>();
+      Dictionary<int, T> currentList = new Dictionary<int, T>();
+
+      Recurse<T>(new List<IList<T>>(lists), 0, currentList, flattened);
+
+      return flattened;
+    }
+
+    private static void Recurse<T>(IList<IList<T>> global, int current, Dictionary<int, T> currentSet, List<List<T>> flattenedResult)
+    {
+      IList<T> currentArray = global[current];
+
+      for (int i = 0; i < currentArray.Count; i++)
+      {
+        currentSet[current] = currentArray[i];
+
+        if (current == global.Count - 1)
+        {
+          List<T> items = new List<T>();
+
+          for (int k = 0; k < currentSet.Count; k++)
+          {
+            items.Add(currentSet[k]);
+          }
+
+          flattenedResult.Add(items);
+        }
+        else
+        {
+          Recurse(global, current + 1, currentSet, flattenedResult);
+        }
+      }
+    }
+
+    public static List<T> CreateList<T>(ICollection collection)
+    {
+      if (collection == null)
+        throw new ArgumentNullException("collection");
+
+      T[] array = new T[collection.Count];
+      collection.CopyTo(array, 0);
+
+      return new List<T>(array);
+    }
+
+    public static bool ListEquals<T>(IList<T> a, IList<T> b)
+    {
+      if (a == null || b == null)
+        return (a == null && b == null);
+
+      if (a.Count != b.Count)
+        return false;
+
+      EqualityComparer<T> comparer = EqualityComparer<T>.Default;
+
+      for (int i = 0; i < a.Count; i++)
+      {
+        if (!comparer.Equals(a[i], b[i]))
+          return false;
+      }
+
+      return true;
+    }
+
+    #region GetSingleItem
+    public static bool TryGetSingleItem<T>(IList<T> list, out T value)
+    {
+      return TryGetSingleItem<T>(list, false, out value);
+    }
+
+    public static bool TryGetSingleItem<T>(IList<T> list, bool returnDefaultIfEmpty, out T value)
+    {
+      return MiscellaneousUtils.TryAction<T>(delegate { return GetSingleItem(list, returnDefaultIfEmpty); }, out value);
+    }
+
+    public static T GetSingleItem<T>(IList<T> list)
+    {
+      return GetSingleItem<T>(list, false);
+    }
+
+    public static T GetSingleItem<T>(IList<T> list, bool returnDefaultIfEmpty)
+    {
+      if (list.Count == 1)
+        return list[0];
+      else if (returnDefaultIfEmpty && list.Count == 0)
+        return default(T);
+      else
+        throw new Exception("Expected single {0} in list but got {1}.".FormatWith(CultureInfo.InvariantCulture, typeof(T), list.Count));
+    }
+    #endregion
+
+    public static IList<T> Minus<T>(IList<T> list, IList<T> minus)
+    {
+      ValidationUtils.ArgumentNotNull(list, "list");
+
+      List<T> result = new List<T>(list.Count);
+      foreach (T t in list)
+      {
+        if (minus == null || !minus.Contains(t))
+          result.Add(t);
+      }
+
+      return result;
+    }
+
+    public static IList CreateGenericList(Type listType)
+    {
+      ValidationUtils.ArgumentNotNull(listType, "listType");
+
+      return (IList)ReflectionUtils.CreateGeneric(typeof(List<>), listType);
+    }
+
+    public static IDictionary CreateGenericDictionary(Type keyType, Type valueType)
+    {
+      ValidationUtils.ArgumentNotNull(keyType, "keyType");
+      ValidationUtils.ArgumentNotNull(valueType, "valueType");
+
+      return (IDictionary)ReflectionUtils.CreateGeneric(typeof(Dictionary<,>), keyType, valueType);
+    }
+
+    public static bool IsListType(Type type)
+    {
+      ValidationUtils.ArgumentNotNull(type, "type");
+
+      if (type.IsArray)
+        return true;
+      if (typeof(IList).IsAssignableFrom(type))
+        return true;
+      if (ReflectionUtils.ImplementsGenericDefinition(type, typeof(IList<>)))
+        return true;
+
+      return false;
+    }
+
+    public static bool IsCollectionType(Type type)
+    {
+      ValidationUtils.ArgumentNotNull(type, "type");
+
+      if (type.IsArray)
+        return true;
+      if (typeof(ICollection).IsAssignableFrom(type))
+        return true;
+      if (ReflectionUtils.ImplementsGenericDefinition(type, typeof(ICollection<>)))
+        return true;
+
+      return false;
+    }
+
+    public static bool IsDictionaryType(Type type)
+    {
+      ValidationUtils.ArgumentNotNull(type, "type");
+
+      if (typeof(IDictionary).IsAssignableFrom(type))
+        return true;
+      if (ReflectionUtils.ImplementsGenericDefinition(type, typeof (IDictionary<,>)))
+        return true;
+
+      return false;
+    }
+
+    public static IWrappedCollection CreateCollectionWrapper(object list)
+    {
+      ValidationUtils.ArgumentNotNull(list, "list");
+
+      Type collectionDefinition;
+      if (ReflectionUtils.ImplementsGenericDefinition(list.GetType(), typeof(ICollection<>), out collectionDefinition))
+      {
+        Type collectionItemType = ReflectionUtils.GetCollectionItemType(collectionDefinition);
+
+        // Activator.CreateInstance throws AmbiguousMatchException. Manually invoke constructor
+        Func<Type, IList<object>, object> instanceCreator = (t, a) =>
+        {
+          ConstructorInfo c = t.GetConstructor(new[] { collectionDefinition });
+          return c.Invoke(new[] { list });
+        };
+
+        return (IWrappedCollection)ReflectionUtils.CreateGeneric(typeof(CollectionWrapper<>), new[] { collectionItemType }, instanceCreator, list);
+      }
+      else if (list is IList)
+      {
+        return new CollectionWrapper<object>((IList)list);
+      }
+      else
+      {
+        throw new Exception("Can not create ListWrapper for type {0}.".FormatWith(CultureInfo.InvariantCulture, list.GetType()));
+      }
+    }
+    public static IWrappedList CreateListWrapper(object list)
+    {
+      ValidationUtils.ArgumentNotNull(list, "list");
+
+      Type listDefinition;
+      if (ReflectionUtils.ImplementsGenericDefinition(list.GetType(), typeof(IList<>), out listDefinition))
+      {
+        Type collectionItemType = ReflectionUtils.GetCollectionItemType(listDefinition);
+
+        // Activator.CreateInstance throws AmbiguousMatchException. Manually invoke constructor
+        Func<Type, IList<object>, object> instanceCreator = (t, a) =>
+        {
+          ConstructorInfo c = t.GetConstructor(new[] {listDefinition});
+          return c.Invoke(new[] { list });
+        };
+
+        return (IWrappedList)ReflectionUtils.CreateGeneric(typeof(ListWrapper<>), new[] { collectionItemType }, instanceCreator, list);
+      }
+      else if (list is IList)
+      {
+        return new ListWrapper<object>((IList)list);
+      }
+      else
+      {
+        throw new Exception("Can not create ListWrapper for type {0}.".FormatWith(CultureInfo.InvariantCulture, list.GetType()));
+      }
+    }
+
+    public static IWrappedDictionary CreateDictionaryWrapper(object dictionary)
+    {
+      ValidationUtils.ArgumentNotNull(dictionary, "dictionary");
+
+      Type dictionaryDefinition;
+      if (ReflectionUtils.ImplementsGenericDefinition(dictionary.GetType(), typeof(IDictionary<,>), out dictionaryDefinition))
+      {
+        Type dictionaryKeyType = ReflectionUtils.GetDictionaryKeyType(dictionaryDefinition);
+        Type dictionaryValueType = ReflectionUtils.GetDictionaryValueType(dictionaryDefinition);
+
+        // Activator.CreateInstance throws AmbiguousMatchException. Manually invoke constructor
+        Func<Type, IList<object>, object> instanceCreator = (t, a) =>
+        {
+          ConstructorInfo c = t.GetConstructor(new[] { dictionaryDefinition });
+          return c.Invoke(new[] { dictionary });
+        };
+
+        return (IWrappedDictionary)ReflectionUtils.CreateGeneric(typeof(DictionaryWrapper<,>), new[] { dictionaryKeyType, dictionaryValueType }, instanceCreator, dictionary);
+      }
+      else if (dictionary is IDictionary)
+      {
+        return new DictionaryWrapper<object, object>((IDictionary)dictionary);
+      }
+      else
+      {
+        throw new Exception("Can not create DictionaryWrapper for type {0}.".FormatWith(CultureInfo.InvariantCulture, dictionary.GetType()));
+      }
+    }
+
+    public static object CreateAndPopulateList(Type listType, Action<IList, bool> populateList)
+    {
+      ValidationUtils.ArgumentNotNull(listType, "listType");
+      ValidationUtils.ArgumentNotNull(populateList, "populateList");
+
+      IList list;
+      Type collectionType;
+      bool isReadOnlyOrFixedSize = false;
+
+      if (listType.IsArray)
+      {
+        // have to use an arraylist when creating array
+        // there is no way to know the size until it is finised
+        list = new List<object>();
+        isReadOnlyOrFixedSize = true;
+      }
+      else if (ReflectionUtils.InheritsGenericDefinition(listType, typeof(ReadOnlyCollection<>), out collectionType))
+      {
+        Type readOnlyCollectionContentsType = collectionType.GetGenericArguments()[0];
+        Type genericEnumerable = ReflectionUtils.MakeGenericType(typeof(IEnumerable<>), readOnlyCollectionContentsType);
+        bool suitableConstructor = false;
+
+        foreach (ConstructorInfo constructor in listType.GetConstructors())
+        {
+          IList<ParameterInfo> parameters = constructor.GetParameters();
+
+          if (parameters.Count == 1)
+          {
+            if (genericEnumerable.IsAssignableFrom(parameters[0].ParameterType))
+            {
+              suitableConstructor = true;
+              break;
+            }
+          }
+        }
+
+        if (!suitableConstructor)
+          throw new Exception("Read-only type {0} does not have a public constructor that takes a type that implements {1}.".FormatWith(CultureInfo.InvariantCulture, listType, genericEnumerable));
+
+        // can't add or modify a readonly list
+        // use List<T> and convert once populated
+        list = CreateGenericList(readOnlyCollectionContentsType);
+        isReadOnlyOrFixedSize = true;
+      }
+      else if (typeof(IList).IsAssignableFrom(listType))
+      {
+        if (ReflectionUtils.IsInstantiatableType(listType))
+          list = (IList)Activator.CreateInstance(listType);
+        else if (listType == typeof(IList))
+          list = new List<object>();
+        else
+          list = null;
+      }
+      else if (ReflectionUtils.ImplementsGenericDefinition(listType, typeof(ICollection<>)))
+      {
+        if (ReflectionUtils.IsInstantiatableType(listType))
+          list = CreateCollectionWrapper(Activator.CreateInstance(listType));
+        else
+          list = null;
+      }
+      else
+      {
+        list = null;
+      }
+
+      if (list == null)
+        throw new Exception("Cannot create and populate list type {0}.".FormatWith(CultureInfo.InvariantCulture, listType));
+
+      populateList(list, isReadOnlyOrFixedSize);
+
+      // create readonly and fixed sized collections using the temporary list
+      if (isReadOnlyOrFixedSize)
+      {
+        if (listType.IsArray)
+          list = ToArray(((List<object>)list).ToArray(), ReflectionUtils.GetCollectionItemType(listType));
+        else if (ReflectionUtils.InheritsGenericDefinition(listType, typeof(ReadOnlyCollection<>)))
+          list = (IList)ReflectionUtils.CreateInstance(listType, list);
+      }
+      else if (list is IWrappedCollection)
+      {
+        return ((IWrappedCollection) list).UnderlyingCollection;
+      }
+
+      return list;
+    }
+
+    public static Array ToArray(Array initial, Type type)
+    {
+      if (type == null)
+        throw new ArgumentNullException("type");
+
+      Array destinationArray = Array.CreateInstance(type, initial.Length);
+      Array.Copy(initial, 0, destinationArray, 0, initial.Length);
+      return destinationArray;
+    }
+
+    public static bool AddDistinct<T>(this IList<T> list, T value)
+    {
+      return list.AddDistinct(value, EqualityComparer<T>.Default);
+    }
+
+    public static bool AddDistinct<T>(this IList<T> list, T value, IEqualityComparer<T> comparer)
+    {
+      if (list.ContainsValue(value, comparer))
+        return false;
+
+      list.Add(value);
+      return true;
+    }
+
+    // this is here because LINQ Bridge doesn't support Contains with IEqualityComparer<T>
+    public static bool ContainsValue<TSource>(this IEnumerable<TSource> source, TSource value, IEqualityComparer<TSource> comparer)
+    {
+      if (comparer == null)
+        comparer = EqualityComparer<TSource>.Default;
+
+      if (source == null)
+        throw new ArgumentNullException("source");
+
+      foreach (TSource local in source)
+      {
+        if (comparer.Equals(local, value))
+          return true;
+      }
+
+      return false;
+    }
+
+    public static bool AddRangeDistinct<T>(this IList<T> list, IEnumerable<T> values)
+    {
+      return list.AddRangeDistinct(values, EqualityComparer<T>.Default);
+    }
+
+    public static bool AddRangeDistinct<T>(this IList<T> list, IEnumerable<T> values, IEqualityComparer<T> comparer)
+    {
+      bool allAdded = true;
+      foreach (T value in values)
+      {
+        if (!list.AddDistinct(value, comparer))
+          allAdded = false;
+      }
+
+      return allAdded;
+    }
+
+    public static int IndexOf<T>(this IEnumerable<T> collection, Func<T, bool> predicate)
+    {
+      int index = 0;
+      foreach (T value in collection)
+      {
+        if (predicate(value))
+          return index;
+
+        index++;
+      }
+
+      return -1;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/CollectionWrapper.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/CollectionWrapper.cs
new file mode 100644 (file)
index 0000000..21fe881
--- /dev/null
@@ -0,0 +1,271 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Threading;
+using Newtonsoft.Json.Utilities;
+using System.Linq;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal interface IWrappedCollection : IList
+  {
+    object UnderlyingCollection { get; }
+  }
+
+  internal class CollectionWrapper<T> : ICollection<T>, IWrappedCollection
+  {
+    private readonly IList _list;
+    private readonly ICollection<T> _genericCollection;
+    private object _syncRoot;
+
+    public CollectionWrapper(IList list)
+    {
+      ValidationUtils.ArgumentNotNull(list, "list");
+
+      if (list is ICollection<T>)
+        _genericCollection = (ICollection<T>)list;
+      else
+        _list = list;
+    }
+
+    public CollectionWrapper(ICollection<T> list)
+    {
+      ValidationUtils.ArgumentNotNull(list, "list");
+
+      _genericCollection = list;
+    }
+
+    public virtual void Add(T item)
+    {
+      if (_genericCollection != null)
+        _genericCollection.Add(item);
+      else
+        _list.Add(item);
+    }
+
+    public virtual void Clear()
+    {
+      if (_genericCollection != null)
+        _genericCollection.Clear();
+      else
+        _list.Clear();
+    }
+
+    public virtual bool Contains(T item)
+    {
+      if (_genericCollection != null)
+        return _genericCollection.Contains(item);
+      else
+        return _list.Contains(item);
+    }
+
+    public virtual void CopyTo(T[] array, int arrayIndex)
+    {
+      if (_genericCollection != null)
+        _genericCollection.CopyTo(array, arrayIndex);
+      else
+        _list.CopyTo(array, arrayIndex);
+    }
+
+    public virtual int Count
+    {
+      get
+      {
+        if (_genericCollection != null)
+          return _genericCollection.Count;
+        else
+          return _list.Count;
+      }
+    }
+
+    public virtual bool IsReadOnly
+    {
+      get
+      {
+        if (_genericCollection != null)
+          return _genericCollection.IsReadOnly;
+        else
+          return _list.IsReadOnly;
+      }
+    }
+
+    public virtual bool Remove(T item)
+    {
+      if (_genericCollection != null)
+      {
+        return _genericCollection.Remove(item);
+      }
+      else
+      {
+        bool contains = _list.Contains(item);
+
+        if (contains)
+          _list.Remove(item);
+
+        return contains;
+      }
+    }
+
+    public virtual IEnumerator<T> GetEnumerator()
+    {
+      if (_genericCollection != null)
+        return _genericCollection.GetEnumerator();
+
+      return _list.Cast<T>().GetEnumerator();
+    }
+
+    IEnumerator IEnumerable.GetEnumerator()
+    {
+      if (_genericCollection != null)
+        return _genericCollection.GetEnumerator();
+      else
+        return _list.GetEnumerator();
+    }
+
+    int IList.Add(object value)
+    {
+      VerifyValueType(value);
+      Add((T)value);
+
+      return (Count - 1);
+    }
+
+    bool IList.Contains(object value)
+    {
+      if (IsCompatibleObject(value))
+        return Contains((T)value);
+
+      return false;
+    }
+
+    int IList.IndexOf(object value)
+    {
+      if (_genericCollection != null)
+        throw new Exception("Wrapped ICollection<T> does not support IndexOf.");
+
+      if (IsCompatibleObject(value))
+        return _list.IndexOf((T)value);
+
+      return -1;
+    }
+
+    void IList.RemoveAt(int index)
+    {
+      if (_genericCollection != null)
+        throw new Exception("Wrapped ICollection<T> does not support RemoveAt.");
+
+      _list.RemoveAt(index);
+    }
+
+    void IList.Insert(int index, object value)
+    {
+      if (_genericCollection != null)
+        throw new Exception("Wrapped ICollection<T> does not support Insert.");
+
+      VerifyValueType(value);
+      _list.Insert(index, (T)value);
+    }
+
+    bool IList.IsFixedSize
+    {
+      get { return false; }
+    }
+
+    void IList.Remove(object value)
+    {
+      if (IsCompatibleObject(value))
+        Remove((T)value);
+    }
+
+    object IList.this[int index]
+    {
+      get
+      {
+        if (_genericCollection != null)
+          throw new Exception("Wrapped ICollection<T> does not support indexer.");
+
+        return _list[index];
+      }
+      set
+      {
+        if (_genericCollection != null)
+          throw new Exception("Wrapped ICollection<T> does not support indexer.");
+
+        VerifyValueType(value);
+        _list[index] = (T)value;
+      }
+    }
+
+    void ICollection.CopyTo(Array array, int arrayIndex)
+    {
+      CopyTo((T[])array, arrayIndex);
+    }
+
+    bool ICollection.IsSynchronized
+    {
+      get { return false; }
+    }
+
+    object ICollection.SyncRoot
+    {
+      get
+      {
+        if (_syncRoot == null)
+          Interlocked.CompareExchange(ref _syncRoot, new object(), null);
+
+        return _syncRoot;
+      }
+    }
+
+    private static void VerifyValueType(object value)
+    {
+      if (!IsCompatibleObject(value))
+        throw new ArgumentException("The value '{0}' is not of type '{1}' and cannot be used in this generic collection.".FormatWith(CultureInfo.InvariantCulture, value, typeof(T)), "value");
+    }
+
+    private static bool IsCompatibleObject(object value)
+    {
+      if (!(value is T) && (value != null || (typeof(T).IsValueType && !ReflectionUtils.IsNullableType(typeof(T)))))
+        return false;
+
+      return true;
+    }
+
+    public object UnderlyingCollection
+    {
+      get
+      {
+        if (_genericCollection != null)
+          return _genericCollection;
+        else
+          return _list;
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs
new file mode 100644 (file)
index 0000000..418dc94
--- /dev/null
@@ -0,0 +1,515 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Globalization;
+using System.ComponentModel;
+using Newtonsoft.Json.Serialization;
+using System.Reflection;
+
+#if !SILVERLIGHT
+using System.Data.SqlTypes;
+#endif
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal static class ConvertUtils
+  {
+    internal struct TypeConvertKey : IEquatable<TypeConvertKey>
+    {
+      private readonly Type _initialType;
+      private readonly Type _targetType;
+
+      public Type InitialType
+      {
+        get { return _initialType; }
+      }
+
+      public Type TargetType
+      {
+        get { return _targetType; }
+      }
+
+      public TypeConvertKey(Type initialType, Type targetType)
+      {
+        _initialType = initialType;
+        _targetType = targetType;
+      }
+
+      public override int GetHashCode()
+      {
+        return _initialType.GetHashCode() ^ _targetType.GetHashCode();
+      }
+
+      public override bool Equals(object obj)
+      {
+        if (!(obj is TypeConvertKey))
+          return false;
+
+        return Equals((TypeConvertKey)obj);
+      }
+
+      public bool Equals(TypeConvertKey other)
+      {
+        return (_initialType == other._initialType && _targetType == other._targetType);
+      }
+    }
+
+    private static readonly ThreadSafeStore<TypeConvertKey, Func<object, object>> CastConverters =
+      new ThreadSafeStore<TypeConvertKey, Func<object, object>>(CreateCastConverter);
+
+    private static Func<object, object> CreateCastConverter(TypeConvertKey t)
+    {
+      MethodInfo castMethodInfo = t.TargetType.GetMethod("op_Implicit", new[] { t.InitialType });
+      if (castMethodInfo == null)
+        castMethodInfo = t.TargetType.GetMethod("op_Explicit", new[] { t.InitialType });
+
+      if (castMethodInfo == null)
+        return null;
+
+      MethodCall<object, object> call = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall<object>(castMethodInfo);
+
+      return o => call(null, o);
+    }
+
+    public static bool CanConvertType(Type initialType, Type targetType, bool allowTypeNameToString)
+    {
+      ValidationUtils.ArgumentNotNull(initialType, "initialType");
+      ValidationUtils.ArgumentNotNull(targetType, "targetType");
+
+      if (ReflectionUtils.IsNullableType(targetType))
+        targetType = Nullable.GetUnderlyingType(targetType);
+
+      if (targetType == initialType)
+        return true;
+
+      if (typeof(IConvertible).IsAssignableFrom(initialType) && typeof(IConvertible).IsAssignableFrom(targetType))
+      {
+        return true;
+      }
+
+#if !PocketPC && !NET20
+      if (initialType == typeof(DateTime) && targetType == typeof(DateTimeOffset))
+        return true;
+#endif
+
+      if (initialType == typeof(Guid) && (targetType == typeof(Guid) || targetType == typeof(string)))
+        return true;
+
+      if (initialType == typeof(Type) && targetType == typeof(string))
+        return true;
+
+#if !PocketPC
+      // see if source or target types have a TypeConverter that converts between the two
+      TypeConverter toConverter = GetConverter(initialType);
+
+      if (toConverter != null && !IsComponentConverter(toConverter) && toConverter.CanConvertTo(targetType))
+      {
+        if (allowTypeNameToString || toConverter.GetType() != typeof(TypeConverter))
+          return true;
+      }
+
+      TypeConverter fromConverter = GetConverter(targetType);
+
+      if (fromConverter != null && !IsComponentConverter(fromConverter) && fromConverter.CanConvertFrom(initialType))
+        return true;
+#endif
+
+      // handle DBNull and INullable
+      if (initialType == typeof(DBNull))
+      {
+        if (ReflectionUtils.IsNullable(targetType))
+          return true;
+      }
+
+      return false;
+    }
+
+    private static bool IsComponentConverter(TypeConverter converter)
+    {
+#if !SILVERLIGHT && !PocketPC
+      return (converter is ComponentConverter);
+#else
+      return false;
+#endif
+    }
+
+    #region Convert
+    /// <summary>
+    /// Converts the value to the specified type.
+    /// </summary>
+    /// <typeparam name="T">The type to convert the value to.</typeparam>
+    /// <param name="initialValue">The value to convert.</param>
+    /// <returns>The converted type.</returns>
+    public static T Convert<T>(object initialValue)
+    {
+      return Convert<T>(initialValue, CultureInfo.CurrentCulture);
+    }
+
+    /// <summary>
+    /// Converts the value to the specified type.
+    /// </summary>
+    /// <typeparam name="T">The type to convert the value to.</typeparam>
+    /// <param name="initialValue">The value to convert.</param>
+    /// <param name="culture">The culture to use when converting.</param>
+    /// <returns>The converted type.</returns>
+    public static T Convert<T>(object initialValue, CultureInfo culture)
+    {
+      return (T)Convert(initialValue, culture, typeof(T));
+    }
+
+    /// <summary>
+    /// Converts the value to the specified type.
+    /// </summary>
+    /// <param name="initialValue">The value to convert.</param>
+    /// <param name="culture">The culture to use when converting.</param>
+    /// <param name="targetType">The type to convert the value to.</param>
+    /// <returns>The converted type.</returns>
+    public static object Convert(object initialValue, CultureInfo culture, Type targetType)
+    {
+      if (initialValue == null)
+        throw new ArgumentNullException("initialValue");
+
+      if (ReflectionUtils.IsNullableType(targetType))
+        targetType = Nullable.GetUnderlyingType(targetType);
+
+      Type initialType = initialValue.GetType();
+
+      if (targetType == initialType)
+        return initialValue;
+
+      if (initialValue is string && typeof(Type).IsAssignableFrom(targetType))
+        return Type.GetType((string) initialValue, true);
+
+      if (targetType.IsInterface || targetType.IsGenericTypeDefinition || targetType.IsAbstract)
+        throw new ArgumentException("Target type {0} is not a value type or a non-abstract class.".FormatWith(CultureInfo.InvariantCulture, targetType), "targetType");
+
+      // use Convert.ChangeType if both types are IConvertible
+      if (initialValue is IConvertible && typeof(IConvertible).IsAssignableFrom(targetType))
+      {
+        if (targetType.IsEnum)
+        {
+          if (initialValue is string)
+            return Enum.Parse(targetType, initialValue.ToString(), true);
+          else if (IsInteger(initialValue))
+            return Enum.ToObject(targetType, initialValue);
+        }
+        
+        return System.Convert.ChangeType(initialValue, targetType, culture);
+      }
+
+#if !PocketPC && !NET20
+      if (initialValue is DateTime && targetType == typeof(DateTimeOffset))
+        return new DateTimeOffset((DateTime)initialValue);
+#endif
+
+      if (initialValue is string)
+      {
+        if (targetType == typeof (Guid))
+          return new Guid((string) initialValue);
+        if (targetType == typeof (Uri))
+          return new Uri((string) initialValue);
+        if (targetType == typeof (TimeSpan))
+#if !(NET35 || NET20 || SILVERLIGHT)
+          return TimeSpan.Parse((string) initialValue, CultureInfo.InvariantCulture);
+#else
+          return TimeSpan.Parse((string)initialValue);
+#endif
+      }
+
+#if !PocketPC
+      // see if source or target types have a TypeConverter that converts between the two
+      TypeConverter toConverter = GetConverter(initialType);
+
+      if (toConverter != null && toConverter.CanConvertTo(targetType))
+      {
+#if !SILVERLIGHT
+        return toConverter.ConvertTo(null, culture, initialValue, targetType);
+#else
+        return toConverter.ConvertTo(initialValue, targetType);
+#endif
+      }
+
+      TypeConverter fromConverter = GetConverter(targetType);
+
+      if (fromConverter != null && fromConverter.CanConvertFrom(initialType))
+      {
+#if !SILVERLIGHT
+        return fromConverter.ConvertFrom(null, culture, initialValue);
+#else
+        return fromConverter.ConvertFrom(initialValue);
+#endif
+      }
+#endif
+
+      // handle DBNull and INullable
+      if (initialValue == DBNull.Value)
+      {
+        if (ReflectionUtils.IsNullable(targetType))
+          return EnsureTypeAssignable(null, initialType, targetType);
+        
+        throw new Exception("Can not convert null {0} into non-nullable {1}.".FormatWith(CultureInfo.InvariantCulture, initialType, targetType));
+      }
+#if !SILVERLIGHT
+      if (initialValue is INullable)
+        return EnsureTypeAssignable(ToValue((INullable)initialValue), initialType, targetType);
+#endif
+
+      throw new Exception("Can not convert from {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, initialType, targetType));
+    }
+    #endregion
+
+    #region TryConvert
+    /// <summary>
+    /// Converts the value to the specified type.
+    /// </summary>
+    /// <typeparam name="T">The type to convert the value to.</typeparam>
+    /// <param name="initialValue">The value to convert.</param>
+    /// <param name="convertedValue">The converted value if the conversion was successful or the default value of <c>T</c> if it failed.</param>
+    /// <returns>
+    ///        <c>true</c> if <c>initialValue</c> was converted successfully; otherwise, <c>false</c>.
+    /// </returns>
+    public static bool TryConvert<T>(object initialValue, out T convertedValue)
+    {
+      return TryConvert(initialValue, CultureInfo.CurrentCulture, out convertedValue);
+    }
+
+    /// <summary>
+    /// Converts the value to the specified type.
+    /// </summary>
+    /// <typeparam name="T">The type to convert the value to.</typeparam>
+    /// <param name="initialValue">The value to convert.</param>
+    /// <param name="culture">The culture to use when converting.</param>
+    /// <param name="convertedValue">The converted value if the conversion was successful or the default value of <c>T</c> if it failed.</param>
+    /// <returns>
+    ///        <c>true</c> if <c>initialValue</c> was converted successfully; otherwise, <c>false</c>.
+    /// </returns>
+    public static bool TryConvert<T>(object initialValue, CultureInfo culture, out T convertedValue)
+    {
+      return MiscellaneousUtils.TryAction<T>(delegate
+      {
+        object tempConvertedValue;
+        TryConvert(initialValue, CultureInfo.CurrentCulture, typeof(T), out tempConvertedValue);
+
+        return (T)tempConvertedValue;
+      }, out convertedValue);
+    }
+
+    /// <summary>
+    /// Converts the value to the specified type.
+    /// </summary>
+    /// <param name="initialValue">The value to convert.</param>
+    /// <param name="culture">The culture to use when converting.</param>
+    /// <param name="targetType">The type to convert the value to.</param>
+    /// <param name="convertedValue">The converted value if the conversion was successful or the default value of <c>T</c> if it failed.</param>
+    /// <returns>
+    ///        <c>true</c> if <c>initialValue</c> was converted successfully; otherwise, <c>false</c>.
+    /// </returns>
+    public static bool TryConvert(object initialValue, CultureInfo culture, Type targetType, out object convertedValue)
+    {
+      return MiscellaneousUtils.TryAction<object>(delegate { return Convert(initialValue, culture, targetType); }, out convertedValue);
+    }
+    #endregion
+
+    #region ConvertOrCast
+    /// <summary>
+    /// Converts the value to the specified type. If the value is unable to be converted, the
+    /// value is checked whether it assignable to the specified type.
+    /// </summary>
+    /// <typeparam name="T">The type to convert or cast the value to.</typeparam>
+    /// <param name="initialValue">The value to convert.</param>
+    /// <returns>The converted type. If conversion was unsuccessful, the initial value is returned if assignable to the target type</returns>
+    public static T ConvertOrCast<T>(object initialValue)
+    {
+      return ConvertOrCast<T>(initialValue, CultureInfo.CurrentCulture);
+    }
+
+    /// <summary>
+    /// Converts the value to the specified type. If the value is unable to be converted, the
+    /// value is checked whether it assignable to the specified type.
+    /// </summary>
+    /// <typeparam name="T">The type to convert or cast the value to.</typeparam>
+    /// <param name="initialValue">The value to convert.</param>
+    /// <param name="culture">The culture to use when converting.</param>
+    /// <returns>The converted type. If conversion was unsuccessful, the initial value is returned if assignable to the target type</returns>
+    public static T ConvertOrCast<T>(object initialValue, CultureInfo culture)
+    {
+      return (T)ConvertOrCast(initialValue, culture, typeof(T));
+    }
+
+    /// <summary>
+    /// Converts the value to the specified type. If the value is unable to be converted, the
+    /// value is checked whether it assignable to the specified type.
+    /// </summary>
+    /// <param name="initialValue">The value to convert.</param>
+    /// <param name="culture">The culture to use when converting.</param>
+    /// <param name="targetType">The type to convert or cast the value to.</param>
+    /// <returns>
+    /// The converted type. If conversion was unsuccessful, the initial value
+    /// is returned if assignable to the target type.
+    /// </returns>
+    public static object ConvertOrCast(object initialValue, CultureInfo culture, Type targetType)
+    {
+      object convertedValue;
+
+      if (targetType == typeof(object))
+        return initialValue;
+
+      if (initialValue == null && ReflectionUtils.IsNullable(targetType))
+        return null;
+
+      if (TryConvert(initialValue, culture, targetType, out convertedValue))
+        return convertedValue;
+
+      return EnsureTypeAssignable(initialValue, ReflectionUtils.GetObjectType(initialValue), targetType);
+    }
+    #endregion
+
+    #region TryConvertOrCast
+    /// <summary>
+    /// Converts the value to the specified type. If the value is unable to be converted, the
+    /// value is checked whether it assignable to the specified type.
+    /// </summary>
+    /// <typeparam name="T">The type to convert the value to.</typeparam>
+    /// <param name="initialValue">The value to convert.</param>
+    /// <param name="convertedValue">The converted value if the conversion was successful or the default value of <c>T</c> if it failed.</param>
+    /// <returns>
+    ///        <c>true</c> if <c>initialValue</c> was converted successfully or is assignable; otherwise, <c>false</c>.
+    /// </returns>
+    public static bool TryConvertOrCast<T>(object initialValue, out T convertedValue)
+    {
+      return TryConvertOrCast<T>(initialValue, CultureInfo.CurrentCulture, out convertedValue);
+    }
+
+    /// <summary>
+    /// Converts the value to the specified type. If the value is unable to be converted, the
+    /// value is checked whether it assignable to the specified type.
+    /// </summary>
+    /// <typeparam name="T">The type to convert the value to.</typeparam>
+    /// <param name="initialValue">The value to convert.</param>
+    /// <param name="culture">The culture to use when converting.</param>
+    /// <param name="convertedValue">The converted value if the conversion was successful or the default value of <c>T</c> if it failed.</param>
+    /// <returns>
+    ///        <c>true</c> if <c>initialValue</c> was converted successfully or is assignable; otherwise, <c>false</c>.
+    /// </returns>
+    public static bool TryConvertOrCast<T>(object initialValue, CultureInfo culture, out T convertedValue)
+    {
+      return MiscellaneousUtils.TryAction<T>(delegate
+      {
+        object tempConvertedValue;
+        TryConvertOrCast(initialValue, CultureInfo.CurrentCulture, typeof(T), out tempConvertedValue);
+
+        return (T)tempConvertedValue;
+      }, out convertedValue);
+    }
+
+    /// <summary>
+    /// Converts the value to the specified type. If the value is unable to be converted, the
+    /// value is checked whether it assignable to the specified type.
+    /// </summary>
+    /// <param name="initialValue">The value to convert.</param>
+    /// <param name="culture">The culture to use when converting.</param>
+    /// <param name="targetType">The type to convert the value to.</param>
+    /// <param name="convertedValue">The converted value if the conversion was successful or the default value of <c>T</c> if it failed.</param>
+    /// <returns>
+    ///        <c>true</c> if <c>initialValue</c> was converted successfully or is assignable; otherwise, <c>false</c>.
+    /// </returns>
+    public static bool TryConvertOrCast(object initialValue, CultureInfo culture, Type targetType, out object convertedValue)
+    {
+      return MiscellaneousUtils.TryAction<object>(delegate { return ConvertOrCast(initialValue, culture, targetType); }, out convertedValue);
+    }
+    #endregion
+
+    private static object EnsureTypeAssignable(object value, Type initialType, Type targetType)
+    {
+      Type valueType = (value != null) ? value.GetType() : null;
+
+      if (value != null)
+      {
+        if (targetType.IsAssignableFrom(valueType))
+          return value;
+
+        Func<object, object> castConverter = CastConverters.Get(new TypeConvertKey(valueType, targetType));
+        if (castConverter != null)
+          return castConverter(value);
+      }
+      else
+      {
+        if (ReflectionUtils.IsNullable(targetType))
+          return null;
+      }
+
+      throw new Exception("Could not cast or convert from {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, (initialType != null) ? initialType.ToString() : "{null}", targetType));
+    }
+
+#if !SILVERLIGHT
+    public static object ToValue(INullable nullableValue)
+    {
+      if (nullableValue == null)
+        return null;
+      else if (nullableValue is SqlInt32)
+        return ToValue((SqlInt32)nullableValue);
+      else if (nullableValue is SqlInt64)
+        return ToValue((SqlInt64)nullableValue);
+      else if (nullableValue is SqlBoolean)
+        return ToValue((SqlBoolean)nullableValue);
+      else if (nullableValue is SqlString)
+        return ToValue((SqlString)nullableValue);
+      else if (nullableValue is SqlDateTime)
+        return ToValue((SqlDateTime)nullableValue);
+
+      throw new Exception("Unsupported INullable type: {0}".FormatWith(CultureInfo.InvariantCulture, nullableValue.GetType()));
+    }
+#endif
+
+#if !PocketPC
+    internal static TypeConverter GetConverter(Type t)
+    {
+      return JsonTypeReflector.GetTypeConverter(t);
+    }
+#endif
+
+    public static bool IsInteger(object value)
+    {
+      switch (System.Convert.GetTypeCode(value))
+      {
+        case TypeCode.SByte:
+        case TypeCode.Byte:
+        case TypeCode.Int16:
+        case TypeCode.UInt16:
+        case TypeCode.Int32:
+        case TypeCode.UInt32:
+        case TypeCode.Int64:
+        case TypeCode.UInt64:
+          return true;
+        default:
+          return false;
+      }
+    }
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/DateTimeUtils.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/DateTimeUtils.cs
new file mode 100644 (file)
index 0000000..86a399a
--- /dev/null
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Xml;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal static class DateTimeUtils
+  {
+    public static string GetLocalOffset(this DateTime d)
+    {
+      TimeSpan utcOffset;
+#if PocketPC || NET20
+      utcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(d);
+#else
+      utcOffset = TimeZoneInfo.Local.GetUtcOffset(d);
+#endif
+
+      return utcOffset.Hours.ToString("+00;-00", CultureInfo.InvariantCulture) + ":" + utcOffset.Minutes.ToString("00;00", CultureInfo.InvariantCulture);
+    }
+
+    public static XmlDateTimeSerializationMode ToSerializationMode(DateTimeKind kind)
+    {
+      switch (kind)
+      {
+        case DateTimeKind.Local:
+          return XmlDateTimeSerializationMode.Local;
+        case DateTimeKind.Unspecified:
+          return XmlDateTimeSerializationMode.Unspecified;
+        case DateTimeKind.Utc:
+          return XmlDateTimeSerializationMode.Utc;
+        default:
+          throw MiscellaneousUtils.CreateArgumentOutOfRangeException("kind", kind, "Unexpected DateTimeKind value.");
+      }
+    }
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/DictionaryWrapper.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/DictionaryWrapper.cs
new file mode 100644 (file)
index 0000000..9d31cf6
--- /dev/null
@@ -0,0 +1,400 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Collections;
+using System.Threading;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal interface IWrappedDictionary : IDictionary
+  {
+    object UnderlyingDictionary { get; }
+  }
+
+  internal class DictionaryWrapper<TKey, TValue> : IDictionary<TKey, TValue>, IWrappedDictionary
+  {
+    private readonly IDictionary _dictionary;
+    private readonly IDictionary<TKey, TValue> _genericDictionary;
+    private object _syncRoot;
+
+    public DictionaryWrapper(IDictionary dictionary)
+    {
+      ValidationUtils.ArgumentNotNull(dictionary, "dictionary");
+
+      _dictionary = dictionary;
+    }
+
+    public DictionaryWrapper(IDictionary<TKey, TValue> dictionary)
+    {
+      ValidationUtils.ArgumentNotNull(dictionary, "dictionary");
+
+      _genericDictionary = dictionary;
+    }
+
+    public void Add(TKey key, TValue value)
+    {
+      if (_genericDictionary != null)
+        _genericDictionary.Add(key, value);
+      else
+        _dictionary.Add(key, value);
+    }
+
+    public bool ContainsKey(TKey key)
+    {
+      if (_genericDictionary != null)
+        return _genericDictionary.ContainsKey(key);
+      else
+        return _dictionary.Contains(key);
+    }
+
+    public ICollection<TKey> Keys
+    {
+      get
+      {
+        if (_genericDictionary != null)
+          return _genericDictionary.Keys;
+        else
+          return _dictionary.Keys.Cast<TKey>().ToList();
+      }
+    }
+
+    public bool Remove(TKey key)
+    {
+      if (_genericDictionary != null)
+      {
+        return _genericDictionary.Remove(key);
+      }
+      else
+      {
+        if (_dictionary.Contains(key))
+        {
+          _dictionary.Remove(key);
+          return true;
+        }
+        else
+        {
+          return false;
+        }
+      }
+    }
+
+    public bool TryGetValue(TKey key, out TValue value)
+    {
+      if (_genericDictionary != null)
+      {
+        return _genericDictionary.TryGetValue(key, out value);
+      }
+      else
+      {
+        if (!_dictionary.Contains(key))
+        {
+          value = default(TValue);
+          return false;
+        }
+        else
+        {
+          value = (TValue)_dictionary[key];
+          return true;
+        }
+      }
+    }
+
+    public ICollection<TValue> Values
+    {
+      get
+      {
+        if (_genericDictionary != null)
+          return _genericDictionary.Values;
+        else
+          return _dictionary.Values.Cast<TValue>().ToList();
+      }
+    }
+
+    public TValue this[TKey key]
+    {
+      get
+      {
+        if (_genericDictionary != null)
+          return _genericDictionary[key];
+        else
+          return (TValue)_dictionary[key];
+      }
+      set
+      {
+        if (_genericDictionary != null)
+          _genericDictionary[key] = value;
+        else
+          _dictionary[key] = value;
+      }
+    }
+
+    public void Add(KeyValuePair<TKey, TValue> item)
+    {
+      if (_genericDictionary != null)
+        _genericDictionary.Add(item);
+      else
+        ((IList)_dictionary).Add(item);
+    }
+
+    public void Clear()
+    {
+      if (_genericDictionary != null)
+        _genericDictionary.Clear();
+      else
+        _dictionary.Clear();
+    }
+
+    public bool Contains(KeyValuePair<TKey, TValue> item)
+    {
+      if (_genericDictionary != null)
+        return _genericDictionary.Contains(item);
+      else
+        return ((IList)_dictionary).Contains(item);
+    }
+
+    public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
+    {
+      if (_genericDictionary != null)
+      {
+        _genericDictionary.CopyTo(array, arrayIndex);
+      }
+      else
+      {
+        foreach (DictionaryEntry item in _dictionary)
+        {
+          array[arrayIndex++] = new KeyValuePair<TKey, TValue>((TKey)item.Key, (TValue)item.Value);
+        }
+      }
+    }
+
+    public int Count
+    {
+      get
+      {
+        if (_genericDictionary != null)
+          return _genericDictionary.Count;
+        else
+          return _dictionary.Count;
+      }
+    }
+
+    public bool IsReadOnly
+    {
+      get
+      {
+        if (_genericDictionary != null)
+          return _genericDictionary.IsReadOnly;
+        else
+          return _dictionary.IsReadOnly;
+      }
+    }
+
+    public bool Remove(KeyValuePair<TKey, TValue> item)
+    {
+      if (_genericDictionary != null)
+      {
+        return _genericDictionary.Remove(item);
+      }
+      else
+      {
+        if (_dictionary.Contains(item.Key))
+        {
+          object value = _dictionary[item.Key];
+
+          if (object.Equals(value, item.Value))
+          {
+            _dictionary.Remove(item.Key);
+            return true;
+          }
+          else
+          {
+            return false;
+          }
+        }
+        else
+        {
+          return true;
+        }
+      }
+    }
+
+    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
+    {
+      if (_genericDictionary != null)
+        return _genericDictionary.GetEnumerator();
+      else
+        return _dictionary.Cast<DictionaryEntry>().Select(de => new KeyValuePair<TKey, TValue>((TKey)de.Key, (TValue)de.Value)).GetEnumerator();
+    }
+
+    IEnumerator IEnumerable.GetEnumerator()
+    {
+      return GetEnumerator();
+    }
+
+    void IDictionary.Add(object key, object value)
+    {
+      if (_genericDictionary != null)
+        _genericDictionary.Add((TKey)key, (TValue)value);
+      else
+        _dictionary.Add(key, value);
+    }
+
+    bool IDictionary.Contains(object key)
+    {
+      if (_genericDictionary != null)
+        return _genericDictionary.ContainsKey((TKey)key);
+      else
+        return _dictionary.Contains(key);
+    }
+
+    private struct DictionaryEnumerator<TEnumeratorKey, TEnumeratorValue> : IDictionaryEnumerator
+    {
+      private readonly IEnumerator<KeyValuePair<TEnumeratorKey, TEnumeratorValue>> _e;
+
+      public DictionaryEnumerator(IEnumerator<KeyValuePair<TEnumeratorKey, TEnumeratorValue>> e)
+      {
+        ValidationUtils.ArgumentNotNull(e, "e");
+        _e = e;
+      }
+
+      public DictionaryEntry Entry
+      {
+        get { return (DictionaryEntry)Current; }
+      }
+
+      public object Key
+      {
+        get { return Entry.Key; }
+      }
+
+      public object Value
+      {
+        get { return Entry.Value; }
+      }
+
+      public object Current
+      {
+        get { return new DictionaryEntry(_e.Current.Key, _e.Current.Value); }
+      }
+
+      public bool MoveNext()
+      {
+        return _e.MoveNext();
+      }
+
+      public void Reset()
+      {
+        _e.Reset();
+      }
+    }
+
+    IDictionaryEnumerator IDictionary.GetEnumerator()
+    {
+      if (_genericDictionary != null)
+        return new DictionaryEnumerator<TKey, TValue>(_genericDictionary.GetEnumerator());
+      else
+        return _dictionary.GetEnumerator();
+    }
+
+    bool IDictionary.IsFixedSize
+    {
+      get
+      {
+        if (_genericDictionary != null)
+          return false;
+        else
+          return _dictionary.IsFixedSize;
+      }
+    }
+
+    ICollection IDictionary.Keys
+    {
+      get
+      {
+        if (_genericDictionary != null)
+          return _genericDictionary.Keys.ToList();
+        else
+          return _dictionary.Keys;
+      }
+    }
+
+    public void Remove(object key)
+    {
+      if (_genericDictionary != null)
+        _genericDictionary.Remove((TKey)key);
+      else
+        _dictionary.Remove(key);
+    }
+
+    ICollection IDictionary.Values
+    {
+      get
+      {
+        if (_genericDictionary != null)
+          return _genericDictionary.Values.ToList();
+        else
+          return _dictionary.Values;
+      }
+    }
+
+    object IDictionary.this[object key]
+    {
+      get
+      {
+        if (_genericDictionary != null)
+          return _genericDictionary[(TKey)key];
+        else
+          return _dictionary[key];
+      }
+      set
+      {
+        if (_genericDictionary != null)
+          _genericDictionary[(TKey)key] = (TValue)value;
+        else
+          _dictionary[key] = value;
+      }
+    }
+
+    void ICollection.CopyTo(Array array, int index)
+    {
+      if (_genericDictionary != null)
+        _genericDictionary.CopyTo((KeyValuePair<TKey, TValue>[])array, index);
+      else
+        _dictionary.CopyTo(array, index);
+    }
+
+    bool ICollection.IsSynchronized
+    {
+      get
+      {
+        if (_genericDictionary != null)
+          return false;
+        else
+          return _dictionary.IsSynchronized;
+      }
+    }
+
+    object ICollection.SyncRoot
+    {
+      get
+      {
+        if (_syncRoot == null)
+          Interlocked.CompareExchange(ref _syncRoot, new object(), null);
+
+        return _syncRoot;
+      }
+    }
+
+    public object UnderlyingDictionary
+    {
+      get
+      {
+        if (_genericDictionary != null)
+          return _genericDictionary;
+        else
+          return _dictionary;
+      }
+    }
+  }
+}
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/DynamicProxy.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/DynamicProxy.cs
new file mode 100644 (file)
index 0000000..fc4e496
--- /dev/null
@@ -0,0 +1,87 @@
+#if !(NET35 || NET20 || WINDOWS_PHONE)
+using System;
+using System.Collections.Generic;
+using System.Dynamic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Text;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal class DynamicProxy<T>
+  {
+    public virtual IEnumerable<string> GetDynamicMemberNames(T instance)
+    {
+      return new string[0];
+    }
+
+    public virtual bool TryBinaryOperation(T instance, BinaryOperationBinder binder, object arg, out object result)
+    {
+      result = null;
+      return false;
+    }
+
+    public virtual bool TryConvert(T instance, ConvertBinder binder, out object result)
+    {
+      result = null;
+      return false;
+    }
+
+    public virtual bool TryCreateInstance(T instance, CreateInstanceBinder binder, object[] args, out object result)
+    {
+      result = null;
+      return false;
+    }
+
+    public virtual bool TryDeleteIndex(T instance, DeleteIndexBinder binder, object[] indexes)
+    {
+      return false;
+    }
+
+    public virtual bool TryDeleteMember(T instance, DeleteMemberBinder binder)
+    {
+      return false;
+    }
+
+    public virtual bool TryGetIndex(T instance, GetIndexBinder binder, object[] indexes, out object result)
+    {
+      result = null;
+      return false;
+    }
+
+    public virtual bool TryGetMember(T instance, GetMemberBinder binder, out object result)
+    {
+      result = null;
+      return false;
+    }
+
+    public virtual bool TryInvoke(T instance, InvokeBinder binder, object[] args, out object result)
+    {
+      result = null;
+      return false;
+    }
+
+    public virtual bool TryInvokeMember(T instance, InvokeMemberBinder binder, object[] args, out object result)
+    {
+      result = null;
+      return false;
+    }
+
+    public virtual bool TrySetIndex(T instance, SetIndexBinder binder, object[] indexes, object value)
+    {
+      return false;
+    }
+
+    public virtual bool TrySetMember(T instance, SetMemberBinder binder, object value)
+    {
+      return false;
+    }
+
+    public virtual bool TryUnaryOperation(T instance, UnaryOperationBinder binder, out object result)
+    {
+      result = null;
+      return false;
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/DynamicProxyMetaObject.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/DynamicProxyMetaObject.cs
new file mode 100644 (file)
index 0000000..51b9d4c
--- /dev/null
@@ -0,0 +1,398 @@
+#if !(NET35 || NET20 || WINDOWS_PHONE)
+using System;
+using System.Collections.Generic;
+using System.Dynamic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reflection;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal sealed class DynamicProxyMetaObject<T> : DynamicMetaObject
+  {
+    private readonly DynamicProxy<T> _proxy;
+    private readonly bool _dontFallbackFirst;
+
+    internal DynamicProxyMetaObject(Expression expression, T value, DynamicProxy<T> proxy, bool dontFallbackFirst)
+      : base(expression, BindingRestrictions.Empty, value)
+    {
+      _proxy = proxy;
+      _dontFallbackFirst = dontFallbackFirst;
+    }
+
+    private new T Value { get { return (T)base.Value; } }
+
+    private bool IsOverridden(string method)
+    {
+      return _proxy.GetType().GetMember(method, MemberTypes.Method, BindingFlags.Public | BindingFlags.Instance).Cast<MethodInfo>()
+        .Any(info =>
+          // check that the method overrides the original on DynamicObjectProxy
+          info.DeclaringType != typeof(DynamicProxy<T>) &&
+          info.GetBaseDefinition().DeclaringType == typeof(DynamicProxy<T>));
+    }
+
+    public override DynamicMetaObject BindGetMember(GetMemberBinder binder)
+    {
+      return IsOverridden("TryGetMember")
+           ? CallMethodWithResult("TryGetMember", binder, NoArgs, e => binder.FallbackGetMember(this, e))
+           : base.BindGetMember(binder);
+    }
+
+    public override DynamicMetaObject BindSetMember(SetMemberBinder binder, DynamicMetaObject value)
+    {
+      return IsOverridden("TrySetMember")
+           ? CallMethodReturnLast("TrySetMember", binder, GetArgs(value), e => binder.FallbackSetMember(this, value, e))
+           : base.BindSetMember(binder, value);
+    }
+
+    public override DynamicMetaObject BindDeleteMember(DeleteMemberBinder binder)
+    {
+      return IsOverridden("TryDeleteMember")
+           ? CallMethodNoResult("TryDeleteMember", binder, NoArgs, e => binder.FallbackDeleteMember(this, e))
+           : base.BindDeleteMember(binder);
+    }
+
+
+    public override DynamicMetaObject BindConvert(ConvertBinder binder)
+    {
+      return IsOverridden("TryConvert")
+           ? CallMethodWithResult("TryConvert", binder, NoArgs, e => binder.FallbackConvert(this, e))
+           : base.BindConvert(binder);
+    }
+
+    public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args)
+    {
+      if (!IsOverridden("TryInvokeMember"))
+        return base.BindInvokeMember(binder, args);
+
+      //
+      // Generate a tree like:
+      //
+      // {
+      //   object result;
+      //   TryInvokeMember(payload, out result)
+      //      ? result
+      //      : TryGetMember(payload, out result)
+      //          ? FallbackInvoke(result)
+      //          : fallbackResult
+      // }
+      //
+      // Then it calls FallbackInvokeMember with this tree as the
+      // "error", giving the language the option of using this
+      // tree or doing .NET binding.
+      //
+      Fallback fallback = e => binder.FallbackInvokeMember(this, args, e);
+
+      DynamicMetaObject call = BuildCallMethodWithResult(
+          "TryInvokeMember",
+          binder,
+          GetArgArray(args),
+          BuildCallMethodWithResult(
+              "TryGetMember",
+              new GetBinderAdapter(binder),
+              NoArgs,
+              fallback(null),
+              e => binder.FallbackInvoke(e, args, null)
+          ),
+          null
+      );
+
+      return _dontFallbackFirst ? call : fallback(call);
+    }
+
+
+    public override DynamicMetaObject BindCreateInstance(CreateInstanceBinder binder, DynamicMetaObject[] args)
+    {
+      return IsOverridden("TryCreateInstance")
+           ? CallMethodWithResult("TryCreateInstance", binder, GetArgArray(args), e => binder.FallbackCreateInstance(this, args, e))
+           : base.BindCreateInstance(binder, args);
+    }
+
+    public override DynamicMetaObject BindInvoke(InvokeBinder binder, DynamicMetaObject[] args)
+    {
+      return IsOverridden("TryInvoke")
+        ? CallMethodWithResult("TryInvoke", binder, GetArgArray(args), e => binder.FallbackInvoke(this, args, e))
+        : base.BindInvoke(binder, args);
+    }
+
+    public override DynamicMetaObject BindBinaryOperation(BinaryOperationBinder binder, DynamicMetaObject arg)
+    {
+      return IsOverridden("TryBinaryOperation")
+        ? CallMethodWithResult("TryBinaryOperation", binder, GetArgs(arg), e => binder.FallbackBinaryOperation(this, arg, e))
+        : base.BindBinaryOperation(binder, arg);
+    }
+
+    public override DynamicMetaObject BindUnaryOperation(UnaryOperationBinder binder)
+    {
+      return IsOverridden("TryUnaryOperation")
+           ? CallMethodWithResult("TryUnaryOperation", binder, NoArgs, e => binder.FallbackUnaryOperation(this, e))
+           : base.BindUnaryOperation(binder);
+    }
+
+    public override DynamicMetaObject BindGetIndex(GetIndexBinder binder, DynamicMetaObject[] indexes)
+    {
+      return IsOverridden("TryGetIndex")
+           ? CallMethodWithResult("TryGetIndex", binder, GetArgArray(indexes), e => binder.FallbackGetIndex(this, indexes, e))
+           : base.BindGetIndex(binder, indexes);
+    }
+
+    public override DynamicMetaObject BindSetIndex(SetIndexBinder binder, DynamicMetaObject[] indexes, DynamicMetaObject value)
+    {
+      return IsOverridden("TrySetIndex")
+           ? CallMethodReturnLast("TrySetIndex", binder, GetArgArray(indexes, value), e => binder.FallbackSetIndex(this, indexes, value, e))
+           : base.BindSetIndex(binder, indexes, value);
+    }
+
+    public override DynamicMetaObject BindDeleteIndex(DeleteIndexBinder binder, DynamicMetaObject[] indexes)
+    {
+      return IsOverridden("TryDeleteIndex")
+           ? CallMethodNoResult("TryDeleteIndex", binder, GetArgArray(indexes), e => binder.FallbackDeleteIndex(this, indexes, e))
+           : base.BindDeleteIndex(binder, indexes);
+    }
+
+    private delegate DynamicMetaObject Fallback(DynamicMetaObject errorSuggestion);
+
+    private readonly static Expression[] NoArgs = new Expression[0];
+
+    private static Expression[] GetArgs(params DynamicMetaObject[] args)
+    {
+      return args.Select(arg => Expression.Convert(arg.Expression, typeof(object))).ToArray();
+    }
+
+    private static Expression[] GetArgArray(DynamicMetaObject[] args)
+    {
+      return new[] { Expression.NewArrayInit(typeof(object), GetArgs(args)) };
+    }
+
+    private static Expression[] GetArgArray(DynamicMetaObject[] args, DynamicMetaObject value)
+    {
+      return new Expression[]
+            {
+                Expression.NewArrayInit(typeof(object), GetArgs(args)),
+                Expression.Convert(value.Expression, typeof(object))
+            };
+    }
+
+    private static ConstantExpression Constant(DynamicMetaObjectBinder binder)
+    {
+      Type t = binder.GetType();
+      while (!t.IsVisible)
+        t = t.BaseType;
+      return Expression.Constant(binder, t);
+    }
+
+    /// <summary>
+    /// Helper method for generating a MetaObject which calls a
+    /// specific method on Dynamic that returns a result
+    /// </summary>
+    private DynamicMetaObject CallMethodWithResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback, Fallback fallbackInvoke = null)
+    {
+      //
+      // First, call fallback to do default binding
+      // This produces either an error or a call to a .NET member
+      //
+      DynamicMetaObject fallbackResult = fallback(null);
+
+      DynamicMetaObject callDynamic = BuildCallMethodWithResult(methodName, binder, args, fallbackResult, fallbackInvoke);
+
+      //
+      // Now, call fallback again using our new MO as the error
+      // When we do this, one of two things can happen:
+      //   1. Binding will succeed, and it will ignore our call to
+      //      the dynamic method, OR
+      //   2. Binding will fail, and it will use the MO we created
+      //      above.
+      //
+
+      return _dontFallbackFirst ? callDynamic : fallback(callDynamic);
+    }
+
+    private DynamicMetaObject BuildCallMethodWithResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, DynamicMetaObject fallbackResult, Fallback fallbackInvoke)
+    {
+      //
+      // Build a new expression like:
+      // {
+      //   object result;
+      //   TryGetMember(payload, out result) ? fallbackInvoke(result) : fallbackResult
+      // }
+      //
+      ParameterExpression result = Expression.Parameter(typeof(object), null);
+
+      IList<Expression> callArgs = new List<Expression>();
+      callArgs.Add(Expression.Convert(Expression, typeof(T)));
+      callArgs.Add(Constant(binder));
+      callArgs.AddRange(args);
+      callArgs.Add(result);
+
+      DynamicMetaObject resultMO = new DynamicMetaObject(result, BindingRestrictions.Empty);
+
+      // Need to add a conversion if calling TryConvert
+      if (binder.ReturnType != typeof (object))
+      {
+        UnaryExpression convert = Expression.Convert(resultMO.Expression, binder.ReturnType);
+        // will always be a cast or unbox
+
+        resultMO = new DynamicMetaObject(convert, resultMO.Restrictions);
+      }
+
+      if (fallbackInvoke != null)
+        resultMO = fallbackInvoke(resultMO);
+
+      DynamicMetaObject callDynamic = new DynamicMetaObject(
+        Expression.Block(
+          new[] {result},
+          Expression.Condition(
+            Expression.Call(
+              Expression.Constant(_proxy),
+              typeof(DynamicProxy<T>).GetMethod(methodName),
+              callArgs
+              ),
+            resultMO.Expression,
+            fallbackResult.Expression,
+            binder.ReturnType
+            )
+          ),
+        GetRestrictions().Merge(resultMO.Restrictions).Merge(fallbackResult.Restrictions)
+        );
+
+      return callDynamic;
+    }
+
+    /// <summary>
+    /// Helper method for generating a MetaObject which calls a
+    /// specific method on Dynamic, but uses one of the arguments for
+    /// the result.
+    /// </summary>
+    private DynamicMetaObject CallMethodReturnLast(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback)
+    {
+      //
+      // First, call fallback to do default binding
+      // This produces either an error or a call to a .NET member
+      //
+      DynamicMetaObject fallbackResult = fallback(null);
+
+      //
+      // Build a new expression like:
+      // {
+      //   object result;
+      //   TrySetMember(payload, result = value) ? result : fallbackResult
+      // }
+      //
+      ParameterExpression result = Expression.Parameter(typeof(object), null);
+
+      IList<Expression> callArgs = new List<Expression>();
+      callArgs.Add(Expression.Convert(Expression, typeof (T)));
+      callArgs.Add(Constant(binder));
+      callArgs.AddRange(args);
+      callArgs[args.Length + 1] = Expression.Assign(result, callArgs[args.Length + 1]);
+
+      DynamicMetaObject callDynamic = new DynamicMetaObject(
+          Expression.Block(
+              new[] { result },
+              Expression.Condition(
+                  Expression.Call(
+                      Expression.Constant(_proxy),
+                      typeof(DynamicProxy<T>).GetMethod(methodName),
+                      callArgs
+                  ),
+                  result,
+                  fallbackResult.Expression,
+                  typeof(object)
+              )
+          ),
+          GetRestrictions().Merge(fallbackResult.Restrictions)
+      );
+
+      //
+      // Now, call fallback again using our new MO as the error
+      // When we do this, one of two things can happen:
+      //   1. Binding will succeed, and it will ignore our call to
+      //      the dynamic method, OR
+      //   2. Binding will fail, and it will use the MO we created
+      //      above.
+      //
+      return _dontFallbackFirst ? callDynamic : fallback(callDynamic);
+    }
+
+    /// <summary>
+    /// Helper method for generating a MetaObject which calls a
+    /// specific method on Dynamic, but uses one of the arguments for
+    /// the result.
+    /// </summary>
+    private DynamicMetaObject CallMethodNoResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback)
+    {
+      //
+      // First, call fallback to do default binding
+      // This produces either an error or a call to a .NET member
+      //
+      DynamicMetaObject fallbackResult = fallback(null);
+
+      IList<Expression> callArgs = new List<Expression>();
+      callArgs.Add(Expression.Convert(Expression, typeof(T)));
+      callArgs.Add(Constant(binder));
+      callArgs.AddRange(args);
+
+      //
+      // Build a new expression like:
+      //   if (TryDeleteMember(payload)) { } else { fallbackResult }
+      //
+      DynamicMetaObject callDynamic = new DynamicMetaObject(
+        Expression.Condition(
+          Expression.Call(
+            Expression.Constant(_proxy),
+            typeof(DynamicProxy<T>).GetMethod(methodName),
+            callArgs
+            ),
+          Expression.Empty(),
+          fallbackResult.Expression,
+          typeof (void)
+          ),
+        GetRestrictions().Merge(fallbackResult.Restrictions)
+        );
+
+      //
+      // Now, call fallback again using our new MO as the error
+      // When we do this, one of two things can happen:
+      //   1. Binding will succeed, and it will ignore our call to
+      //      the dynamic method, OR
+      //   2. Binding will fail, and it will use the MO we created
+      //      above.
+      //
+      return _dontFallbackFirst ? callDynamic : fallback(callDynamic);
+    }
+
+    /// <summary>
+    /// Returns a Restrictions object which includes our current restrictions merged
+    /// with a restriction limiting our type
+    /// </summary>
+    private BindingRestrictions GetRestrictions()
+    {
+      return (Value == null && HasValue)
+           ? BindingRestrictions.GetInstanceRestriction(Expression, null)
+           : BindingRestrictions.GetTypeRestriction(Expression, LimitType);
+    }
+
+    public override IEnumerable<string> GetDynamicMemberNames()
+    {
+      return _proxy.GetDynamicMemberNames(Value);
+    }
+
+    // It is okay to throw NotSupported from this binder. This object
+    // is only used by DynamicObject.GetMember--it is not expected to
+    // (and cannot) implement binding semantics. It is just so the DO
+    // can use the Name and IgnoreCase properties.
+    private sealed class GetBinderAdapter : GetMemberBinder
+    {
+      internal GetBinderAdapter(InvokeMemberBinder binder) :
+        base(binder.Name, binder.IgnoreCase)
+      {
+      }
+
+      public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
+      {
+        throw new NotSupportedException();
+      }
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/DynamicReflectionDelegateFactory.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/DynamicReflectionDelegateFactory.cs
new file mode 100644 (file)
index 0000000..7dc47e5
--- /dev/null
@@ -0,0 +1,200 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+#if !PocketPC && !SILVERLIGHT
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Text;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal class DynamicReflectionDelegateFactory : ReflectionDelegateFactory
+  {
+    public static DynamicReflectionDelegateFactory Instance = new DynamicReflectionDelegateFactory();
+
+    private static DynamicMethod CreateDynamicMethod(string name, Type returnType, Type[] parameterTypes, Type owner)
+    {
+      DynamicMethod dynamicMethod = !owner.IsInterface
+        ? new DynamicMethod(name, returnType, parameterTypes, owner, true)
+        : new DynamicMethod(name, returnType, parameterTypes, owner.Module, true);
+
+      return dynamicMethod;
+    }
+
+    public override MethodCall<T, object> CreateMethodCall<T>(MethodBase method)
+    {
+      DynamicMethod dynamicMethod = CreateDynamicMethod(method.ToString(), typeof(object), new[] { typeof(object), typeof(object[]) }, method.DeclaringType);
+      ILGenerator generator = dynamicMethod.GetILGenerator();
+
+      ParameterInfo[] args = method.GetParameters();
+
+      Label argsOk = generator.DefineLabel();
+
+      generator.Emit(OpCodes.Ldarg_1);
+      generator.Emit(OpCodes.Ldlen);
+      generator.Emit(OpCodes.Ldc_I4, args.Length);
+      generator.Emit(OpCodes.Beq, argsOk);
+
+      generator.Emit(OpCodes.Newobj, typeof(TargetParameterCountException).GetConstructor(Type.EmptyTypes));
+      generator.Emit(OpCodes.Throw);
+
+      generator.MarkLabel(argsOk);
+
+      if (!method.IsConstructor && !method.IsStatic)
+        generator.PushInstance(method.DeclaringType);
+
+      for (int i = 0; i < args.Length; i++)
+      {
+        generator.Emit(OpCodes.Ldarg_1);
+        generator.Emit(OpCodes.Ldc_I4, i);
+        generator.Emit(OpCodes.Ldelem_Ref);
+
+        generator.UnboxIfNeeded(args[i].ParameterType);
+      }
+
+      if (method.IsConstructor)
+        generator.Emit(OpCodes.Newobj, (ConstructorInfo)method);
+      else if (method.IsFinal || !method.IsVirtual)
+        generator.CallMethod((MethodInfo)method);
+
+      Type returnType = method.IsConstructor
+        ? method.DeclaringType
+        : ((MethodInfo)method).ReturnType;
+
+      if (returnType != typeof(void))
+        generator.BoxIfNeeded(returnType);
+      else
+        generator.Emit(OpCodes.Ldnull);
+
+      generator.Return();
+
+      return (MethodCall<T, object>)dynamicMethod.CreateDelegate(typeof(MethodCall<T, object>));
+    }
+
+    public override Func<T> CreateDefaultConstructor<T>(Type type)
+    {
+      DynamicMethod dynamicMethod = CreateDynamicMethod("Create" + type.FullName, typeof(object), Type.EmptyTypes, type);
+      dynamicMethod.InitLocals = true;
+      ILGenerator generator = dynamicMethod.GetILGenerator();
+
+      if (type.IsValueType)
+      {
+        generator.DeclareLocal(type);
+        generator.Emit(OpCodes.Ldloc_0);
+        generator.Emit(OpCodes.Box, type);
+      }
+      else
+      {
+        ConstructorInfo constructorInfo =
+          type.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null,
+                              Type.EmptyTypes, null);
+
+        if (constructorInfo == null)
+          throw new Exception("Could not get constructor for {0}.".FormatWith(CultureInfo.InvariantCulture, type));
+
+        generator.Emit(OpCodes.Newobj, constructorInfo);
+      }
+
+      generator.Return();
+
+      return (Func<T>)dynamicMethod.CreateDelegate(typeof(Func<T>));
+    }
+
+    public override Func<T, object> CreateGet<T>(PropertyInfo propertyInfo)
+    {
+      MethodInfo getMethod = propertyInfo.GetGetMethod(true);
+      if (getMethod == null)
+        throw new Exception("Property '{0}' does not have a getter.".FormatWith(CultureInfo.InvariantCulture,
+                                                                                propertyInfo.Name));
+
+      DynamicMethod dynamicMethod = CreateDynamicMethod("Get" + propertyInfo.Name, typeof(T), new[] { typeof(object) }, propertyInfo.DeclaringType);
+
+      ILGenerator generator = dynamicMethod.GetILGenerator();
+
+      if (!getMethod.IsStatic)
+        generator.PushInstance(propertyInfo.DeclaringType);
+
+      generator.CallMethod(getMethod);
+      generator.BoxIfNeeded(propertyInfo.PropertyType);
+      generator.Return();
+
+      return (Func<T, object>)dynamicMethod.CreateDelegate(typeof(Func<T, object>));
+    }
+
+    public override Func<T, object> CreateGet<T>(FieldInfo fieldInfo)
+    {
+      DynamicMethod dynamicMethod = CreateDynamicMethod("Get" + fieldInfo.Name, typeof(T), new[] { typeof(object) }, fieldInfo.DeclaringType);
+
+      ILGenerator generator = dynamicMethod.GetILGenerator();
+
+      if (!fieldInfo.IsStatic)
+        generator.PushInstance(fieldInfo.DeclaringType);
+
+      generator.Emit(OpCodes.Ldfld, fieldInfo);
+      generator.BoxIfNeeded(fieldInfo.FieldType);
+      generator.Return();
+
+      return (Func<T, object>)dynamicMethod.CreateDelegate(typeof(Func<T, object>));
+    }
+
+    public override Action<T, object> CreateSet<T>(FieldInfo fieldInfo)
+    {
+      DynamicMethod dynamicMethod = CreateDynamicMethod("Set" + fieldInfo.Name, null, new[] { typeof(object), typeof(object) }, fieldInfo.DeclaringType);
+      ILGenerator generator = dynamicMethod.GetILGenerator();
+
+      if (!fieldInfo.IsStatic)
+        generator.PushInstance(fieldInfo.DeclaringType);
+
+      generator.Emit(OpCodes.Ldarg_1);
+      generator.UnboxIfNeeded(fieldInfo.FieldType);
+      generator.Emit(OpCodes.Stfld, fieldInfo);
+      generator.Return();
+
+      return (Action<T, object>)dynamicMethod.CreateDelegate(typeof(Action<T, object>));
+    }
+
+    public override Action<T, object> CreateSet<T>(PropertyInfo propertyInfo)
+    {
+      MethodInfo setMethod = propertyInfo.GetSetMethod(true);
+      DynamicMethod dynamicMethod = CreateDynamicMethod("Set" + propertyInfo.Name, null, new[] { typeof(object), typeof(object) }, propertyInfo.DeclaringType);
+      ILGenerator generator = dynamicMethod.GetILGenerator();
+
+      if (!setMethod.IsStatic)
+        generator.PushInstance(propertyInfo.DeclaringType);
+
+      generator.Emit(OpCodes.Ldarg_1);
+      generator.UnboxIfNeeded(propertyInfo.PropertyType);
+      generator.CallMethod(setMethod);
+      generator.Return();
+
+      return (Action<T, object>)dynamicMethod.CreateDelegate(typeof(Action<T, object>));
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/DynamicUtils.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/DynamicUtils.cs
new file mode 100644 (file)
index 0000000..b028d61
--- /dev/null
@@ -0,0 +1,200 @@
+#if !(NET35 || NET20 || WINDOWS_PHONE)
+using System;
+using System.Collections.Generic;
+using System.Dynamic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Globalization;
+using Newtonsoft.Json.Serialization;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal static class DynamicUtils
+  {
+    internal static class BinderWrapper
+    {
+#if !SILVERLIGHT
+      public const string CSharpAssemblyName = "Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
+#else
+      public const string CSharpAssemblyName = "Microsoft.CSharp, Version=2.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";
+#endif
+
+      private const string BinderTypeName = "Microsoft.CSharp.RuntimeBinder.Binder, " + CSharpAssemblyName;
+      private const string CSharpArgumentInfoTypeName = "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo, " + CSharpAssemblyName;
+      private const string CSharpArgumentInfoFlagsTypeName = "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, " + CSharpAssemblyName;
+      private const string CSharpBinderFlagsTypeName = "Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, " + CSharpAssemblyName;
+
+      private static object _getCSharpArgumentInfoArray;
+      private static object _setCSharpArgumentInfoArray;
+      private static MethodCall<object, object> _getMemberCall;
+      private static MethodCall<object, object> _setMemberCall;
+      private static bool _init;
+
+      private static void Init()
+      {
+        if (!_init)
+        {
+          Type binderType = Type.GetType(BinderTypeName, false);
+          if (binderType == null)
+            throw new Exception("Could not resolve type '{0}'. You may need to add a reference to Microsoft.CSharp.dll to work with dynamic types.".FormatWith(CultureInfo.InvariantCulture, BinderTypeName));
+
+          // None
+          _getCSharpArgumentInfoArray = CreateSharpArgumentInfoArray(0);
+          // None, Constant | UseCompileTimeType
+          _setCSharpArgumentInfoArray = CreateSharpArgumentInfoArray(0, 3);
+          CreateMemberCalls();
+
+          _init = true;
+        }
+      }
+
+      private static object CreateSharpArgumentInfoArray(params int[] values)
+      {
+        Type csharpArgumentInfoType = Type.GetType(CSharpArgumentInfoTypeName);
+        Type csharpArgumentInfoFlags = Type.GetType(CSharpArgumentInfoFlagsTypeName);
+
+        Array a = Array.CreateInstance(csharpArgumentInfoType, values.Length);
+
+        for (int i = 0; i < values.Length; i++)
+        {
+          MethodInfo createArgumentInfoMethod = csharpArgumentInfoType.GetMethod("Create", BindingFlags.Public | BindingFlags.Static, null, new[] { csharpArgumentInfoFlags, typeof(string) }, null);
+          object arg = createArgumentInfoMethod.Invoke(null, new object[] { 0, null });
+          a.SetValue(arg, i);
+        }
+
+        return a;
+      }
+
+      private static void CreateMemberCalls()
+      {
+        Type csharpArgumentInfoType = Type.GetType(CSharpArgumentInfoTypeName);
+        Type csharpBinderFlagsType = Type.GetType(CSharpBinderFlagsTypeName);
+        Type binderType = Type.GetType(BinderTypeName);
+
+        Type csharpArgumentInfoTypeEnumerableType = typeof(IEnumerable<>).MakeGenericType(csharpArgumentInfoType);
+
+        MethodInfo getMemberMethod = binderType.GetMethod("GetMember", BindingFlags.Public | BindingFlags.Static, null, new[] { csharpBinderFlagsType, typeof(string), typeof(Type), csharpArgumentInfoTypeEnumerableType }, null);
+        _getMemberCall = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall<object>(getMemberMethod);
+
+        MethodInfo setMemberMethod = binderType.GetMethod("SetMember", BindingFlags.Public | BindingFlags.Static, null, new[] { csharpBinderFlagsType, typeof(string), typeof(Type), csharpArgumentInfoTypeEnumerableType }, null);
+        _setMemberCall = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall<object>(setMemberMethod);
+      }
+
+      public static CallSiteBinder GetMember(string name, Type context)
+      {
+        Init();
+        return (CallSiteBinder)_getMemberCall(null, 0, name, context, _getCSharpArgumentInfoArray);
+      }
+
+      public static CallSiteBinder SetMember(string name, Type context)
+      {
+        Init();
+        return (CallSiteBinder)_setMemberCall(null, 0, name, context, _setCSharpArgumentInfoArray);
+      }
+    }
+
+    public static bool TryGetMember(this IDynamicMetaObjectProvider dynamicProvider, string name, out object value)
+    {
+      ValidationUtils.ArgumentNotNull(dynamicProvider, "dynamicProvider");
+
+      GetMemberBinder getMemberBinder = (GetMemberBinder) BinderWrapper.GetMember(name, typeof (DynamicUtils));
+
+      CallSite<Func<CallSite, object, object>> callSite = CallSite<Func<CallSite, object, object>>.Create(new NoThrowGetBinderMember(getMemberBinder));
+
+      object result = callSite.Target(callSite, dynamicProvider);
+
+      if (!ReferenceEquals(result, NoThrowExpressionVisitor.ErrorResult))
+      {
+        value = result;
+        return true;
+      }
+      else
+      {
+        value = null;
+        return false;
+      }
+    }
+
+    public static bool TrySetMember(this IDynamicMetaObjectProvider dynamicProvider, string name, object value)
+    {
+      ValidationUtils.ArgumentNotNull(dynamicProvider, "dynamicProvider");
+
+      SetMemberBinder binder = (SetMemberBinder)BinderWrapper.SetMember(name, typeof(DynamicUtils));
+
+      var setterSite = CallSite<Func<CallSite, object, object, object>>.Create(new NoThrowSetBinderMember(binder));
+
+      object result = setterSite.Target(setterSite, dynamicProvider, value);
+
+      return !ReferenceEquals(result, NoThrowExpressionVisitor.ErrorResult);
+    }
+
+    public static IEnumerable<string> GetDynamicMemberNames(this IDynamicMetaObjectProvider dynamicProvider)
+    {
+      DynamicMetaObject metaObject = dynamicProvider.GetMetaObject(Expression.Constant(dynamicProvider));
+      return metaObject.GetDynamicMemberNames();
+    }
+
+    internal class NoThrowGetBinderMember : GetMemberBinder
+    {
+      private readonly GetMemberBinder _innerBinder;
+
+      public NoThrowGetBinderMember(GetMemberBinder innerBinder)
+        : base(innerBinder.Name, innerBinder.IgnoreCase)
+      {
+        _innerBinder = innerBinder;
+      }
+
+      public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
+      {
+        DynamicMetaObject retMetaObject = _innerBinder.Bind(target, new DynamicMetaObject[] { });
+
+        NoThrowExpressionVisitor noThrowVisitor = new NoThrowExpressionVisitor();
+        Expression resultExpression = noThrowVisitor.Visit(retMetaObject.Expression);
+
+        DynamicMetaObject finalMetaObject = new DynamicMetaObject(resultExpression, retMetaObject.Restrictions);
+        return finalMetaObject;
+      }
+    }
+
+    internal class NoThrowSetBinderMember : SetMemberBinder
+    {
+      private readonly SetMemberBinder _innerBinder;
+
+      public NoThrowSetBinderMember(SetMemberBinder innerBinder)
+        : base(innerBinder.Name, innerBinder.IgnoreCase)
+      {
+        _innerBinder = innerBinder;
+      }
+
+      public override DynamicMetaObject FallbackSetMember(DynamicMetaObject target, DynamicMetaObject value, DynamicMetaObject errorSuggestion)
+      {
+        DynamicMetaObject retMetaObject = _innerBinder.Bind(target, new DynamicMetaObject[] { value });
+
+        NoThrowExpressionVisitor noThrowVisitor = new NoThrowExpressionVisitor();
+        Expression resultExpression = noThrowVisitor.Visit(retMetaObject.Expression);
+
+        DynamicMetaObject finalMetaObject = new DynamicMetaObject(resultExpression, retMetaObject.Restrictions);
+        return finalMetaObject;
+      }
+    }
+
+
+    internal class NoThrowExpressionVisitor : ExpressionVisitor
+    {
+      internal static readonly object ErrorResult = new object();
+
+      protected override Expression VisitConditional(ConditionalExpression node)
+      {
+        // if the result of a test is to throw an error, rewrite to result an error result value
+        if (node.IfFalse.NodeType == ExpressionType.Throw)
+          return Expression.Condition(node.Test, node.IfTrue, Expression.Constant(ErrorResult));
+
+        return base.VisitConditional(node);
+      }
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/DynamicWrapper.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/DynamicWrapper.cs
new file mode 100644 (file)
index 0000000..d056fd2
--- /dev/null
@@ -0,0 +1,294 @@
+#if !SILVERLIGHT && !PocketPC
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Resources;
+using System.Text;
+using System.Threading;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal class DynamicWrapperBase
+  {
+    internal protected object UnderlyingObject;
+  }
+
+  internal static class DynamicWrapper
+  {
+    private static readonly object _lock = new object();
+    private static readonly WrapperDictionary _wrapperDictionary = new WrapperDictionary();
+
+    private static ModuleBuilder _moduleBuilder;
+
+    private static ModuleBuilder ModuleBuilder
+    {
+      get
+      {
+        Init();
+        return _moduleBuilder;
+      }
+    }
+
+    private static void Init()
+    {
+      if (_moduleBuilder == null)
+      {
+        lock (_lock)
+        {
+          if (_moduleBuilder == null)
+          {
+            AssemblyName assemblyName = new AssemblyName("Newtonsoft.Json.Dynamic");
+            assemblyName.KeyPair = new StrongNameKeyPair(GetStrongKey());
+
+            AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
+            _moduleBuilder = assembly.DefineDynamicModule("Newtonsoft.Json.DynamicModule", false);
+          }
+        }
+      }
+    }
+
+    private static byte[] GetStrongKey()
+    {
+      string name;
+#if NET35
+      name = "Newtonsoft.Json.Net35.Dynamic.snk";
+#else
+      name = "Newtonsoft.Json.Dynamic.snk";
+#endif
+
+      using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name))
+      {
+        if (stream == null)
+          throw new MissingManifestResourceException("Should have a Newtonsoft.Json.Dynamic.snk as an embedded resource.");
+
+        int length = (int)stream.Length;
+        byte[] buffer = new byte[length];
+        stream.Read(buffer, 0, length);
+
+        return buffer;
+      }
+    }
+
+    public static Type GetWrapper(Type interfaceType, Type realObjectType)
+    {
+      Type wrapperType = _wrapperDictionary.GetType(interfaceType, realObjectType);
+
+      if (wrapperType == null)
+      {
+        lock (_lock)
+        {
+          wrapperType = _wrapperDictionary.GetType(interfaceType, realObjectType);
+
+          if (wrapperType == null)
+          {
+            wrapperType = GenerateWrapperType(interfaceType, realObjectType);
+            _wrapperDictionary.SetType(interfaceType, realObjectType, wrapperType);
+          }
+        }
+      }
+
+      return wrapperType;
+    }
+
+    public static object GetUnderlyingObject(object wrapper)
+    {
+      DynamicWrapperBase wrapperBase = wrapper as DynamicWrapperBase;
+      if (wrapperBase == null)
+        throw new ArgumentException("Object is not a wrapper.", "wrapper");
+
+      return wrapperBase.UnderlyingObject;
+    }
+
+    private static Type GenerateWrapperType(Type interfaceType, Type underlyingType)
+    {
+      TypeBuilder wrapperBuilder = ModuleBuilder.DefineType(
+          "{0}_{1}_Wrapper".FormatWith(CultureInfo.InvariantCulture, interfaceType.Name, underlyingType.Name),
+          TypeAttributes.NotPublic | TypeAttributes.Sealed,
+          typeof(DynamicWrapperBase),
+          new[] { interfaceType });
+
+      WrapperMethodBuilder wrapperMethod = new WrapperMethodBuilder(underlyingType, wrapperBuilder);
+
+      foreach (MethodInfo method in interfaceType.AllMethods())
+      {
+        wrapperMethod.Generate(method);
+      }
+
+      return wrapperBuilder.CreateType();
+    }
+
+    public static T CreateWrapper<T>(object realObject) where T : class
+    {
+      var dynamicType = GetWrapper(typeof(T), realObject.GetType());
+      var dynamicWrapper = (DynamicWrapperBase)Activator.CreateInstance(dynamicType);
+
+      dynamicWrapper.UnderlyingObject = realObject;
+
+      return dynamicWrapper as T;
+    }
+  }
+
+  internal class WrapperMethodBuilder
+  {
+    private readonly Type _realObjectType;
+    private readonly TypeBuilder _wrapperBuilder;
+
+    public WrapperMethodBuilder(Type realObjectType, TypeBuilder proxyBuilder)
+    {
+      _realObjectType = realObjectType;
+      _wrapperBuilder = proxyBuilder;
+    }
+
+    public void Generate(MethodInfo newMethod)
+    {
+      if (newMethod.IsGenericMethod)
+        newMethod = newMethod.GetGenericMethodDefinition();
+
+      FieldInfo srcField = typeof(DynamicWrapperBase).GetField("UnderlyingObject", BindingFlags.Instance | BindingFlags.NonPublic);
+
+      var parameters = newMethod.GetParameters();
+      var parameterTypes = parameters.Select(parameter => parameter.ParameterType).ToArray();
+
+      MethodBuilder methodBuilder = _wrapperBuilder.DefineMethod(
+          newMethod.Name,
+          MethodAttributes.Public | MethodAttributes.Virtual,
+          newMethod.ReturnType,
+          parameterTypes);
+
+      if (newMethod.IsGenericMethod)
+      {
+        methodBuilder.DefineGenericParameters(
+            newMethod.GetGenericArguments().Select(arg => arg.Name).ToArray());
+      }
+
+      ILGenerator ilGenerator = methodBuilder.GetILGenerator();
+
+      LoadUnderlyingObject(ilGenerator, srcField);
+      PushParameters(parameters, ilGenerator);
+      ExecuteMethod(newMethod, parameterTypes, ilGenerator);
+      Return(ilGenerator);
+    }
+
+    private static void Return(ILGenerator ilGenerator)
+    {
+      ilGenerator.Emit(OpCodes.Ret);
+    }
+
+    private void ExecuteMethod(MethodBase newMethod, Type[] parameterTypes, ILGenerator ilGenerator)
+    {
+      MethodInfo srcMethod = GetMethod(newMethod, parameterTypes);
+
+      if (srcMethod == null)
+        throw new MissingMethodException("Unable to find method " + newMethod.Name + " on " + _realObjectType.FullName);
+
+      ilGenerator.Emit(OpCodes.Call, srcMethod);
+    }
+
+    private MethodInfo GetMethod(MethodBase realMethod, Type[] parameterTypes)
+    {
+      if (realMethod.IsGenericMethod)
+        return _realObjectType.GetGenericMethod(realMethod.Name, parameterTypes);
+
+      return _realObjectType.GetMethod(realMethod.Name, parameterTypes);
+    }
+
+    private static void PushParameters(ICollection<ParameterInfo> parameters, ILGenerator ilGenerator)
+    {
+      for (int i = 1; i < parameters.Count + 1; i++)
+        ilGenerator.Emit(OpCodes.Ldarg, i);
+    }
+
+    private static void LoadUnderlyingObject(ILGenerator ilGenerator, FieldInfo srcField)
+    {
+      ilGenerator.Emit(OpCodes.Ldarg_0);
+      ilGenerator.Emit(OpCodes.Ldfld, srcField);
+    }
+  }
+
+  internal class WrapperDictionary
+  {
+    private readonly Dictionary<string, Type> _wrapperTypes = new Dictionary<string, Type>();
+
+    private static string GenerateKey(Type interfaceType, Type realObjectType)
+    {
+      return interfaceType.Name + "_" + realObjectType.Name;
+    }
+
+    public Type GetType(Type interfaceType, Type realObjectType)
+    {
+      string key = GenerateKey(interfaceType, realObjectType);
+
+      if (_wrapperTypes.ContainsKey(key))
+        return _wrapperTypes[key];
+
+      return null;
+    }
+
+    public void SetType(Type interfaceType, Type realObjectType, Type wrapperType)
+    {
+      string key = GenerateKey(interfaceType, realObjectType);
+
+      if (_wrapperTypes.ContainsKey(key))
+        _wrapperTypes[key] = wrapperType;
+      else
+        _wrapperTypes.Add(key, wrapperType);
+    }
+  }
+
+  internal static class TypeExtensions
+  {
+    public static MethodInfo GetGenericMethod(this Type type, string name, params Type[] parameterTypes)
+    {
+      var methods = type.GetMethods().Where(method => method.Name == name);
+
+      foreach (var method in methods)
+      {
+        if (method.HasParameters(parameterTypes))
+          return method;
+      }
+
+      return null;
+    }
+
+    public static bool HasParameters(this MethodInfo method, params Type[] parameterTypes)
+    {
+      var methodParameters = method.GetParameters().Select(parameter => parameter.ParameterType).ToArray();
+
+      if (methodParameters.Length != parameterTypes.Length)
+        return false;
+
+      for (int i = 0; i < methodParameters.Length; i++)
+        if (methodParameters[i].ToString() != parameterTypes[i].ToString())
+          return false;
+
+      return true;
+    }
+
+    public static IEnumerable<Type> AllInterfaces(this Type target)
+    {
+      foreach (var IF in target.GetInterfaces())
+      {
+        yield return IF;
+        foreach (var childIF in IF.AllInterfaces())
+        {
+          yield return childIF;
+        }
+      }
+    }
+
+    public static IEnumerable<MethodInfo> AllMethods(this Type target)
+    {
+      var allTypes = target.AllInterfaces().ToList();
+      allTypes.Add(target);
+
+      return from type in allTypes
+             from method in type.GetMethods()
+             select method;
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/EnumUtils.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/EnumUtils.cs
new file mode 100644 (file)
index 0000000..8c2beb4
--- /dev/null
@@ -0,0 +1,236 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Reflection;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal static class EnumUtils
+  {
+    /// <summary>
+    /// Parses the specified enum member name, returning it's value.
+    /// </summary>
+    /// <param name="enumMemberName">Name of the enum member.</param>
+    /// <returns></returns>
+    public static T Parse<T>(string enumMemberName) where T : struct
+    {
+      return Parse<T>(enumMemberName, false);
+    }
+
+    /// <summary>
+    /// Parses the specified enum member name, returning it's value.
+    /// </summary>
+    /// <param name="enumMemberName">Name of the enum member.</param>
+    /// <param name="ignoreCase">If set to <c>true</c> ignore case.</param>
+    /// <returns></returns>
+    public static T Parse<T>(string enumMemberName, bool ignoreCase) where T : struct
+    {
+      ValidationUtils.ArgumentTypeIsEnum(typeof(T), "T");
+
+      return (T)Enum.Parse(typeof(T), enumMemberName, ignoreCase);
+    }
+
+    public static bool TryParse<T>(string enumMemberName, bool ignoreCase, out T value) where T : struct
+    {
+      ValidationUtils.ArgumentTypeIsEnum(typeof(T), "T");
+
+      return MiscellaneousUtils.TryAction(() => Parse<T>(enumMemberName, ignoreCase), out value);
+    }
+
+    public static IList<T> GetFlagsValues<T>(T value) where T : struct
+    {
+      Type enumType = typeof(T);
+
+      if (!enumType.IsDefined(typeof(FlagsAttribute), false))
+        throw new Exception("Enum type {0} is not a set of flags.".FormatWith(CultureInfo.InvariantCulture, enumType));
+
+      Type underlyingType = Enum.GetUnderlyingType(value.GetType());
+
+      ulong num = Convert.ToUInt64(value, CultureInfo.InvariantCulture);
+      EnumValues<ulong> enumNameValues = GetNamesAndValues<T>();
+      IList<T> selectedFlagsValues = new List<T>();
+
+      foreach (EnumValue<ulong> enumNameValue in enumNameValues)
+      {
+        if ((num & enumNameValue.Value) == enumNameValue.Value && enumNameValue.Value != 0)
+          selectedFlagsValues.Add((T)Convert.ChangeType(enumNameValue.Value, underlyingType, CultureInfo.CurrentCulture));
+      }
+
+      if (selectedFlagsValues.Count == 0 && enumNameValues.SingleOrDefault(v => v.Value == 0) != null)
+        selectedFlagsValues.Add(default(T));
+
+      return selectedFlagsValues;
+    }
+
+    /// <summary>
+    /// Gets a dictionary of the names and values of an Enum type.
+    /// </summary>
+    /// <returns></returns>
+    public static EnumValues<ulong> GetNamesAndValues<T>() where T : struct
+    {
+      return GetNamesAndValues<ulong>(typeof(T));
+    }
+
+    /// <summary>
+    /// Gets a dictionary of the names and values of an Enum type.
+    /// </summary>
+    /// <returns></returns>
+    public static EnumValues<TUnderlyingType> GetNamesAndValues<TEnum, TUnderlyingType>()
+      where TEnum : struct
+      where TUnderlyingType : struct
+    {
+      return GetNamesAndValues<TUnderlyingType>(typeof(TEnum));
+    }
+
+    /// <summary>
+    /// Gets a dictionary of the names and values of an Enum type.
+    /// </summary>
+    /// <param name="enumType">The enum type to get names and values for.</param>
+    /// <returns></returns>
+    public static EnumValues<TUnderlyingType> GetNamesAndValues<TUnderlyingType>(Type enumType) where TUnderlyingType : struct
+    {
+      if (enumType == null)
+        throw new ArgumentNullException("enumType");
+
+      ValidationUtils.ArgumentTypeIsEnum(enumType, "enumType");
+
+      IList<object> enumValues = GetValues(enumType);
+      IList<string> enumNames = GetNames(enumType);
+
+      EnumValues<TUnderlyingType> nameValues = new EnumValues<TUnderlyingType>();
+
+      for (int i = 0; i < enumValues.Count; i++)
+      {
+        try
+        {
+          nameValues.Add(new EnumValue<TUnderlyingType>(enumNames[i], (TUnderlyingType)Convert.ChangeType(enumValues[i], typeof(TUnderlyingType), CultureInfo.CurrentCulture)));
+        }
+        catch (OverflowException e)
+        {
+          throw new Exception(
+            string.Format(CultureInfo.InvariantCulture, "Value from enum with the underlying type of {0} cannot be added to dictionary with a value type of {1}. Value was too large: {2}",
+              Enum.GetUnderlyingType(enumType), typeof(TUnderlyingType), Convert.ToUInt64(enumValues[i], CultureInfo.InvariantCulture)), e);
+        }
+      }
+
+      return nameValues;
+    }
+
+    public static IList<T> GetValues<T>()
+    {
+      return GetValues(typeof(T)).Cast<T>().ToList();
+    }
+
+    public static IList<object> GetValues(Type enumType)
+    {
+      if (!enumType.IsEnum)
+        throw new ArgumentException("Type '" + enumType.Name + "' is not an enum.");
+
+      List<object> values = new List<object>();
+
+      var fields = from field in enumType.GetFields()
+                   where field.IsLiteral
+                   select field;
+
+      foreach (FieldInfo field in fields)
+      {
+        object value = field.GetValue(enumType);
+        values.Add(value);
+      }
+
+      return values;
+    }
+
+    public static IList<string> GetNames<T>()
+    {
+      return GetNames(typeof(T));
+    }
+
+    public static IList<string> GetNames(Type enumType)
+    {
+      if (!enumType.IsEnum)
+        throw new ArgumentException("Type '" + enumType.Name + "' is not an enum.");
+
+      List<string> values = new List<string>();
+
+      var fields = from field in enumType.GetFields()
+                   where field.IsLiteral
+                   select field;
+
+      foreach (FieldInfo field in fields)
+      {
+        values.Add(field.Name);
+      }
+
+      return values;
+    }
+
+
+    /// <summary>
+    /// Gets the maximum valid value of an Enum type. Flags enums are ORed.
+    /// </summary>
+    /// <typeparam name="TEnumType">The type of the returned value. Must be assignable from the enum's underlying value type.</typeparam>
+    /// <param name="enumType">The enum type to get the maximum value for.</param>
+    /// <returns></returns>
+    public static TEnumType GetMaximumValue<TEnumType>(Type enumType) where TEnumType : IConvertible, IComparable<TEnumType>
+    {
+      if (enumType == null)
+        throw new ArgumentNullException("enumType");
+
+      Type enumUnderlyingType = Enum.GetUnderlyingType(enumType);
+
+      if (!typeof(TEnumType).IsAssignableFrom(enumUnderlyingType))
+        throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "TEnumType is not assignable from the enum's underlying type of {0}.", enumUnderlyingType.Name));
+
+      ulong maximumValue = 0;
+      IList<object> enumValues = GetValues(enumType);
+
+      if (enumType.IsDefined(typeof(FlagsAttribute), false))
+      {
+        foreach (TEnumType value in enumValues)
+        {
+          maximumValue = maximumValue | value.ToUInt64(CultureInfo.InvariantCulture);
+        }
+      }
+      else
+      {
+        foreach (TEnumType value in enumValues)
+        {
+          ulong tempValue = value.ToUInt64(CultureInfo.InvariantCulture);
+
+          // maximumValue is smaller than the enum value
+          if (maximumValue.CompareTo(tempValue) == -1)
+            maximumValue = tempValue;
+        }
+      }
+
+      return (TEnumType)Convert.ChangeType(maximumValue, typeof(TEnumType), CultureInfo.InvariantCulture);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/EnumValue.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/EnumValue.cs
new file mode 100644 (file)
index 0000000..7f93f92
--- /dev/null
@@ -0,0 +1,53 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal class EnumValue<T> where T : struct
+  {
+    private string _name;
+    private T _value;
+
+    public string Name
+    {
+      get { return _name; }
+    }
+    public T Value
+    {
+      get { return _value; }
+    }
+
+    public EnumValue(string name, T value)
+    {
+      _name = name;
+      _value = value;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/EnumValues.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/EnumValues.cs
new file mode 100644 (file)
index 0000000..6d70965
--- /dev/null
@@ -0,0 +1,41 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal class EnumValues<T> : KeyedCollection<string, EnumValue<T>> where T : struct
+  {
+    protected override string GetKeyForItem(EnumValue<T> item)
+    {
+      return item.Name;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/ILGeneratorExtensions.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/ILGeneratorExtensions.cs
new file mode 100644 (file)
index 0000000..8ffc8c8
--- /dev/null
@@ -0,0 +1,77 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+#if !PocketPC && !SILVERLIGHT
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection.Emit;
+using System.Text;
+using System.Reflection;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal static class ILGeneratorExtensions
+  {
+    public static void PushInstance(this ILGenerator generator, Type type)
+    {
+      generator.Emit(OpCodes.Ldarg_0);
+      if (type.IsValueType)
+        generator.Emit(OpCodes.Unbox, type);
+      else
+        generator.Emit(OpCodes.Castclass, type);
+    }
+
+    public static void BoxIfNeeded(this ILGenerator generator, Type type)
+    {
+      if (type.IsValueType)
+        generator.Emit(OpCodes.Box, type);
+      else
+        generator.Emit(OpCodes.Castclass, type);
+    }
+
+    public static void UnboxIfNeeded(this ILGenerator generator, Type type)
+    {
+      if (type.IsValueType)
+        generator.Emit(OpCodes.Unbox_Any, type);
+      else
+        generator.Emit(OpCodes.Castclass, type);
+    }
+
+    public static void CallMethod(this ILGenerator generator, MethodInfo methodInfo)
+    {
+      if (methodInfo.IsFinal || !methodInfo.IsVirtual)
+        generator.Emit(OpCodes.Call, methodInfo);
+      else
+        generator.Emit(OpCodes.Callvirt, methodInfo);
+    }
+
+    public static void Return(this ILGenerator generator)
+    {
+      generator.Emit(OpCodes.Ret);
+    }
+  }
+}
+#endif
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/JavaScriptUtils.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/JavaScriptUtils.cs
new file mode 100644 (file)
index 0000000..df1007c
--- /dev/null
@@ -0,0 +1,148 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections;
+using System.Globalization;
+using System.IO;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Collections.Generic;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal static class JavaScriptUtils
+  {
+    public static void WriteEscapedJavaScriptString(TextWriter writer, string value, char delimiter, bool appendDelimiters)
+    {
+      // leading delimiter
+      if (appendDelimiters)
+        writer.Write(delimiter);
+
+      if (value != null)
+      {
+        int lastWritePosition = 0;
+        int skipped = 0;
+        char[] chars = null;
+
+        for (int i = 0; i < value.Length; i++)
+        {
+          char c = value[i];
+          string escapedValue;
+
+          switch (c)
+          {
+            case '\t':
+              escapedValue = @"\t";
+              break;
+            case '\n':
+              escapedValue = @"\n";
+              break;
+            case '\r':
+              escapedValue = @"\r";
+              break;
+            case '\f':
+              escapedValue = @"\f";
+              break;
+            case '\b':
+              escapedValue = @"\b";
+              break;
+            case '\\':
+              escapedValue = @"\\";
+              break;
+            case '\u0085': // Next Line
+              escapedValue = @"\u0085";
+              break;
+            case '\u2028': // Line Separator
+              escapedValue = @"\u2028";
+              break;
+            case '\u2029': // Paragraph Separator
+              escapedValue = @"\u2029";
+              break;
+            case '\'':
+              // only escape if this charater is being used as the delimiter
+              escapedValue = (delimiter == '\'') ? @"\'" : null;
+              break;
+            case '"':
+              // only escape if this charater is being used as the delimiter
+              escapedValue = (delimiter == '"') ? "\\\"" : null;
+              break;
+            default:
+              escapedValue = (c <= '\u001f') ? StringUtils.ToCharAsUnicode(c) : null;
+              break;
+          }
+
+          if (escapedValue != null)
+          {
+            if (chars == null)
+              chars = value.ToCharArray();
+
+            // write skipped text
+            if (skipped > 0)
+            {
+              writer.Write(chars, lastWritePosition, skipped);
+              skipped = 0;
+            }
+
+            // write escaped value and note position
+            writer.Write(escapedValue);
+            lastWritePosition = i + 1;
+          }
+          else
+          {
+            skipped++;
+          }
+        }
+
+        // write any remaining skipped text
+        if (skipped > 0)
+        {
+          if (lastWritePosition == 0)
+            writer.Write(value);
+          else
+            writer.Write(chars, lastWritePosition, skipped);
+        }
+      }
+
+      // trailing delimiter
+      if (appendDelimiters)
+        writer.Write(delimiter);
+    }
+
+    public static string ToEscapedJavaScriptString(string value)
+    {
+      return ToEscapedJavaScriptString(value, '"', true);
+    }
+
+    public static string ToEscapedJavaScriptString(string value, char delimiter, bool appendDelimiters)
+    {
+      using (StringWriter w = StringUtils.CreateStringWriter(StringUtils.GetLength(value) ?? 16))
+      {
+        WriteEscapedJavaScriptString(w, value, delimiter, appendDelimiters);
+        return w.ToString();
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/LateBoundReflectionDelegateFactory.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/LateBoundReflectionDelegateFactory.cs
new file mode 100644 (file)
index 0000000..cebafab
--- /dev/null
@@ -0,0 +1,87 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Globalization;
+using System.Reflection;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal class LateBoundReflectionDelegateFactory : ReflectionDelegateFactory
+  {
+    public static readonly LateBoundReflectionDelegateFactory Instance = new LateBoundReflectionDelegateFactory();
+
+    public override MethodCall<T, object> CreateMethodCall<T>(MethodBase method)
+    {
+      ValidationUtils.ArgumentNotNull(method, "method");
+
+      ConstructorInfo c = method as ConstructorInfo;
+      if (c != null)
+        return (o, a) => c.Invoke(a);
+
+      return (o, a) => method.Invoke(o, a);
+    }
+
+    public override Func<T> CreateDefaultConstructor<T>(Type type)
+    {
+      ValidationUtils.ArgumentNotNull(type, "type");
+
+      if (type.IsValueType)
+        return () => (T)ReflectionUtils.CreateInstance(type);
+
+      ConstructorInfo constructorInfo = ReflectionUtils.GetDefaultConstructor(type, true);
+
+      return () => (T)constructorInfo.Invoke(null);
+    }
+
+    public override Func<T, object> CreateGet<T>(PropertyInfo propertyInfo)
+    {
+      ValidationUtils.ArgumentNotNull(propertyInfo, "propertyInfo");
+
+      return o => propertyInfo.GetValue(o, null);
+    }
+
+    public override Func<T, object> CreateGet<T>(FieldInfo fieldInfo)
+    {
+      ValidationUtils.ArgumentNotNull(fieldInfo, "fieldInfo");
+
+      return o => fieldInfo.GetValue(o);
+    }
+
+    public override Action<T, object> CreateSet<T>(FieldInfo fieldInfo)
+    {
+      ValidationUtils.ArgumentNotNull(fieldInfo, "fieldInfo");
+
+      return (o, v) => fieldInfo.SetValue(o, v);
+    }
+
+    public override Action<T, object> CreateSet<T>(PropertyInfo propertyInfo)
+    {
+      ValidationUtils.ArgumentNotNull(propertyInfo, "propertyInfo");
+
+      return (o, v) => propertyInfo.SetValue(o, v, null);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/ListWrapper.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/ListWrapper.cs
new file mode 100644 (file)
index 0000000..150a00c
--- /dev/null
@@ -0,0 +1,194 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Threading;
+using Newtonsoft.Json.Utilities;
+using System.Linq;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal interface IWrappedList : IList
+  {
+    object UnderlyingList { get; }
+  }
+
+  internal class ListWrapper<T> : CollectionWrapper<T>, IList<T>, IWrappedList
+  {
+    private readonly IList<T> _genericList;
+
+    public ListWrapper(IList list)
+      : base(list)
+    {
+      ValidationUtils.ArgumentNotNull(list, "list");
+
+      if (list is IList<T>)
+        _genericList = (IList<T>) list;
+    }
+
+    public ListWrapper(IList<T> list)
+      : base(list)
+    {
+      ValidationUtils.ArgumentNotNull(list, "list");
+
+      _genericList = list;
+    }
+
+    public int IndexOf(T item)
+    {
+      if (_genericList != null)
+        return _genericList.IndexOf(item);
+      else
+        return ((IList)this).IndexOf(item);
+    }
+
+    public void Insert(int index, T item)
+    {
+      if (_genericList != null)
+        _genericList.Insert(index, item);
+      else
+        ((IList)this).Insert(index, item);
+    }
+
+    public void RemoveAt(int index)
+    {
+      if (_genericList != null)
+        _genericList.RemoveAt(index);
+      else
+        ((IList)this).RemoveAt(index);
+    }
+
+    public T this[int index]
+    {
+      get
+      {
+        if (_genericList != null)
+          return _genericList[index];
+        else
+          return (T)((IList)this)[index];
+      }
+      set
+      {
+        if (_genericList != null)
+          _genericList[index] = value;
+        else
+          ((IList)this)[index] = value;
+      }
+    }
+
+    public override void Add(T item)
+    {
+      if (_genericList != null)
+        _genericList.Add(item);
+      else
+        base.Add(item);
+    }
+
+    public override void Clear()
+    {
+      if (_genericList != null)
+        _genericList.Clear();
+      else
+        base.Clear();
+    }
+
+    public override bool Contains(T item)
+    {
+      if (_genericList != null)
+        return _genericList.Contains(item);
+      else
+        return base.Contains(item);
+    }
+
+    public override void CopyTo(T[] array, int arrayIndex)
+    {
+      if (_genericList != null)
+        _genericList.CopyTo(array, arrayIndex);
+      else
+        base.CopyTo(array, arrayIndex);
+    }
+
+    public override int Count
+    {
+      get
+      {
+        if (_genericList != null)
+          return _genericList.Count;
+        else
+          return base.Count;
+      }
+    }
+
+    public override bool IsReadOnly
+    {
+      get
+      {
+        if (_genericList != null)
+          return _genericList.IsReadOnly;
+        else
+          return base.IsReadOnly;
+      }
+    }
+
+    public override bool Remove(T item)
+    {
+      if (_genericList != null)
+      {
+        return _genericList.Remove(item);
+      }
+      else
+      {
+        bool contains = base.Contains(item);
+
+        if (contains)
+          base.Remove(item);
+
+        return contains;
+      }
+    }
+
+    public override IEnumerator<T> GetEnumerator()
+    {
+      if (_genericList != null)
+        return _genericList.GetEnumerator();
+
+      return base.GetEnumerator();
+    }
+
+    public object UnderlyingList
+    {
+      get
+      {
+        if (_genericList != null)
+          return _genericList;
+        else
+          return UnderlyingCollection;
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/MathUtils.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/MathUtils.cs
new file mode 100644 (file)
index 0000000..d367874
--- /dev/null
@@ -0,0 +1,134 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal class MathUtils
+  {
+    public static int IntLength(int i)
+    {
+      if (i < 0)
+        throw new ArgumentOutOfRangeException();
+
+      if (i == 0)
+        return 1;
+
+      return (int)Math.Floor(Math.Log10(i)) + 1;
+    }
+
+    public static int HexToInt(char h)
+    {
+      if ((h >= '0') && (h <= '9'))
+      {
+        return (h - '0');
+      }
+      if ((h >= 'a') && (h <= 'f'))
+      {
+        return ((h - 'a') + 10);
+      }
+      if ((h >= 'A') && (h <= 'F'))
+      {
+        return ((h - 'A') + 10);
+      }
+      return -1;
+    }
+
+    public static char IntToHex(int n)
+    {
+      if (n <= 9)
+      {
+        return (char)(n + 48);
+      }
+      return (char)((n - 10) + 97);
+    }
+
+    public static int GetDecimalPlaces(double value)
+    {
+      // increasing max decimal places above 10 produces weirdness
+      int maxDecimalPlaces = 10;
+      double threshold = Math.Pow(0.1d, maxDecimalPlaces);
+
+      if (value == 0.0)
+        return 0;
+      int decimalPlaces = 0;
+      while (value - Math.Floor(value) > threshold && decimalPlaces < maxDecimalPlaces)
+      {
+        value *= 10.0;
+        decimalPlaces++;
+      }
+      return decimalPlaces;
+    }
+
+    public static int? Min(int? val1, int? val2)
+    {
+      if (val1 == null)
+        return val2;
+      if (val2 == null)
+        return val1;
+
+      return Math.Min(val1.Value, val2.Value);
+    }
+
+    public static int? Max(int? val1, int? val2)
+    {
+      if (val1 == null)
+        return val2;
+      if (val2 == null)
+        return val1;
+
+      return Math.Max(val1.Value, val2.Value);
+    }
+
+    public static double? Min(double? val1, double? val2)
+    {
+      if (val1 == null)
+        return val2;
+      if (val2 == null)
+        return val1;
+
+      return Math.Min(val1.Value, val2.Value);
+    }
+
+    public static double? Max(double? val1, double? val2)
+    {
+      if (val1 == null)
+        return val2;
+      if (val2 == null)
+        return val1;
+
+      return Math.Max(val1.Value, val2.Value);
+    }
+
+    public static bool ApproxEquals(double d1, double d2)
+    {
+      // are values equal to within 6 (or so) digits of precision?
+      return Math.Abs(d1 - d2) < (Math.Abs(d1) * 1e-6);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/MethodCall.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/MethodCall.cs
new file mode 100644 (file)
index 0000000..6305dca
--- /dev/null
@@ -0,0 +1,29 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal delegate TResult MethodCall<T, TResult>(T target, params object[] args);
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/MiscellaneousUtils.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/MiscellaneousUtils.cs
new file mode 100644 (file)
index 0000000..733aed1
--- /dev/null
@@ -0,0 +1,162 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Reflection;
+using System.Text;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal delegate T Creator<T>();
+
+  internal static class MiscellaneousUtils
+  {
+    public static bool ValueEquals(object objA, object objB)
+    {
+      if (objA == null && objB == null)
+        return true;
+      if (objA != null && objB == null)
+        return false;
+      if (objA == null && objB != null)
+        return false;
+
+      // comparing an Int32 and Int64 both of the same value returns false
+      // make types the same then compare
+      if (objA.GetType() != objB.GetType())
+      {
+        if (ConvertUtils.IsInteger(objA) && ConvertUtils.IsInteger(objB))
+          return Convert.ToDecimal(objA, CultureInfo.CurrentCulture).Equals(Convert.ToDecimal(objB, CultureInfo.CurrentCulture));
+        else if ((objA is double || objA is float || objA is decimal) && (objB is double || objB is float || objB is decimal))
+          return MathUtils.ApproxEquals(Convert.ToDouble(objA, CultureInfo.CurrentCulture), Convert.ToDouble(objB, CultureInfo.CurrentCulture));
+        else
+          return false;
+      }
+
+      return objA.Equals(objB);
+    }
+
+    public static ArgumentOutOfRangeException CreateArgumentOutOfRangeException(string paramName, object actualValue, string message)
+    {
+      string newMessage = message + Environment.NewLine + @"Actual value was {0}.".FormatWith(CultureInfo.InvariantCulture, actualValue);
+
+      return new ArgumentOutOfRangeException(paramName, newMessage);
+    }
+
+    public static bool TryAction<T>(Creator<T> creator, out T output)
+    {
+      ValidationUtils.ArgumentNotNull(creator, "creator");
+
+      try
+      {
+        output = creator();
+        return true;
+      }
+      catch
+      {
+        output = default(T);
+        return false;
+      }
+    }
+
+    public static string ToString(object value)
+    {
+      if (value == null)
+        return "{null}";
+
+      return (value is string) ? @"""" + value.ToString() + @"""" : value.ToString();
+    }
+
+    public static byte[] HexToBytes(string hex)
+    {
+      string fixedHex = hex.Replace("-", string.Empty);
+
+      // array to put the result in
+      byte[] bytes = new byte[fixedHex.Length / 2];
+      // variable to determine shift of high/low nibble
+      int shift = 4;
+      // offset of the current byte in the array
+      int offset = 0;
+      // loop the characters in the string
+      foreach (char c in fixedHex)
+      {
+        // get character code in range 0-9, 17-22
+        // the % 32 handles lower case characters
+        int b = (c - '0') % 32;
+        // correction for a-f
+        if (b > 9) b -= 7;
+        // store nibble (4 bits) in byte array
+        bytes[offset] |= (byte)(b << shift);
+        // toggle the shift variable between 0 and 4
+        shift ^= 4;
+        // move to next byte
+        if (shift != 0) offset++;
+      }
+      return bytes;
+    }
+
+    public static string BytesToHex(byte[] bytes)
+    {
+      return BytesToHex(bytes, false);
+    }
+
+    public static string BytesToHex(byte[] bytes, bool removeDashes)
+    {
+      string hex = BitConverter.ToString(bytes);
+      if (removeDashes)
+        hex = hex.Replace("-", "");
+
+      return hex;
+    }
+
+    public static int ByteArrayCompare(byte[] a1, byte[] a2)
+    {
+      int lengthCompare = a1.Length.CompareTo(a2.Length);
+      if (lengthCompare != 0)
+        return lengthCompare;
+
+      for (int i = 0; i < a1.Length; i++)
+      {
+        int valueCompare = a1[i].CompareTo(a2[i]);
+        if (valueCompare != 0)
+          return valueCompare;
+      }
+
+      return 0;
+    }
+
+    public static string GetPrefix(string qualifiedName)
+    {
+      string prefix;
+      string localName;
+      GetQualifiedNameParts(qualifiedName, out prefix, out localName);
+
+      return prefix;
+    }
+
+    public static string GetLocalName(string qualifiedName)
+    {
+      string prefix;
+      string localName;
+      GetQualifiedNameParts(qualifiedName, out prefix, out localName);
+
+      return localName;
+    }
+
+    public static void GetQualifiedNameParts(string qualifiedName, out string prefix, out string localName)
+    {
+      int colonPosition = qualifiedName.IndexOf(':');
+
+      if ((colonPosition == -1 || colonPosition == 0) || (qualifiedName.Length - 1) == colonPosition)
+      {
+        prefix = null;
+        localName = qualifiedName;
+      }
+      else
+      {
+        prefix = qualifiedName.Substring(0, colonPosition);
+        localName = qualifiedName.Substring(colonPosition + 1);
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/ReflectionDelegateFactory.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/ReflectionDelegateFactory.cs
new file mode 100644 (file)
index 0000000..ec7e9a9
--- /dev/null
@@ -0,0 +1,67 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Globalization;
+using System.Reflection;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal abstract class ReflectionDelegateFactory
+  {
+    public Func<T, object> CreateGet<T>(MemberInfo memberInfo)
+    {
+      PropertyInfo propertyInfo = memberInfo as PropertyInfo;
+      if (propertyInfo != null)
+        return CreateGet<T>(propertyInfo);
+
+      FieldInfo fieldInfo = memberInfo as FieldInfo;
+      if (fieldInfo != null)
+        return CreateGet<T>(fieldInfo);
+
+      throw new Exception("Could not create getter for {0}.".FormatWith(CultureInfo.InvariantCulture, memberInfo));
+    }
+
+    public Action<T, object> CreateSet<T>(MemberInfo memberInfo)
+    {
+      PropertyInfo propertyInfo = memberInfo as PropertyInfo;
+      if (propertyInfo != null)
+        return CreateSet<T>(propertyInfo);
+
+      FieldInfo fieldInfo = memberInfo as FieldInfo;
+      if (fieldInfo != null)
+        return CreateSet<T>(fieldInfo);
+
+      throw new Exception("Could not create setter for {0}.".FormatWith(CultureInfo.InvariantCulture, memberInfo));
+    }
+
+    public abstract MethodCall<T, object> CreateMethodCall<T>(MethodBase method);
+    public abstract Func<T> CreateDefaultConstructor<T>(Type type);
+    public abstract Func<T, object> CreateGet<T>(PropertyInfo propertyInfo);
+    public abstract Func<T, object> CreateGet<T>(FieldInfo fieldInfo);
+    public abstract Action<T, object> CreateSet<T>(FieldInfo fieldInfo);
+    public abstract Action<T, object> CreateSet<T>(PropertyInfo propertyInfo);
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs
new file mode 100644 (file)
index 0000000..b0350bc
--- /dev/null
@@ -0,0 +1,950 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Collections;
+using System.Linq;
+using System.Globalization;
+using System.Runtime.Serialization.Formatters;
+using System.Text;
+using System.Text.RegularExpressions;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal static class ReflectionUtils
+  {
+    public static Type GetObjectType(object v)
+    {
+      return (v != null) ? v.GetType() : null;
+    }
+
+    public static string GetTypeName(Type t, FormatterAssemblyStyle assemblyFormat)
+    {
+      switch (assemblyFormat)
+      {
+        case FormatterAssemblyStyle.Simple:
+          return GetSimpleTypeName(t);
+        case FormatterAssemblyStyle.Full:
+          return t.AssemblyQualifiedName;
+        default:
+          throw new ArgumentOutOfRangeException();
+      }
+    }
+
+    private static string GetSimpleTypeName(Type type)
+    {
+#if !SILVERLIGHT
+      string fullyQualifiedTypeName = type.FullName + ", " + type.Assembly.GetName().Name;
+
+      // for type names with no nested type names then return
+      if (!type.IsGenericType || type.IsGenericTypeDefinition)
+        return fullyQualifiedTypeName;
+#else
+      // Assembly.GetName() is marked SecurityCritical
+      string fullyQualifiedTypeName = type.AssemblyQualifiedName;
+#endif
+
+      StringBuilder builder = new StringBuilder();
+
+      // loop through the type name and filter out qualified assembly details from nested type names
+      bool writingAssemblyName = false;
+      bool skippingAssemblyDetails = false;
+      for (int i = 0; i < fullyQualifiedTypeName.Length; i++)
+      {
+        char current = fullyQualifiedTypeName[i];
+        switch (current)
+        {
+          case '[':
+            writingAssemblyName = false;
+            skippingAssemblyDetails = false;
+            builder.Append(current);
+            break;
+          case ']':
+            writingAssemblyName = false;
+            skippingAssemblyDetails = false;
+            builder.Append(current);
+            break;
+          case ',':
+            if (!writingAssemblyName)
+            {
+              writingAssemblyName = true;
+              builder.Append(current);
+            }
+            else
+            {
+              skippingAssemblyDetails = true;
+            }
+            break;
+          default:
+            if (!skippingAssemblyDetails)
+              builder.Append(current);
+            break;
+        }
+      }
+
+      return builder.ToString();
+    }
+
+    public static bool IsInstantiatableType(Type t)
+    {
+      ValidationUtils.ArgumentNotNull(t, "t");
+
+      if (t.IsAbstract || t.IsInterface || t.IsArray || t.IsGenericTypeDefinition || t == typeof(void))
+        return false;
+
+      if (!HasDefaultConstructor(t))
+        return false;
+
+      return true;
+    }
+
+    public static bool HasDefaultConstructor(Type t)
+    {
+      return HasDefaultConstructor(t, false);
+    }
+
+    public static bool HasDefaultConstructor(Type t, bool nonPublic)
+    {
+      ValidationUtils.ArgumentNotNull(t, "t");
+
+      if (t.IsValueType)
+        return true;
+
+      return (GetDefaultConstructor(t, nonPublic) != null);
+    }
+
+    public static ConstructorInfo GetDefaultConstructor(Type t)
+    {
+      return GetDefaultConstructor(t, false);
+    }
+
+    public static ConstructorInfo GetDefaultConstructor(Type t, bool nonPublic)
+    {
+      BindingFlags accessModifier = BindingFlags.Public;
+      
+      if (nonPublic)
+        accessModifier = accessModifier | BindingFlags.NonPublic;
+
+      return t.GetConstructor(accessModifier | BindingFlags.Instance, null, new Type[0], null);
+    }
+
+    public static bool IsNullable(Type t)
+    {
+      ValidationUtils.ArgumentNotNull(t, "t");
+
+      if (t.IsValueType)
+        return IsNullableType(t);
+
+      return true;
+    }
+
+    public static bool IsNullableType(Type t)
+    {
+      ValidationUtils.ArgumentNotNull(t, "t");
+
+      return (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>));
+    }
+
+    public static Type EnsureNotNullableType(Type t)
+    {
+      return (IsNullableType(t))
+        ? Nullable.GetUnderlyingType(t)
+        : t;
+    }
+
+    //public static bool IsValueTypeUnitializedValue(ValueType value)
+    //{
+    //  if (value == null)
+    //    return true;
+
+    //  return value.Equals(CreateUnitializedValue(value.GetType()));
+    //}
+
+    public static bool IsUnitializedValue(object value)
+    {
+      if (value == null)
+      {
+        return true;
+      }
+      else
+      {
+        object unitializedValue = CreateUnitializedValue(value.GetType());
+        return value.Equals(unitializedValue);
+      }
+    }
+
+    public static object CreateUnitializedValue(Type type)
+    {
+      ValidationUtils.ArgumentNotNull(type, "type");
+
+      if (type.IsGenericTypeDefinition)
+        throw new ArgumentException("Type {0} is a generic type definition and cannot be instantiated.".FormatWith(CultureInfo.InvariantCulture, type), "type");
+
+      if (type.IsClass || type.IsInterface || type == typeof(void))
+        return null;
+      else if (type.IsValueType)
+        return Activator.CreateInstance(type);
+      else
+        throw new ArgumentException("Type {0} cannot be instantiated.".FormatWith(CultureInfo.InvariantCulture, type), "type");
+    }
+
+    public static bool IsPropertyIndexed(PropertyInfo property)
+    {
+      ValidationUtils.ArgumentNotNull(property, "property");
+
+      return !CollectionUtils.IsNullOrEmpty<ParameterInfo>(property.GetIndexParameters());
+    }
+
+    public static bool ImplementsGenericDefinition(Type type, Type genericInterfaceDefinition)
+    {
+      Type implementingType;
+      return ImplementsGenericDefinition(type, genericInterfaceDefinition, out implementingType);
+    }
+
+    public static bool ImplementsGenericDefinition(Type type, Type genericInterfaceDefinition, out Type implementingType)
+    {
+      ValidationUtils.ArgumentNotNull(type, "type");
+      ValidationUtils.ArgumentNotNull(genericInterfaceDefinition, "genericInterfaceDefinition");
+
+      if (!genericInterfaceDefinition.IsInterface || !genericInterfaceDefinition.IsGenericTypeDefinition)
+        throw new ArgumentNullException("'{0}' is not a generic interface definition.".FormatWith(CultureInfo.InvariantCulture, genericInterfaceDefinition));
+
+      if (type.IsInterface)
+      {
+        if (type.IsGenericType)
+        {
+          Type interfaceDefinition = type.GetGenericTypeDefinition();
+
+          if (genericInterfaceDefinition == interfaceDefinition)
+          {
+            implementingType = type;
+            return true;
+          }
+        }
+      }
+
+      foreach (Type i in type.GetInterfaces())
+      {
+        if (i.IsGenericType)
+        {
+          Type interfaceDefinition = i.GetGenericTypeDefinition();
+
+          if (genericInterfaceDefinition == interfaceDefinition)
+          {
+            implementingType = i;
+            return true;
+          }
+        }
+      }
+
+      implementingType = null;
+      return false;
+    }
+
+    public static bool AssignableToTypeName(this Type type, string fullTypeName, out Type match)
+    {
+      Type current = type;
+
+      while (current != null)
+      {
+        if (string.Equals(current.FullName, fullTypeName, StringComparison.Ordinal))
+        {
+          match = current;
+          return true;
+        }
+
+        current = current.BaseType;
+      }
+
+      foreach (Type i in type.GetInterfaces())
+      {
+        if (string.Equals(i.Name, fullTypeName, StringComparison.Ordinal))
+        {
+          match = type;
+          return true;
+        }
+      }
+
+      match = null;
+      return false;
+    }
+
+    public static bool AssignableToTypeName(this Type type, string fullTypeName)
+    {
+      Type match;
+      return type.AssignableToTypeName(fullTypeName, out match);
+    }
+
+    public static bool InheritsGenericDefinition(Type type, Type genericClassDefinition)
+    {
+      Type implementingType;
+      return InheritsGenericDefinition(type, genericClassDefinition, out implementingType);
+    }
+
+    public static bool InheritsGenericDefinition(Type type, Type genericClassDefinition, out Type implementingType)
+    {
+      ValidationUtils.ArgumentNotNull(type, "type");
+      ValidationUtils.ArgumentNotNull(genericClassDefinition, "genericClassDefinition");
+
+      if (!genericClassDefinition.IsClass || !genericClassDefinition.IsGenericTypeDefinition)
+        throw new ArgumentNullException("'{0}' is not a generic class definition.".FormatWith(CultureInfo.InvariantCulture, genericClassDefinition));
+
+      return InheritsGenericDefinitionInternal(type, genericClassDefinition, out implementingType);
+    }
+
+    private static bool InheritsGenericDefinitionInternal(Type currentType, Type genericClassDefinition, out Type implementingType)
+    {
+      if (currentType.IsGenericType)
+      {
+        Type currentGenericClassDefinition = currentType.GetGenericTypeDefinition();
+
+        if (genericClassDefinition == currentGenericClassDefinition)
+        {
+          implementingType = currentType;
+          return true;
+        }
+      }
+
+      if (currentType.BaseType == null)
+      {
+        implementingType = null;
+        return false;
+      }
+
+      return InheritsGenericDefinitionInternal(currentType.BaseType, genericClassDefinition, out implementingType);
+    }
+
+    /// <summary>
+    /// Gets the type of the typed collection's items.
+    /// </summary>
+    /// <param name="type">The type.</param>
+    /// <returns>The type of the typed collection's items.</returns>
+    public static Type GetCollectionItemType(Type type)
+    {
+      ValidationUtils.ArgumentNotNull(type, "type");
+      Type genericListType;
+
+      if (type.IsArray)
+      {
+        return type.GetElementType();
+      }
+      else if (ImplementsGenericDefinition(type, typeof(IEnumerable<>), out genericListType))
+      {
+        if (genericListType.IsGenericTypeDefinition)
+          throw new Exception("Type {0} is not a collection.".FormatWith(CultureInfo.InvariantCulture, type));
+
+        return genericListType.GetGenericArguments()[0];
+      }
+      else if (typeof(IEnumerable).IsAssignableFrom(type))
+      {
+        return null;
+      }
+      else
+      {
+        throw new Exception("Type {0} is not a collection.".FormatWith(CultureInfo.InvariantCulture, type));
+      }
+    }
+
+    public static void GetDictionaryKeyValueTypes(Type dictionaryType, out Type keyType, out Type valueType)
+    {
+      ValidationUtils.ArgumentNotNull(dictionaryType, "type");
+
+      Type genericDictionaryType;
+      if (ImplementsGenericDefinition(dictionaryType, typeof(IDictionary<,>), out genericDictionaryType))
+      {
+        if (genericDictionaryType.IsGenericTypeDefinition)
+          throw new Exception("Type {0} is not a dictionary.".FormatWith(CultureInfo.InvariantCulture, dictionaryType));
+
+        Type[] dictionaryGenericArguments = genericDictionaryType.GetGenericArguments();
+
+        keyType = dictionaryGenericArguments[0];
+        valueType = dictionaryGenericArguments[1];
+        return;
+      }
+      else if (typeof(IDictionary).IsAssignableFrom(dictionaryType))
+      {
+        keyType = null;
+        valueType = null;
+        return;
+      }
+      else
+      {
+        throw new Exception("Type {0} is not a dictionary.".FormatWith(CultureInfo.InvariantCulture, dictionaryType));
+      }
+    }
+
+    public static Type GetDictionaryValueType(Type dictionaryType)
+    {
+      Type keyType;
+      Type valueType;
+      GetDictionaryKeyValueTypes(dictionaryType, out keyType, out valueType);
+
+      return valueType;
+    }
+
+    public static Type GetDictionaryKeyType(Type dictionaryType)
+    {
+      Type keyType;
+      Type valueType;
+      GetDictionaryKeyValueTypes(dictionaryType, out keyType, out valueType);
+
+      return keyType;
+    }
+
+    /// <summary>
+    /// Tests whether the list's items are their unitialized value.
+    /// </summary>
+    /// <param name="list">The list.</param>
+    /// <returns>Whether the list's items are their unitialized value</returns>
+    public static bool ItemsUnitializedValue<T>(IList<T> list)
+    {
+      ValidationUtils.ArgumentNotNull(list, "list");
+
+      Type elementType = GetCollectionItemType(list.GetType());
+
+      if (elementType.IsValueType)
+      {
+        object unitializedValue = CreateUnitializedValue(elementType);
+
+        for (int i = 0; i < list.Count; i++)
+        {
+          if (!list[i].Equals(unitializedValue))
+            return false;
+        }
+      }
+      else if (elementType.IsClass)
+      {
+        for (int i = 0; i < list.Count; i++)
+        {
+          object value = list[i];
+
+          if (value != null)
+            return false;
+        }
+      }
+      else
+      {
+        throw new Exception("Type {0} is neither a ValueType or a Class.".FormatWith(CultureInfo.InvariantCulture, elementType));
+      }
+
+      return true;
+    }
+
+    /// <summary>
+    /// Gets the member's underlying type.
+    /// </summary>
+    /// <param name="member">The member.</param>
+    /// <returns>The underlying type of the member.</returns>
+    public static Type GetMemberUnderlyingType(MemberInfo member)
+    {
+      ValidationUtils.ArgumentNotNull(member, "member");
+
+      switch (member.MemberType)
+      {
+        case MemberTypes.Field:
+          return ((FieldInfo)member).FieldType;
+        case MemberTypes.Property:
+          return ((PropertyInfo)member).PropertyType;
+        case MemberTypes.Event:
+          return ((EventInfo)member).EventHandlerType;
+        default:
+          throw new ArgumentException("MemberInfo must be of type FieldInfo, PropertyInfo or EventInfo", "member");
+      }
+    }
+
+    /// <summary>
+    /// Determines whether the member is an indexed property.
+    /// </summary>
+    /// <param name="member">The member.</param>
+    /// <returns>
+    ///        <c>true</c> if the member is an indexed property; otherwise, <c>false</c>.
+    /// </returns>
+    public static bool IsIndexedProperty(MemberInfo member)
+    {
+      ValidationUtils.ArgumentNotNull(member, "member");
+
+      PropertyInfo propertyInfo = member as PropertyInfo;
+
+      if (propertyInfo != null)
+        return IsIndexedProperty(propertyInfo);
+      else
+        return false;
+    }
+
+    /// <summary>
+    /// Determines whether the property is an indexed property.
+    /// </summary>
+    /// <param name="property">The property.</param>
+    /// <returns>
+    ///        <c>true</c> if the property is an indexed property; otherwise, <c>false</c>.
+    /// </returns>
+    public static bool IsIndexedProperty(PropertyInfo property)
+    {
+      ValidationUtils.ArgumentNotNull(property, "property");
+
+      return (property.GetIndexParameters().Length > 0);
+    }
+
+    /// <summary>
+    /// Gets the member's value on the object.
+    /// </summary>
+    /// <param name="member">The member.</param>
+    /// <param name="target">The target object.</param>
+    /// <returns>The member's value on the object.</returns>
+    public static object GetMemberValue(MemberInfo member, object target)
+    {
+      ValidationUtils.ArgumentNotNull(member, "member");
+      ValidationUtils.ArgumentNotNull(target, "target");
+
+      switch (member.MemberType)
+      {
+        case MemberTypes.Field:
+          return ((FieldInfo)member).GetValue(target);
+        case MemberTypes.Property:
+          try
+          {
+            return ((PropertyInfo)member).GetValue(target, null);
+          }
+          catch (TargetParameterCountException e)
+          {
+            throw new ArgumentException("MemberInfo '{0}' has index parameters".FormatWith(CultureInfo.InvariantCulture, member.Name), e);
+          }
+        default:
+          throw new ArgumentException("MemberInfo '{0}' is not of type FieldInfo or PropertyInfo".FormatWith(CultureInfo.InvariantCulture, CultureInfo.InvariantCulture, member.Name), "member");
+      }
+    }
+
+    /// <summary>
+    /// Sets the member's value on the target object.
+    /// </summary>
+    /// <param name="member">The member.</param>
+    /// <param name="target">The target.</param>
+    /// <param name="value">The value.</param>
+    public static void SetMemberValue(MemberInfo member, object target, object value)
+    {
+      ValidationUtils.ArgumentNotNull(member, "member");
+      ValidationUtils.ArgumentNotNull(target, "target");
+
+      switch (member.MemberType)
+      {
+        case MemberTypes.Field:
+          ((FieldInfo)member).SetValue(target, value);
+          break;
+        case MemberTypes.Property:
+          ((PropertyInfo)member).SetValue(target, value, null);
+          break;
+        default:
+          throw new ArgumentException("MemberInfo '{0}' must be of type FieldInfo or PropertyInfo".FormatWith(CultureInfo.InvariantCulture, member.Name), "member");
+      }
+    }
+
+    /// <summary>
+    /// Determines whether the specified MemberInfo can be read.
+    /// </summary>
+    /// <param name="member">The MemberInfo to determine whether can be read.</param>
+    /// /// <param name="nonPublic">if set to <c>true</c> then allow the member to be gotten non-publicly.</param>
+    /// <returns>
+    ///        <c>true</c> if the specified MemberInfo can be read; otherwise, <c>false</c>.
+    /// </returns>
+    public static bool CanReadMemberValue(MemberInfo member, bool nonPublic)
+    {
+      switch (member.MemberType)
+      {
+        case MemberTypes.Field:
+          FieldInfo fieldInfo = (FieldInfo)member;
+
+          if (nonPublic)
+            return true;
+          else if (fieldInfo.IsPublic)
+            return true;
+          return false;
+        case MemberTypes.Property:
+          PropertyInfo propertyInfo = (PropertyInfo) member;
+
+          if (!propertyInfo.CanRead)
+            return false;
+          if (nonPublic)
+            return true;
+          return (propertyInfo.GetGetMethod(nonPublic) != null);
+        default:
+          return false;
+      }
+    }
+
+    /// <summary>
+    /// Determines whether the specified MemberInfo can be set.
+    /// </summary>
+    /// <param name="member">The MemberInfo to determine whether can be set.</param>
+    /// <param name="nonPublic">if set to <c>true</c> then allow the member to be set non-publicly.</param>
+    /// <returns>
+    ///        <c>true</c> if the specified MemberInfo can be set; otherwise, <c>false</c>.
+    /// </returns>
+    public static bool CanSetMemberValue(MemberInfo member, bool nonPublic)
+    {
+      switch (member.MemberType)
+      {
+        case MemberTypes.Field:
+          FieldInfo fieldInfo = (FieldInfo)member;
+
+          if (fieldInfo.IsInitOnly)
+            return false;
+          if (nonPublic)
+            return true;
+          else if (fieldInfo.IsPublic)
+            return true;
+          return false;
+        case MemberTypes.Property:
+          PropertyInfo propertyInfo = (PropertyInfo)member;
+
+          if (!propertyInfo.CanWrite)
+            return false;
+          if (nonPublic)
+            return true;
+          return (propertyInfo.GetSetMethod(nonPublic) != null);
+        default:
+          return false;
+      }
+    }
+
+    public static List<MemberInfo> GetFieldsAndProperties<T>(BindingFlags bindingAttr)
+    {
+      return GetFieldsAndProperties(typeof(T), bindingAttr);
+    }
+
+    public static List<MemberInfo> GetFieldsAndProperties(Type type, BindingFlags bindingAttr)
+    {
+      List<MemberInfo> targetMembers = new List<MemberInfo>();
+
+      targetMembers.AddRange(GetFields(type, bindingAttr));
+      targetMembers.AddRange(GetProperties(type, bindingAttr));
+
+      // for some reason .NET returns multiple members when overriding a generic member on a base class
+      // http://forums.msdn.microsoft.com/en-US/netfxbcl/thread/b5abbfee-e292-4a64-8907-4e3f0fb90cd9/
+      // filter members to only return the override on the topmost class
+      // update: I think this is fixed in .NET 3.5 SP1 - leave this in for now...
+      List<MemberInfo> distinctMembers = new List<MemberInfo>(targetMembers.Count);
+
+      var groupedMembers = targetMembers.GroupBy(m => m.Name).Select(g => new { Count = g.Count(), Members = g.Cast<MemberInfo>() });
+      foreach (var groupedMember in groupedMembers)
+      {
+        if (groupedMember.Count == 1)
+        {
+          distinctMembers.Add(groupedMember.Members.First());
+        }
+        else
+        {
+          var members = groupedMember.Members.Where(m => !IsOverridenGenericMember(m, bindingAttr) || m.Name == "Item");
+
+          distinctMembers.AddRange(members);
+        }
+      }
+
+      return distinctMembers;
+    }
+
+    private static bool IsOverridenGenericMember(MemberInfo memberInfo, BindingFlags bindingAttr)
+    {
+      if (memberInfo.MemberType != MemberTypes.Field && memberInfo.MemberType != MemberTypes.Property)
+        throw new ArgumentException("Member must be a field or property.");
+
+      Type declaringType = memberInfo.DeclaringType;
+      if (!declaringType.IsGenericType)
+        return false;
+      Type genericTypeDefinition = declaringType.GetGenericTypeDefinition();
+      if (genericTypeDefinition == null)
+        return false;
+      MemberInfo[] members = genericTypeDefinition.GetMember(memberInfo.Name, bindingAttr);
+      if (members.Length == 0)
+        return false;
+      Type memberUnderlyingType = GetMemberUnderlyingType(members[0]);
+      if (!memberUnderlyingType.IsGenericParameter)
+        return false;
+
+      return true;
+    }
+
+    public static T GetAttribute<T>(ICustomAttributeProvider attributeProvider) where T : Attribute
+    {
+      return GetAttribute<T>(attributeProvider, true);
+    }
+
+    public static T GetAttribute<T>(ICustomAttributeProvider attributeProvider, bool inherit) where T : Attribute
+    {
+      T[] attributes = GetAttributes<T>(attributeProvider, inherit);
+
+      return CollectionUtils.GetSingleItem(attributes, true);
+    }
+
+    public static T[] GetAttributes<T>(ICustomAttributeProvider attributeProvider, bool inherit) where T : Attribute
+    {
+      ValidationUtils.ArgumentNotNull(attributeProvider, "attributeProvider");
+
+      // http://hyperthink.net/blog/getcustomattributes-gotcha/
+      // ICustomAttributeProvider doesn't do inheritance
+
+      if (attributeProvider is Assembly)
+        return (T[])Attribute.GetCustomAttributes((Assembly)attributeProvider, typeof(T), inherit);
+
+      if (attributeProvider is MemberInfo)
+        return (T[])Attribute.GetCustomAttributes((MemberInfo)attributeProvider, typeof(T), inherit);
+
+      if (attributeProvider is Module)
+        return (T[])Attribute.GetCustomAttributes((Module)attributeProvider, typeof(T), inherit);
+
+      if (attributeProvider is ParameterInfo)
+        return (T[])Attribute.GetCustomAttributes((ParameterInfo)attributeProvider, typeof(T), inherit);
+
+      return (T[])attributeProvider.GetCustomAttributes(typeof(T), inherit);
+    }
+
+    public static string GetNameAndAssessmblyName(Type t)
+    {
+      ValidationUtils.ArgumentNotNull(t, "t");
+
+      return t.FullName + ", " + t.Assembly.GetName().Name;
+    }
+
+    public static Type MakeGenericType(Type genericTypeDefinition, params Type[] innerTypes)
+    {
+      ValidationUtils.ArgumentNotNull(genericTypeDefinition, "genericTypeDefinition");
+      ValidationUtils.ArgumentNotNullOrEmpty<Type>(innerTypes, "innerTypes");
+      ValidationUtils.ArgumentConditionTrue(genericTypeDefinition.IsGenericTypeDefinition, "genericTypeDefinition", "Type {0} is not a generic type definition.".FormatWith(CultureInfo.InvariantCulture, genericTypeDefinition));
+
+      return genericTypeDefinition.MakeGenericType(innerTypes);
+    }
+
+    public static object CreateGeneric(Type genericTypeDefinition, Type innerType, params object[] args)
+    {
+      return CreateGeneric(genericTypeDefinition, new [] { innerType }, args);
+    }
+
+    public static object CreateGeneric(Type genericTypeDefinition, IList<Type> innerTypes, params object[] args)
+    {
+      return CreateGeneric(genericTypeDefinition, innerTypes, (t, a) => CreateInstance(t, a.ToArray()), args);
+    }
+
+    public static object CreateGeneric(Type genericTypeDefinition, IList<Type> innerTypes, Func<Type, IList<object>, object> instanceCreator, params object[] args)
+    {
+      ValidationUtils.ArgumentNotNull(genericTypeDefinition, "genericTypeDefinition");
+      ValidationUtils.ArgumentNotNullOrEmpty(innerTypes, "innerTypes");
+      ValidationUtils.ArgumentNotNull(instanceCreator, "createInstance");
+
+      Type specificType = MakeGenericType(genericTypeDefinition, innerTypes.ToArray());
+
+      return instanceCreator(specificType, args);
+    }
+
+    public static bool IsCompatibleValue(object value, Type type)
+    {
+      if (value == null)
+        return IsNullable(type);
+
+      if (type.IsAssignableFrom(value.GetType()))
+        return true;
+
+      return false;
+    }
+
+     public static object CreateInstance(Type type, params object[] args)
+     {
+       ValidationUtils.ArgumentNotNull(type, "type");
+
+#if !PocketPC
+       return Activator.CreateInstance(type, args);
+#else
+       // CF doesn't have a Activator.CreateInstance overload that takes args
+       // lame
+
+       if (type.IsValueType && CollectionUtils.IsNullOrEmpty<object>(args))
+         return Activator.CreateInstance(type);
+
+       ConstructorInfo[] constructors = type.GetConstructors();
+       ConstructorInfo match = constructors.Where(c =>
+         {
+           ParameterInfo[] parameters = c.GetParameters();
+           if (parameters.Length != args.Length)
+             return false;
+
+           for (int i = 0; i < parameters.Length; i++)
+           {
+             ParameterInfo parameter = parameters[i];
+             object value = args[i];
+
+             if (!IsCompatibleValue(value, parameter.ParameterType))
+               return false;
+           }
+
+           return true;
+         }).FirstOrDefault();
+
+       if (match == null)
+         throw new Exception("Could not create '{0}' with given parameters.".FormatWith(CultureInfo.InvariantCulture, type));
+
+       return match.Invoke(args);
+#endif
+     }
+
+    public static void SplitFullyQualifiedTypeName(string fullyQualifiedTypeName, out string typeName, out string assemblyName)
+    {
+      int? assemblyDelimiterIndex = GetAssemblyDelimiterIndex(fullyQualifiedTypeName);
+
+      if (assemblyDelimiterIndex != null)
+      {
+        typeName = fullyQualifiedTypeName.Substring(0, assemblyDelimiterIndex.Value).Trim();
+        assemblyName = fullyQualifiedTypeName.Substring(assemblyDelimiterIndex.Value + 1, fullyQualifiedTypeName.Length - assemblyDelimiterIndex.Value - 1).Trim();
+      }
+      else
+      {
+        typeName = fullyQualifiedTypeName;
+        assemblyName = null;
+      }
+
+    }
+
+    private static int? GetAssemblyDelimiterIndex(string fullyQualifiedTypeName)
+    {
+      // we need to get the first comma following all surrounded in brackets because of generic types
+      // e.g. System.Collections.Generic.Dictionary`2[[System.String, mscorlib,Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+      int scope = 0;
+      for (int i = 0; i < fullyQualifiedTypeName.Length; i++)
+      {
+        char current = fullyQualifiedTypeName[i];
+        switch (current)
+        {
+          case '[':
+            scope++;
+            break;
+          case ']':
+            scope--;
+            break;
+          case ',':
+            if (scope == 0)
+              return i;
+            break;
+        }
+      }
+
+      return null;
+    }
+
+    public static IEnumerable<FieldInfo> GetFields(Type targetType, BindingFlags bindingAttr)
+    {
+      ValidationUtils.ArgumentNotNull(targetType, "targetType");
+
+      List<MemberInfo> fieldInfos = new List<MemberInfo>(targetType.GetFields(bindingAttr));
+      // Type.GetFields doesn't return inherited private fields
+      // manually find private fields from base class
+      GetChildPrivateFields(fieldInfos, targetType, bindingAttr);
+
+      return fieldInfos.Cast<FieldInfo>();
+    }
+
+    private static void GetChildPrivateFields(IList<MemberInfo> initialFields, Type targetType, BindingFlags bindingAttr)
+    {
+      // fix weirdness with private FieldInfos only being returned for the current Type
+      // find base type fields and add them to result
+      if ((bindingAttr & BindingFlags.NonPublic) != 0)
+      {
+        // modify flags to not search for public fields
+        BindingFlags nonPublicBindingAttr = bindingAttr.RemoveFlag(BindingFlags.Public);
+
+        while ((targetType = targetType.BaseType) != null)
+        {
+          // filter out protected fields
+          IEnumerable<MemberInfo> childPrivateFields =
+            targetType.GetFields(nonPublicBindingAttr).Where(f => f.IsPrivate).Cast<MemberInfo>();
+
+          initialFields.AddRange(childPrivateFields);
+        }
+      }
+    }
+
+    public static IEnumerable<PropertyInfo> GetProperties(Type targetType, BindingFlags bindingAttr)
+    {
+      ValidationUtils.ArgumentNotNull(targetType, "targetType");
+
+      List<PropertyInfo> propertyInfos = new List<PropertyInfo>(targetType.GetProperties(bindingAttr));
+      GetChildPrivateProperties(propertyInfos, targetType, bindingAttr);
+
+      // a base class private getter/setter will be inaccessable unless the property was gotten from the base class
+      for (int i = 0; i < propertyInfos.Count; i++)
+      {
+        PropertyInfo member = propertyInfos[i];
+        if (member.DeclaringType != targetType)
+        {
+          Type[] types = member.GetIndexParameters().Select(p => p.ParameterType).ToArray();
+
+          PropertyInfo declaredMember = member.DeclaringType.GetProperty(member.Name, bindingAttr, null, member.PropertyType, types, null);
+          propertyInfos[i] = declaredMember;
+        }
+      }
+
+      return propertyInfos;
+    }
+
+    public static BindingFlags RemoveFlag(this BindingFlags bindingAttr, BindingFlags flag)
+    {
+      return ((bindingAttr & flag) == flag)
+        ? bindingAttr ^ flag
+        : bindingAttr;
+    }
+
+    private static void GetChildPrivateProperties(IList<PropertyInfo> initialProperties, Type targetType, BindingFlags bindingAttr)
+    {
+      // fix weirdness with private PropertyInfos only being returned for the current Type
+      // find base type properties and add them to result
+      if ((bindingAttr & BindingFlags.NonPublic) != 0)
+      {
+        // modify flags to not search for public fields
+        BindingFlags nonPublicBindingAttr = bindingAttr.RemoveFlag(BindingFlags.Public);
+
+        while ((targetType = targetType.BaseType) != null)
+        {
+          foreach (PropertyInfo propertyInfo in targetType.GetProperties(nonPublicBindingAttr))
+          {
+            PropertyInfo nonPublicProperty = propertyInfo;
+
+            // have to test on name rather than reference because instances are different
+            // depending on the type that GetProperties was called on
+            int index = initialProperties.IndexOf(p => p.Name == nonPublicProperty.Name);
+            if (index == -1)
+            {
+              initialProperties.Add(nonPublicProperty);
+            }
+            else
+            {
+              // replace nonpublic properties for a child, but gotten from
+              // the parent with the one from the child
+              // the property gotten from the child will have access to private getter/setter
+              initialProperties[index] = nonPublicProperty;
+            }
+          }
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/StringBuffer.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/StringBuffer.cs
new file mode 100644 (file)
index 0000000..11bb816
--- /dev/null
@@ -0,0 +1,99 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+
+namespace Newtonsoft.Json.Utilities
+{
+  /// <summary>
+  /// Builds a string. Unlike StringBuilder this class lets you reuse it's internal buffer.
+  /// </summary>
+  internal class StringBuffer
+  {
+    private char[] _buffer;
+    private int _position;
+
+    private static readonly char[] _emptyBuffer = new char[0];
+
+    public int Position
+    {
+      get { return _position; }
+      set { _position = value; }
+    }
+
+    public StringBuffer()
+    {
+      _buffer = _emptyBuffer;
+    }
+
+    public StringBuffer(int initalSize)
+    {
+      _buffer = new char[initalSize];
+    }
+
+    public void Append(char value)
+    {
+      // test if the buffer array is large enough to take the value
+      if (_position == _buffer.Length)
+      {
+        EnsureSize(1);
+      }
+
+      // set value and increment poisition
+      _buffer[_position++] = value;
+    }
+
+    public void Clear()
+    {
+      _buffer = _emptyBuffer;
+      _position = 0;
+    }
+
+    private void EnsureSize(int appendLength)
+    {
+      char[] newBuffer = new char[(_position + appendLength) * 2];
+
+      Array.Copy(_buffer, newBuffer, _position);
+
+      _buffer = newBuffer;
+    }
+
+    public override string ToString()
+    {
+      return ToString(0, _position);
+    }
+
+    public string ToString(int start, int length)
+    {
+      // TODO: validation
+      return new string(_buffer, start, length);
+    }
+
+    public char[] GetInternalBuffer()
+    {
+      return _buffer;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/StringUtils.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/StringUtils.cs
new file mode 100644 (file)
index 0000000..96929f0
--- /dev/null
@@ -0,0 +1,388 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Linq;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal static class StringUtils
+  {
+    public const string CarriageReturnLineFeed = "\r\n";
+    public const string Empty = "";
+    public const char CarriageReturn = '\r';
+    public const char LineFeed = '\n';
+    public const char Tab = '\t';
+
+    //public static string FormatWith(this string format, params object[] args)
+    //{
+    //  return FormatWith(format, null, args);
+    //}
+
+    public static string FormatWith(this string format, IFormatProvider provider, params object[] args)
+    {
+      ValidationUtils.ArgumentNotNull(format, "format");
+
+      return string.Format(provider, format, args);
+    }
+
+    /// <summary>
+    /// Determines whether the string contains white space.
+    /// </summary>
+    /// <param name="s">The string to test for white space.</param>
+    /// <returns>
+    ///        <c>true</c> if the string contains white space; otherwise, <c>false</c>.
+    /// </returns>
+    public static bool ContainsWhiteSpace(string s)
+    {
+      if (s == null)
+        throw new ArgumentNullException("s");
+
+      for (int i = 0; i < s.Length; i++)
+      {
+        if (char.IsWhiteSpace(s[i]))
+          return true;
+      }
+      return false;
+    }
+
+    /// <summary>
+    /// Determines whether the string is all white space. Empty string will return false.
+    /// </summary>
+    /// <param name="s">The string to test whether it is all white space.</param>
+    /// <returns>
+    ///        <c>true</c> if the string is all white space; otherwise, <c>false</c>.
+    /// </returns>
+    public static bool IsWhiteSpace(string s)
+    {
+      if (s == null)
+        throw new ArgumentNullException("s");
+
+      if (s.Length == 0)
+        return false;
+
+      for (int i = 0; i < s.Length; i++)
+      {
+        if (!char.IsWhiteSpace(s[i]))
+          return false;
+      }
+
+      return true;
+    }
+
+    /// <summary>
+    /// Ensures the target string ends with the specified string.
+    /// </summary>
+    /// <param name="target">The target.</param>
+    /// <param name="value">The value.</param>
+    /// <returns>The target string with the value string at the end.</returns>
+    public static string EnsureEndsWith(string target, string value)
+    {
+      if (target == null)
+        throw new ArgumentNullException("target");
+
+      if (value == null)
+        throw new ArgumentNullException("value");
+
+      if (target.Length >= value.Length)
+      {
+        if (string.Compare(target, target.Length - value.Length, value, 0, value.Length, StringComparison.OrdinalIgnoreCase) ==
+                        0)
+          return target;
+
+        string trimmedString = target.TrimEnd(null);
+
+        if (string.Compare(trimmedString, trimmedString.Length - value.Length, value, 0, value.Length,
+                        StringComparison.OrdinalIgnoreCase) == 0)
+          return target;
+      }
+
+      return target + value;
+    }
+
+    public static bool IsNullOrEmptyOrWhiteSpace(string s)
+    {
+      if (string.IsNullOrEmpty(s))
+        return true;
+      else if (IsWhiteSpace(s))
+        return true;
+      else
+        return false;
+    }
+
+    /// <summary>
+    /// Perform an action if the string is not null or empty.
+    /// </summary>
+    /// <param name="value">The value.</param>
+    /// <param name="action">The action to perform.</param>
+    public static void IfNotNullOrEmpty(string value, Action<string> action)
+    {
+      IfNotNullOrEmpty(value, action, null);
+    }
+
+    private static void IfNotNullOrEmpty(string value, Action<string> trueAction, Action<string> falseAction)
+    {
+      if (!string.IsNullOrEmpty(value))
+      {
+        if (trueAction != null)
+          trueAction(value);
+      }
+      else
+      {
+        if (falseAction != null)
+          falseAction(value);
+      }
+    }
+
+    /// <summary>
+    /// Indents the specified string.
+    /// </summary>
+    /// <param name="s">The string to indent.</param>
+    /// <param name="indentation">The number of characters to indent by.</param>
+    /// <returns></returns>
+    public static string Indent(string s, int indentation)
+    {
+      return Indent(s, indentation, ' ');
+    }
+
+    /// <summary>
+    /// Indents the specified string.
+    /// </summary>
+    /// <param name="s">The string to indent.</param>
+    /// <param name="indentation">The number of characters to indent by.</param>
+    /// <param name="indentChar">The indent character.</param>
+    /// <returns></returns>
+    public static string Indent(string s, int indentation, char indentChar)
+    {
+      if (s == null)
+        throw new ArgumentNullException("s");
+
+      if (indentation <= 0)
+        throw new ArgumentException("Must be greater than zero.", "indentation");
+
+      StringReader sr = new StringReader(s);
+      StringWriter sw = new StringWriter(CultureInfo.InvariantCulture);
+
+      ActionTextReaderLine(sr, sw, delegate(TextWriter tw, string line)
+      {
+        tw.Write(new string(indentChar, indentation));
+        tw.Write(line);
+      });
+
+      return sw.ToString();
+    }
+
+    private delegate void ActionLine(TextWriter textWriter, string line);
+
+    private static void ActionTextReaderLine(TextReader textReader, TextWriter textWriter, ActionLine lineAction)
+    {
+      string line;
+      bool firstLine = true;
+      while ((line = textReader.ReadLine()) != null)
+      {
+        if (!firstLine)
+          textWriter.WriteLine();
+        else
+          firstLine = false;
+
+        lineAction(textWriter, line);
+      }
+    }
+
+    /// <summary>
+    /// Numbers the lines.
+    /// </summary>
+    /// <param name="s">The string to number.</param>
+    /// <returns></returns>
+    public static string NumberLines(string s)
+    {
+      if (s == null)
+        throw new ArgumentNullException("s");
+
+      StringReader sr = new StringReader(s);
+      StringWriter sw = new StringWriter(CultureInfo.InvariantCulture);
+
+      int lineNumber = 1;
+
+      ActionTextReaderLine(sr, sw, delegate(TextWriter tw, string line)
+      {
+        tw.Write(lineNumber.ToString(CultureInfo.InvariantCulture).PadLeft(4));
+        tw.Write(". ");
+        tw.Write(line);
+
+        lineNumber++;
+      });
+
+      return sw.ToString();
+    }
+
+    /// <summary>
+    /// Nulls an empty string.
+    /// </summary>
+    /// <param name="s">The string.</param>
+    /// <returns>Null if the string was null, otherwise the string unchanged.</returns>
+    public static string NullEmptyString(string s)
+    {
+      return (string.IsNullOrEmpty(s)) ? null : s;
+    }
+
+    public static string ReplaceNewLines(string s, string replacement)
+    {
+      StringReader sr = new StringReader(s);
+      StringBuilder sb = new StringBuilder();
+
+      bool first = true;
+
+      string line;
+      while ((line = sr.ReadLine()) != null)
+      {
+        if (first)
+          first = false;
+        else
+          sb.Append(replacement);
+
+        sb.Append(line);
+      }
+
+      return sb.ToString();
+    }
+
+    public static string Truncate(string s, int maximumLength)
+    {
+      return Truncate(s, maximumLength, "...");
+    }
+
+    public static string Truncate(string s, int maximumLength, string suffix)
+    {
+      if (suffix == null)
+        throw new ArgumentNullException("suffix");
+
+      if (maximumLength <= 0)
+        throw new ArgumentException("Maximum length must be greater than zero.", "maximumLength");
+
+      int subStringLength = maximumLength - suffix.Length;
+
+      if (subStringLength <= 0)
+        throw new ArgumentException("Length of suffix string is greater or equal to maximumLength");
+
+      if (s != null && s.Length > maximumLength)
+      {
+        string truncatedString = s.Substring(0, subStringLength);
+        // incase the last character is a space
+        truncatedString = truncatedString.Trim();
+        truncatedString += suffix;
+
+        return truncatedString;
+      }
+      else
+      {
+        return s;
+      }
+    }
+
+    public static StringWriter CreateStringWriter(int capacity)
+    {
+      StringBuilder sb = new StringBuilder(capacity);
+      StringWriter sw = new StringWriter(sb, CultureInfo.InvariantCulture);
+
+      return sw;
+    }
+
+    public static int? GetLength(string value)
+    {
+      if (value == null)
+        return null;
+      else
+        return value.Length;
+    }
+
+    public static string ToCharAsUnicode(char c)
+    {
+      char h1 = MathUtils.IntToHex((c >> 12) & '\x000f');
+      char h2 = MathUtils.IntToHex((c >> 8) & '\x000f');
+      char h3 = MathUtils.IntToHex((c >> 4) & '\x000f');
+      char h4 = MathUtils.IntToHex(c & '\x000f');
+
+      return new string(new[] { '\\', 'u', h1, h2, h3, h4 });
+    }
+
+    public static void WriteCharAsUnicode(TextWriter writer, char c)
+    {
+      ValidationUtils.ArgumentNotNull(writer, "writer");
+
+      char h1 = MathUtils.IntToHex((c >> 12) & '\x000f');
+      char h2 = MathUtils.IntToHex((c >> 8) & '\x000f');
+      char h3 = MathUtils.IntToHex((c >> 4) & '\x000f');
+      char h4 = MathUtils.IntToHex(c & '\x000f');
+
+      writer.Write('\\');
+      writer.Write('u');
+      writer.Write(h1);
+      writer.Write(h2);
+      writer.Write(h3);
+      writer.Write(h4);
+    }
+
+    public static TSource ForgivingCaseSensitiveFind<TSource>(this IEnumerable<TSource> source, Func<TSource, string> valueSelector, string testValue)
+    {
+      if (source == null)
+        throw new ArgumentNullException("source");
+      if (valueSelector == null)
+        throw new ArgumentNullException("valueSelector");
+
+      var caseInsensitiveResults = source.Where(s => string.Compare(valueSelector(s), testValue, StringComparison.OrdinalIgnoreCase) == 0);
+      if (caseInsensitiveResults.Count() <= 1)
+      {
+        return caseInsensitiveResults.SingleOrDefault();
+      }
+      else
+      {
+        // multiple results returned. now filter using case sensitivity
+        var caseSensitiveResults = source.Where(s => string.Compare(valueSelector(s), testValue, StringComparison.Ordinal) == 0);
+        return caseSensitiveResults.SingleOrDefault();
+      }
+    }
+
+    public static string ToCamelCase(string s)
+    {
+      if (string.IsNullOrEmpty(s))
+        return s;
+
+      if (!char.IsUpper(s[0]))
+        return s;
+
+      string camelCase = char.ToLower(s[0], CultureInfo.InvariantCulture).ToString(CultureInfo.InvariantCulture);
+      if (s.Length > 1)
+        camelCase += s.Substring(1);
+
+      return camelCase;
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/ThreadSafeStore.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/ThreadSafeStore.cs
new file mode 100644 (file)
index 0000000..e339e36
--- /dev/null
@@ -0,0 +1,60 @@
+using System;
+using System.Collections.Generic;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal class ThreadSafeStore<TKey, TValue>
+  {
+    private readonly object _lock = new object();
+    private Dictionary<TKey, TValue> _store;
+    private readonly Func<TKey, TValue> _creator;
+
+    public ThreadSafeStore(Func<TKey, TValue> creator)
+    {
+      if (creator == null)
+        throw new ArgumentNullException("creator");
+
+      _creator = creator;
+    }
+
+    public TValue Get(TKey key)
+    {
+      if (_store == null)
+        return AddValue(key);
+
+      TValue value;
+      if (!_store.TryGetValue(key, out value))
+        return AddValue(key);
+
+      return value;
+    }
+
+    private TValue AddValue(TKey key)
+    {
+      TValue value = _creator(key);
+
+      lock (_lock)
+      {
+        if (_store == null)
+        {
+          _store = new Dictionary<TKey, TValue>();
+          _store[key] = value;
+        }
+        else
+        {
+          // double check locking
+          TValue checkValue;
+          if (_store.TryGetValue(key, out checkValue))
+            return checkValue;
+
+          Dictionary<TKey, TValue> newStore = new Dictionary<TKey, TValue>(_store);
+          newStore[key] = value;
+
+          _store = newStore;
+        }
+
+        return value;
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/ValidationUtils.cs b/trunk/Libraries/Json40r2/Source/Src/Newtonsoft.Json/Utilities/ValidationUtils.cs
new file mode 100644 (file)
index 0000000..d77cb52
--- /dev/null
@@ -0,0 +1,149 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+using System.Globalization;
+
+namespace Newtonsoft.Json.Utilities
+{
+  internal static class ValidationUtils
+  {
+    public const string EmailAddressRegex = @"^([a-zA-Z0-9_'+*$%\^&!\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9:]{2,4})+$";
+    public const string CurrencyRegex = @"(^\$?(?!0,?\d)\d{1,3}(,?\d{3})*(\.\d\d)?)$";
+    public const string DateRegex =
+        @"^(((0?[1-9]|[12]\d|3[01])[\.\-\/](0?[13578]|1[02])[\.\-\/]((1[6-9]|[2-9]\d)?\d{2}|\d))|((0?[1-9]|[12]\d|30)[\.\-\/](0?[13456789]|1[012])[\.\-\/]((1[6-9]|[2-9]\d)?\d{2}|\d))|((0?[1-9]|1\d|2[0-8])[\.\-\/]0?2[\.\-\/]((1[6-9]|[2-9]\d)?\d{2}|\d))|(29[\.\-\/]0?2[\.\-\/]((1[6-9]|[2-9]\d)?(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)|00|[048])))$";
+    public const string NumericRegex = @"\d*";
+
+    public static void ArgumentNotNullOrEmpty(string value, string parameterName)
+    {
+      if (value == null)
+        throw new ArgumentNullException(parameterName);
+
+      if (value.Length == 0)
+        throw new ArgumentException("'{0}' cannot be empty.".FormatWith(CultureInfo.InvariantCulture, parameterName), parameterName);
+    }
+
+    public static void ArgumentNotNullOrEmptyOrWhitespace(string value, string parameterName)
+    {
+      ArgumentNotNullOrEmpty(value, parameterName);
+
+      if (StringUtils.IsWhiteSpace(value))
+        throw new ArgumentException("'{0}' cannot only be whitespace.".FormatWith(CultureInfo.InvariantCulture, parameterName), parameterName);
+    }
+
+    public static void ArgumentTypeIsEnum(Type enumType, string parameterName)
+    {
+      ArgumentNotNull(enumType, "enumType");
+
+      if (!enumType.IsEnum)
+        throw new ArgumentException("Type {0} is not an Enum.".FormatWith(CultureInfo.InvariantCulture, enumType), parameterName);
+    }
+
+    public static void ArgumentNotNullOrEmpty<T>(ICollection<T> collection, string parameterName)
+    {
+      ArgumentNotNullOrEmpty<T>(collection, parameterName, "Collection '{0}' cannot be empty.".FormatWith(CultureInfo.InvariantCulture, parameterName));
+    }
+
+    public static void ArgumentNotNullOrEmpty<T>(ICollection<T> collection, string parameterName, string message)
+    {
+      if (collection == null)
+        throw new ArgumentNullException(parameterName);
+
+      if (collection.Count == 0)
+        throw new ArgumentException(message, parameterName);
+    }
+
+    public static void ArgumentNotNullOrEmpty(ICollection collection, string parameterName)
+    {
+      ArgumentNotNullOrEmpty(collection, parameterName, "Collection '{0}' cannot be empty.".FormatWith(CultureInfo.InvariantCulture, parameterName));
+    }
+
+    public static void ArgumentNotNullOrEmpty(ICollection collection, string parameterName, string message)
+    {
+      if (collection == null)
+        throw new ArgumentNullException(parameterName);
+
+      if (collection.Count == 0)
+        throw new ArgumentException(message, parameterName);
+    }
+
+    public static void ArgumentNotNull(object value, string parameterName)
+    {
+      if (value == null)
+        throw new ArgumentNullException(parameterName);
+    }
+
+    public static void ArgumentNotNegative(int value, string parameterName)
+    {
+      if (value <= 0)
+        throw MiscellaneousUtils.CreateArgumentOutOfRangeException(parameterName, value, "Argument cannot be negative.");
+    }
+
+    public static void ArgumentNotNegative(int value, string parameterName, string message)
+    {
+      if (value <= 0)
+        throw MiscellaneousUtils.CreateArgumentOutOfRangeException(parameterName, value, message);
+    }
+
+    public static void ArgumentNotZero(int value, string parameterName)
+    {
+      if (value == 0)
+        throw MiscellaneousUtils.CreateArgumentOutOfRangeException(parameterName, value, "Argument cannot be zero.");
+    }
+
+    public static void ArgumentNotZero(int value, string parameterName, string message)
+    {
+      if (value == 0)
+        throw MiscellaneousUtils.CreateArgumentOutOfRangeException(parameterName, value, message);
+    }
+
+    public static void ArgumentIsPositive<T>(T value, string parameterName) where T : struct, IComparable<T>
+    {
+      if (value.CompareTo(default(T)) != 1)
+        throw MiscellaneousUtils.CreateArgumentOutOfRangeException(parameterName, value, "Positive number required.");
+    }
+
+    public static void ArgumentIsPositive(int value, string parameterName, string message)
+    {
+      if (value > 0)
+        throw MiscellaneousUtils.CreateArgumentOutOfRangeException(parameterName, value, message);
+    }
+
+    public static void ObjectNotDisposed(bool disposed, Type objectType)
+    {
+      if (disposed)
+        throw new ObjectDisposedException(objectType.Name);
+    }
+
+    public static void ArgumentConditionTrue(bool condition, string parameterName, string message)
+    {
+      if (!condition)
+        throw new ArgumentException(message, parameterName);
+    }
+  }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Tools/7-zip/7-zip.chm b/trunk/Libraries/Json40r2/Source/Tools/7-zip/7-zip.chm
new file mode 100644 (file)
index 0000000..eee875e
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/7-zip/7-zip.chm differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/7-zip/copying.txt b/trunk/Libraries/Json40r2/Source/Tools/7-zip/copying.txt
new file mode 100644 (file)
index 0000000..4c38901
--- /dev/null
@@ -0,0 +1,504 @@
+      GNU LESSER GENERAL PUBLIC LICENSE
+           Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+          Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+      GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+\f
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+          NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+         END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/trunk/Libraries/Json40r2/Source/Tools/7-zip/license.txt b/trunk/Libraries/Json40r2/Source/Tools/7-zip/license.txt
new file mode 100644 (file)
index 0000000..2b4c60c
--- /dev/null
@@ -0,0 +1,30 @@
+      7-Zip Command line version
+      ~~~~~~~~~~~~~~~~~~~~~~~~~~
+      License for use and distribution
+      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+      7-Zip Copyright (C) 1999-2009 Igor Pavlov.
+
+      7za.exe is distributed under the GNU LGPL license
+
+      Notes: 
+        You can use 7-Zip on any computer, including a computer in a commercial 
+        organization. You don't need to register or pay for 7-Zip.
+
+
+      GNU LGPL information
+      --------------------
+
+        This library is free software; you can redistribute it and/or
+        modify it under the terms of the GNU Lesser General Public
+        License as published by the Free Software Foundation; either
+        version 2.1 of the License, or (at your option) any later version.
+
+        This library is distributed in the hope that it will be useful,
+        but WITHOUT ANY WARRANTY; without even the implied warranty of
+        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+        Lesser General Public License for more details.
+
+        You should have received a copy of the GNU Lesser General Public
+        License along with this library; if not, write to the Free Software
+        Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
diff --git a/trunk/Libraries/Json40r2/Source/Tools/7-zip/readme.txt b/trunk/Libraries/Json40r2/Source/Tools/7-zip/readme.txt
new file mode 100644 (file)
index 0000000..91bb3cd
--- /dev/null
@@ -0,0 +1,42 @@
+7-Zip Command line version 4.65
+-------------------------------
+
+7-Zip is a file archiver with high compression ratio.
+7za.exe is a standalone command line version of 7-Zip.
+
+7-Zip Copyright (C) 1999-2009 Igor Pavlov.
+
+Features of 7za.exe: 
+  - High compression ratio in new 7z format
+  - Supported formats:
+      - Packing / unpacking: 7z, ZIP, GZIP, BZIP2 and TAR 
+      - Unpacking only: Z
+  - Highest compression ratio for ZIP and GZIP formats.
+  - Fast compression and decompression
+  - Strong AES-256 encryption in 7z and ZIP formats.
+
+7za.exe is a free software distributed under the GNU LGPL.
+Read license.txt for more information.
+
+Source code of 7za.exe and 7-Zip can be found at
+http://www.7-zip.org/
+
+7za.exe can work in Windows 95/98/ME/NT/2000/XP/2003/Vista.
+
+There is also port of 7za.exe for POSIX systems like Unix (Linux, Solaris, OpenBSD, 
+FreeBSD, Cygwin, AIX, ...), MacOS X and BeOS:
+
+http://p7zip.sourceforge.net/
+
+
+  This distributive packet contains the following files:
+
+  7za.exe       - 7-Zip standalone command line version.
+  readme.txt    - This file.
+  copying.txt   - GNU LGPL license.
+  license.txt   - License information.
+  7-zip.chm     - User's Manual in HTML Help format.
+
+
+---
+End of document
diff --git a/trunk/Libraries/Json40r2/Source/Tools/ILMerge/ILMerge License.rtf b/trunk/Libraries/Json40r2/Source/Tools/ILMerge/ILMerge License.rtf
new file mode 100644 (file)
index 0000000..e800151
--- /dev/null
@@ -0,0 +1,104 @@
+{\rtf1\ansi\ansicpg1252\uc1\deff0\stshfdbch0\stshfloch0\stshfhich0\stshfbi0\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f37\fswiss\fcharset0\fprq2{\*\panose 020b0604030504040204}Tahoma;}
+{\f39\froman\fcharset0\fprq2{\*\panose 02040602050305030304}Book Antiqua;}{\f40\fswiss\fcharset0\fprq2{\*\panose 020b0706030402020204}Franklin Gothic Demi Cond;}{\f41\fswiss\fcharset0\fprq2{\*\panose 020b0503020102020204}Franklin Gothic Book;}
+{\f42\froman\fcharset238\fprq2 Times New Roman CE;}{\f43\froman\fcharset204\fprq2 Times New Roman Cyr;}{\f45\froman\fcharset161\fprq2 Times New Roman Greek;}{\f46\froman\fcharset162\fprq2 Times New Roman Tur;}
+{\f47\froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f48\froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f49\froman\fcharset186\fprq2 Times New Roman Baltic;}{\f50\froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
+{\f412\fswiss\fcharset238\fprq2 Tahoma CE;}{\f413\fswiss\fcharset204\fprq2 Tahoma Cyr;}{\f415\fswiss\fcharset161\fprq2 Tahoma Greek;}{\f416\fswiss\fcharset162\fprq2 Tahoma Tur;}{\f417\fswiss\fcharset177\fprq2 Tahoma (Hebrew);}
+{\f418\fswiss\fcharset178\fprq2 Tahoma (Arabic);}{\f419\fswiss\fcharset186\fprq2 Tahoma Baltic;}{\f420\fswiss\fcharset163\fprq2 Tahoma (Vietnamese);}{\f421\fswiss\fcharset222\fprq2 Tahoma (Thai);}{\f432\froman\fcharset238\fprq2 Book Antiqua CE;}
+{\f433\froman\fcharset204\fprq2 Book Antiqua Cyr;}{\f435\froman\fcharset161\fprq2 Book Antiqua Greek;}{\f436\froman\fcharset162\fprq2 Book Antiqua Tur;}{\f439\froman\fcharset186\fprq2 Book Antiqua Baltic;}
+{\f442\fswiss\fcharset238\fprq2 Franklin Gothic Demi Cond CE;}{\f443\fswiss\fcharset204\fprq2 Franklin Gothic Demi Cond Cyr;}{\f445\fswiss\fcharset161\fprq2 Franklin Gothic Demi Cond Greek;}{\f446\fswiss\fcharset162\fprq2 Franklin Gothic Demi Cond Tur;}
+{\f449\fswiss\fcharset186\fprq2 Franklin Gothic Demi Cond Baltic;}{\f452\fswiss\fcharset238\fprq2 Franklin Gothic Book CE;}{\f453\fswiss\fcharset204\fprq2 Franklin Gothic Book Cyr;}{\f455\fswiss\fcharset161\fprq2 Franklin Gothic Book Greek;}
+{\f456\fswiss\fcharset162\fprq2 Franklin Gothic Book Tur;}{\f459\fswiss\fcharset186\fprq2 Franklin Gothic Book Baltic;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;
+\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}
+{\stylesheet{\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext0 Normal;}{\*\cs10 \additive \ssemihidden Default Paragraph Font;}{\*
+\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv 
+\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs20\lang1024\langfe1024\cgrid\langnp1024\langfenp1024 \snext11 \ssemihidden Normal Table;}{\s15\ql \fi-274\li274\ri0\sb120\sl460\slmult0
+\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin274\itap0 \f40\fs44\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext15 \styrsid9786739 1sectionhead;}{\s16\ql \li0\ri0\sb120\sl200\slmult0
+\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \caps\f40\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext16 \styrsid9786739 4laparahead;}{\s17\ql \li0\ri-18\sb120\sl240\slmult0
+\widctlpar\aspalpha\aspnum\faauto\adjustright\rin-18\lin0\itap0 \f40\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext17 \styrsid9786739 2lasubhead;}{\s18\ql \fi-187\li187\ri0\sb60\sl180\slmult0
+\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin187\itap0 \f41\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext18 \styrsid9786739 3cnumbered;}{\s19\ql \fi-340\li624\ri0\sb60\sl160\slmult0
+\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin624\itap0 \f41\fs14\cf1\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext19 \styrsid9786739 3inumbered2ndlevel;}{\s20\ql \li0\ri0\sb240\sl240\slmult0
+\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \f40\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext20 \styrsid9786739 2afrenchsubhead;}{\s21\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 
+\cbpat9 \f37\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext21 \ssemihidden \styrsid7154712 Document Map;}}{\*\latentstyles\lsdstimax156\lsdlockeddef0}{\*\pgptbl {\pgp\ipgp2\itap0\li0\ri0\sb0\sa0\brdrt\brdrs\brdrw20 }{\pgp\ipgp0
+\itap0\li0\ri0\sb0\sa0}}{\*\rsidtbl \rsid2099452\rsid4207571\rsid5465292\rsid5510097\rsid5510644\rsid7154712\rsid7241305\rsid7672529\rsid7735936\rsid9179139\rsid9786739\rsid10440675\rsid11303133\rsid13130884\rsid14028235\rsid14100361\rsid14113652
+\rsid15276140\rsid16213514}{\*\generator Microsoft Word 11.0.6359;}{\info{\title ILMerge EULA}{\author Ken Leppert}{\operator mbarnett}{\creatim\yr2005\mo3\dy16\hr15\min43}{\revtim\yr2005\mo3\dy16\hr15\min43}{\printim\yr2004\mo4\dy30\hr13\min9}{\version2}
+{\edmins0}{\nofpages3}{\nofwords1188}{\nofchars6775}{\*\company Microsoft Corporation}{\nofcharsws7948}{\vern24703}}\widowctrl\ftnbj\aenddoc\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dgmargin\dghspace180\dgvspace180
+\dghorigin1800\dgvorigin1440\dghshow1\dgvshow1\jexpand\viewkind1\viewscale68\viewzk2\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel
+\wrppunct\asianbrkrule\rsidroot9786739\newtblstyruls\nogrowautofit \fet0\sectd \linex0\endnhere\sectlinegrid360\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang 
+{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang 
+{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain 
+\s15\ql \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\aspalpha\aspnum\faauto\outlinelevel0\adjustright\rin0\lin0\itap0\pararsid7154712 \f40\fs44\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\b\f39\fs28\insrsid9786739 MICROSOFT }{
+\b\f39\fs28\insrsid5465292 ILMerge}{\insrsid9786739 
+\par }{\b\f39\fs22\insrsid9786739 END-USER LICENSE AGREEMENT FOR MICROSOFT SOFTWARE}{\insrsid9786739 
+\par }\pard\plain \s17\qj \li0\ri-17\sb100\sa100\sbauto1\saauto1\widctlpar\aspalpha\aspnum\faauto\adjustright\rin-17\lin0\itap0\pararsid14100361 \f40\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\b\f39\insrsid9786739 IMPORTANT\emdash 
+READ CAREFULLY: }{\f39\insrsid9786739 This End-User License Agreement (\'93EULA\'94) is a legal agreement between you (either an individual or a single entity) and Microsoft Corporation (\'93Microsoft\'94) for th
+e Microsoft software that accompanies this EULA, which includes computer software and may include associated media, printed materials, \'93online\'94 or electronic documentation, and Internet-based services (\'93Software\'94).\~
+ An amendment or addendum to this EULA may accompany the Software.\~ }{\b\f39\insrsid9786739 
+YOU AGREE TO BE BOUND BY THE TERMS OF THIS EULA BY INSTALLING, COPYING, OR OTHERWISE USING THE SOFTWARE. IF YOU DO NOT AGREE, DO NOT INSTALL, COPY, OR USE THE SOFTWARE.}{\insrsid9786739 
+\par }\pard\plain \qj \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14100361 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f39\fs22\insrsid9786739 1.\~\~\~\~\~\~\~\~ }{
+\b\f39\fs22\insrsid9786739 GRANTS OF LICENSE}{\f39\fs22\insrsid9786739 . Microsoft grants you the rights described in this EULA provided that you comply with all terms and conditions of this EULA.\~ }{\insrsid9786739 
+\par }\pard\plain \s19\qj \fi720\li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14100361 \f41\fs14\cf1\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f39\fs22\cf0\insrsid9786739 1.1\~\~\~\~\~\~ }{
+\b\i\f39\fs22\cf0\insrsid9786739 License Grant}{\f39\fs22\cf0\insrsid9786739 . Microsoft grants to you a personal, nonexclusive, nontransferable, limited license to }{\f39\fs22\insrsid9786739 install and use a reasonable number of copies of 
+the Software on computers residing on your premises }{\f39\fs22\cf0\insrsid9786739 for the purposes of designing, developing, and testing, your software product(s), provided that you are the only individual using the Software.\~ }{\insrsid9786739 
+\par }\pard\plain \s18\qj \fi720\li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14100361 \f41\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f39\fs22\insrsid9786739 1.2\~\~\~\~\~\~ }{
+\b\i\f39\fs22\insrsid9786739 Documentation}{\f39\fs22\insrsid9786739 .}{\b\f39\fs22\insrsid9786739 \~ }{\f39\fs22\insrsid9786739 You may make and use a reasonabl
+e number of copies of any documentation, provided that such copies shall be used only for your personal purposes and are not to be republished or distributed (either in hard copy or electronic form) beyond your premises.}{\insrsid9786739 
+\par }\pard \s18\qj \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14100361 {\f39\fs22\insrsid9786739 2.\~\~\~\~\~\~\~\~ }{\b\f39\fs22\insrsid9786739 RESERVATION OF RIGHTS AND OWNERSHIP.\~ }{
+\f39\fs22\insrsid9786739 The Software is licensed as a single product.\~ Its component parts may not be separated. Microsoft reserves all rights not expressly granted to you in this EULA.\~
+ The Software is protected by copyright and other intellectual property laws and treaties}{\f39\fs22\insrsid14028235 , and}{\f39\fs22\insrsid9786739  Microsoft }{\f39\fs22\insrsid14028235 (}{\f39\fs22\insrsid9786739 or its suppliers}{
+\f39\fs22\insrsid14028235 , where applicable)}{\f39\fs22\insrsid9786739  own }{\f39\fs22\insrsid14028235 all right, }{\f39\fs22\insrsid9786739 title, }{\f39\fs22\insrsid14028235 and interest in all }{\f39\fs22\insrsid9786739 
+intellectual property rights in the Software.\~ }{\b\f39\fs22\insrsid9786739 The Software is licensed, not sold.}{\insrsid9786739 
+\par }\pard\plain \s19\qj \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14100361 \f41\fs14\cf1\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f39\fs22\cf0\insrsid9786739 3.\~\~\~\~\~\~\~\~ }{
+\b\f39\fs22\cf0\insrsid9786739 LIMITATIONS ON REVERSE ENGINEERING, DECOMPILATION, AND DISASSEMBLY}{\b\i\f39\fs22\cf0\insrsid9786739 .}{\f39\fs22\cf0\insrsid9786739 \~
+ You may not reverse engineer, decompile, or disassemble the Software, except and only to the extent that such activity is expressly permitted by applicable law notwithstanding this limitation.}{\insrsid9786739 
+\par }\pard\plain \s18\qj \li0\ri0\sb100\sa100\sbauto1\saauto1\sl220\slmult0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14100361 \f41\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f39\fs22\insrsid9786739 4.\~\~\~\~\~\~\~\~ 
+}{\b\f39\fs22\insrsid9786739 NO RENTAL/COMMERCIAL HOSTING.}{\b\i\f39\fs22\insrsid9786739  }{\f39\fs22\insrsid9786739 You may not rent, lease, lend or provide commercial hosting services with the Software.}{\insrsid9786739 
+\par }\pard\plain \s19\qj \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14100361 \f41\fs14\cf1\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f39\fs22\cf0\insrsid9786739 5.\~\~\~\~\~\~\~\~ }{
+\b\f39\fs22\cf0\insrsid9786739 NO SOFTWARE TRANSFER.\~ }{\f39\fs22\cf0\insrsid9786739 You may not assign or otherwise transfer the SOFTWARE or any of your rights hereunder to any third party.}{\insrsid9786739 
+\par }{\f39\fs22\cf0\insrsid9786739 6.\~\~\~\~\~\~\~\~ }{\b\f39\fs22\cf0\insrsid9786739 CONSENT TO USE OF DATA.\~ }{\f39\fs22\cf0\insrsid9786739 You
+ agree that Microsoft and its affiliates may collect and use technical information gathered as part of the product support services provided to you, if any, related to the Software.\~
+ Microsoft may use this information solely to improve our products or to provide customized services or technologies to you and will not disclose this information in a form that personally identifies you.\~\~ }{\insrsid9786739 
+\par }{\f39\fs22\cf0\insrsid5510644 7}{\f39\fs22\cf0\insrsid9786739 .\~\~\~\~\~\~\~\~ }{\b\f39\fs22\cf0\insrsid9786739 ADDITIONAL SOFTWARE/SERVICES.\~ }{\f39\fs22\insrsid9786739 Microsoft is not obligated to provide maintenance, technical supplements}{
+\f39\fs22\insrsid14028235 , updates,}{\f39\fs22\insrsid9786739  or other support to you for the Software licensed under this EULA. }{\f39\fs22\insrsid7241305  }{\f39\fs22\insrsid9786739 In the event that Microsoft does provide such supplements or updates}
+{\b\f39\fs22\insrsid9786739 , }{\f39\fs22\insrsid9786739 this EULA applies to such updates, supplements, or add-on components of the Software that Microsoft may provide to 
+you or make available to you after the date you obtain your initial copy of the Software, unless we provide other terms along with the update, supplement, or add-on component}{\f39\fs22\cf0\insrsid9786739 .\~
+ Microsoft reserves the right to discontinue any Internet-based services provided to you or made available to you through the use of the Software.\~ }{\insrsid9786739 
+\par }\pard\plain \s18\qj \li0\ri0\sb100\sa100\sbauto1\saauto1\sl220\slmult0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14100361 \f41\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f39\fs22\insrsid5510644 8}{
+\f39\fs22\insrsid9786739 .\~\~\~\~\~\~\~\~ }{\b\f39\fs22\insrsid9786739 EXPORT RESTRICTIONS}{\f39\fs22\insrsid9786739 .\~ }{\f39\fs22\cgrid0\insrsid9786739 You acknowledge that the Software is subject to U.S. export jurisdiction.\~
+ You agree to comply with all applicable international and national laws that apply to the Software, including the U.S. Export Administration Regulations, as well as end-user, end-use, and destination restrictions issued by U.S. and other governments.\~\~
+ For additional information see }{\f39\fs22\ul\cgrid0\insrsid9786739 http://www.microsoft.com/exporting/}{\f39\fs22\cgrid0\insrsid9786739 .}{\insrsid9786739 
+\par }\pard\plain \s19\qj \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14100361 \f41\fs14\cf1\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f39\fs22\cf0\insrsid14113652 9}{
+\f39\fs22\cf0\insrsid9786739 .\~\~\~\~\~\~ }{\b\f39\fs22\cf0\insrsid9786739 TERMINATION.}{\f39\fs22\cf0\insrsid9786739 \~ Without prejudice to any other rights, Microsoft may terminate this EULA if you fail to comply with }{\f39\fs22\cf0\insrsid7241305 
+any }{\f39\fs22\cf0\insrsid9786739 term}{\f39\fs22\cf0\insrsid7241305  or}{\f39\fs22\cf0\insrsid9786739  condition of this EULA. }{\f39\fs22\cf0\insrsid7241305  }{\f39\fs22\cf0\insrsid9786739 
+In such event, you must destroy all copies of the Software and all of its component parts.}{\insrsid9786739 
+\par }\pard\plain \s18\qj \li0\ri0\sb100\sa100\sbauto1\saauto1\sl220\slmult0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14100361 \f41\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f39\fs22\insrsid9786739 1}{
+\f39\fs22\insrsid14113652 0}{\f39\fs22\insrsid9786739 .\~\~\~\~\~\~ }{\b\f39\fs22\ul\insrsid9786739 DISCLAIMER OF WARRANTIES}{\b\f39\fs22\insrsid9786739 .\~
+ TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, MICROSOFT AND ITS SUPPLIERS PROVIDE THE SOFTWARE}{\f39\fs22\insrsid9786739  }{\b\f39\fs22\insrsid9786739 AND SUPPORT SERVICES (IF ANY) }{\b\i\f39\fs22\insrsid9786739 AS IS AND WITH ALL FAULTS}{
+\b\f39\fs22\insrsid9786739 , AND HEREBY DISCLAIM ALL OTHER WARRANTIES AND CONDITIONS, WHETHER EXPRESS, IMPLIED
+ OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY (IF ANY) IMPLIED WARRANTIES, DUTIES OR CONDITIONS OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR PURPOSE, OF RELIABILITY OR AVAILABILITY, OF ACCURACY OR COMPLETENESS OF RESPONSES, OF RESULTS, OF WORKMANLI
+K
+E EFFORT, OF LACK OF VIRUSES, AND OF LACK OF NEGLIGENCE, ALL WITH REGARD TO THE SOFTWARE, AND THE PROVISION OF OR FAILURE TO PROVIDE SUPPORT OR OTHER SERVICES, INFORMATION, SOFTWARE, AND RELATED CONTENT THROUGH THE SOFTWARE OR OTHERWISE ARISING OUT OF THE
+ USE OF THE SOFTWARE.\~ ALSO, THERE IS NO WARRANTY OR CONDITION OF TITLE, QUIET ENJOYMENT, QUIET POSSESSION, CORRESPONDENCE TO DESCRIPTION OR NON-INFRINGEMENT WITH REGARD TO THE SOFTWARE.}{\insrsid9786739 
+\par }{\f39\fs22\insrsid9786739 1}{\f39\fs22\insrsid14113652 1}{\f39\fs22\insrsid9786739 .}{\b\f39\fs22\insrsid9786739 \~\~\~\~\~\~ }{\b\f39\fs22\ul\insrsid9786739 EXCLUSION OF INCIDENTAL, CONSEQUENTIAL AND CERTAIN OTHER DAMAGES}{\b\f39\fs22\insrsid9786739 .\~
+ }{\b\caps\f39\fs22\insrsid9786739 
+To the maximum extent permitted by applicable law, in no event shall Microsoft or its suppliers be liable for any special, incidental, punitive, indirect, or consequential damages whatsoever (including, but not limited to, damages for loss of profit
+s, LOSS OF DATA, or confidential or other information}{\b\f39\fs22\insrsid9786739 , }{\b\caps\f39\fs22\insrsid9786739 
+for business interruption, for personal injury, for loss of privacy, for failure to meet any duty including of good faith or of reasonable care, for negligence, and}{\b\f39\fs22\insrsid9786739  }{\b\caps\f39\fs22\insrsid9786739 
+for any other pecuniary or other los
+s whatsoever) arising out of or in any way related to the use of or inability to use the SOFTWARE, the provision of or failure to provide Support OR OTHER Services, informatIon, software, and related CONTENT through the software or otherwise arising out o
+f
+ the use of the software, or otherwise under or in connection with any provision of this EULA, even in the event of the fault, tort (including negligence), misrepresentation, strict liability, breach of contract or breach of warranty of Microsoft or any s
+upplier, and even if Microsoft or any supplier has been advised of the possibility of such damages. }{\insrsid9786739 
+\par }{\f39\fs22\insrsid9786739 1}{\f39\fs22\insrsid14113652 2}{\f39\fs22\insrsid9786739 .}{\b\f39\fs22\insrsid9786739 \~\~\~\~\~\~ }{\b\f39\fs22\ul\insrsid9786739 LIMITATION OF LIABILITY AND REMEDIES}{\b\f39\fs22\insrsid9786739 
+. NOTWITHSTANDING ANY DAMAGES THAT YOU MIGHT INCUR FOR ANY REASON WHATSOEVER (INCLUDING, WITHOUT LIMITATION, A
+LL DAMAGES REFERENCED HEREIN AND ALL DIRECT OR GENERAL DAMAGES IN CONTRACT OR ANYTHING ELSE), THE ENTIRE LIABILITY OF MICROSOFT AND ANY OF ITS SUPPLIERS UNDER ANY PROVISION OF THIS EULA AND YOUR EXCLUSIVE REMEDY HEREUNDER SHALL BE LIMITED TO THE GREATER O
+F THE ACTUAL DAMAGES YOU INCUR IN REASONABLE RELIANCE ON THE SOFTWARE UP TO THE AMOUNT ACTUALLY PAID BY YOU FOR THE SOFTWARE}{\f39\fs22\insrsid9786739  }{\b\f39\fs22\insrsid9786739 OR US$5.00.\~
+ THE FOREGOING LIMITATIONS, EXCLUSIONS AND DISCLAIMERS SHALL APPLY TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, EVEN IF ANY REMEDY FAILS ITS ESSENTIAL PURPOSE.}{\insrsid9786739 
+\par }{\f39\fs22\insrsid9786739 1}{\f39\fs22\insrsid14113652 3}{\f39\fs22\insrsid9786739 .\~\~\~\~\~\~ }{\b\f39\fs22\insrsid9786739 APPLICABLE LAW.\~ }{\f39\fs22\insrsid7735936 T}{\f39\fs22\insrsid9786739 his EULA }{\f39\fs22\insrsid7735936 
+shall be construed under and }{\f39\fs22\insrsid9786739 governed by the laws of the State of Washington}{\f39\fs22\insrsid7735936 , without regard to conflicts of law principles}{\f39\fs22\insrsid9786739 .\~ }{\insrsid9786739 
+\par }\pard\plain \s20\qj \li0\ri0\sb100\sa100\sbauto1\saauto1\sl240\slmult0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14100361 \f40\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f39\insrsid9786739 1}{\f39\insrsid14113652 
+4}{\f39\insrsid9786739 .\~\~\~\~ }{\b\f39\insrsid9786739 ENTIRE AGREEMENT; SEVERABILITY.\~ }{\f39\insrsid9786739 This 
+EULA (including any addendum or amendment to this EULA which is included with the Software) are the entire agreement between you and Microsoft relating to the Software and the support services (if any) and they supersede all prior or contemporaneous oral 
+or written communications,\~proposals and representations with respect to the Software or any other subject matter covered by this EULA.\~
+ If any provision of this EULA is held to be void, invalid, unenforceable or illegal, the other provisions shall continue in full force and effect}{\insrsid9786739 
+\par }\pard\plain \qj \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14100361 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\insrsid10440675 
+\par }}
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Tools/ILMerge/ILMerge.doc b/trunk/Libraries/Json40r2/Source/Tools/ILMerge/ILMerge.doc
new file mode 100644 (file)
index 0000000..1b85114
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/ILMerge/ILMerge.doc differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/NUnitFitTests.html b/trunk/Libraries/Json40r2/Source/Tools/NUnit/NUnitFitTests.html
new file mode 100644 (file)
index 0000000..ca5cd4f
--- /dev/null
@@ -0,0 +1,277 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+       <body>
+               <h1>NUnit Acceptance Tests</h1>
+               <p>
+               Developers love self-referential programs! Hence, NUnit has always run all it's 
+               own tests, even those that are not really unit tests.
+               <p>Now, beginning with NUnit 2.4, NUnit has top-level tests using Ward Cunningham's 
+                       FIT framework. At this time, the tests are pretty rudimentary, but it's a start 
+                       and it's a framework for doing more.
+                       <h2>Running the Tests</h2>
+               <p>Open a console or shell window and navigate to the NUnit bin directory, which 
+                       contains this file. To run the test under Microsoft .Net, enter the command
+                       <pre>    runFile NUnitFitTests.html TestResults.html .</pre>
+                       To run it under Mono, enter
+                       <pre>    mono runFile.exe NUnitFitTests.html TestResults.html .</pre>
+                       Note the space and dot at the end of each command. The results of your test 
+                       will be in TestResults.html in the same directory.
+                       <h2>Platform and CLR Version</h2>
+                       <table BORDER cellSpacing="0" cellPadding="5">
+                               <tr>
+                                       <td colspan="2">NUnit.Fixtures.PlatformInfo</td>
+                               </tr>
+                       </table>
+                       <h2>Verify Unit Tests</h2>
+               <p>
+               Load and run the NUnit unit tests, verifying that the results are as expected. 
+               When these tests are run on different platforms, different numbers of tests may 
+               be skipped, so the values for Skipped and Run tests are informational only.
+               <p>
+               The number of tests in each assembly should be constant across all platforms - 
+               any discrepancy usually means that one of the test source files was not 
+               compiled on the platform. There should be no failures and no tests ignored.
+               <p><b>Note:</b>
+               At the moment, the nunit.extensions.tests assembly is failing because the 
+               fixture doesn't initialize addins in the test domain.
+               <p>
+                       <table BORDER cellSpacing="0" cellPadding="5">
+                               <tr>
+                                       <td colspan="6">NUnit.Fixtures.AssemblyRunner</td>
+                               </tr>
+                               <tr>
+                                       <td>Assembly</td>
+                                       <td>Tests()</td>
+                                       <td>Run()</td>
+                                       <td>Skipped()</td>
+                                       <td>Ignored()</td>
+                                       <td>Failures()</td>
+                               </tr>
+                               <tr>
+                                       <td>nunit.framework.tests.dll</td>
+                                       <td>397</td>
+                                       <td>&nbsp;</td>
+                                       <td>&nbsp;</td>
+                                       <td>0</td>
+                                       <td>0</td>
+                               </tr>
+                               <tr>
+                                       <td>nunit.core.tests.dll</td>
+                                       <td>355</td>
+                                       <td>&nbsp;</td>
+                                       <td>&nbsp;</td>
+                                       <td>0</td>
+                                       <td>0</td>
+                               </tr>
+                               <tr>
+                                       <td>nunit.util.tests.dll</td>
+                                       <td>238</td>
+                                       <td>&nbsp;</td>
+                                       <td>&nbsp;</td>
+                                       <td>0</td>
+                                       <td>0</td>
+                               </tr>
+                               <tr>
+                                       <td>nunit.mocks.tests.dll</td>
+                                       <td>43</td>
+                                       <td>&nbsp;</td>
+                                       <td>&nbsp;</td>
+                                       <td>0</td>
+                                       <td>0</td>
+                               </tr>
+                               <tr>
+                                       <td>nunit.extensions.tests.dll</td>
+                                       <td>5</td>
+                                       <td>&nbsp;</td>
+                                       <td>&nbsp;</td>
+                                       <td>0</td>
+                                       <td>0</td>
+                               </tr>
+                               <tr>
+                                       <td>nunit-console.tests.dll</td>
+                                       <td>40</td>
+                                       <td>&nbsp;</td>
+                                       <td>&nbsp;</td>
+                                       <td>0</td>
+                                       <td>0</td>
+                               </tr>
+                               <tr>
+                                       <td>nunit.uikit.tests.dll</td>
+                                       <td>34</td>
+                                       <td>&nbsp;</td>
+                                       <td>&nbsp;</td>
+                                       <td>0</td>
+                                       <td>0</td>
+                               </tr>
+                               <tr>
+                                       <td>nunit-gui.tests.dll</td>
+                                       <td>15</td>
+                                       <td>&nbsp;</td>
+                                       <td>&nbsp;</td>
+                                       <td>0</td>
+                                       <td>0</td>
+                               </tr>
+                               <tr>
+                                       <td>nunit.fixtures.tests.dll</td>
+                                       <td>6</td>
+                                       <td>&nbsp;</td>
+                                       <td>&nbsp;</td>
+                                       <td>0</td>
+                                       <td>0</td>
+                               </tr>
+                       </table>
+                       <h2>Code Snippet Tests</h2>
+               <p>
+               These tests create a test assembly from a snippet of code and then load and run 
+               the tests that it contains, verifying that the structure of the loaded tests is 
+               as expected and that the number of tests run, skipped, ignored or failed is 
+               correct.
+               <p>
+                       <table BORDER cellSpacing="0" cellPadding="5">
+                               <tr>
+                                       <td colspan="6">NUnit.Fixtures.SnippetRunner</td>
+                               </tr>
+                               <tr>
+                                       <td>Code</td>
+                                       <td>Tree()</td>
+                                       <td>Run()</td>
+                                       <td>Skipped()</td>
+                                       <td>Ignored()</td>
+                                       <td>Failures()</td>
+                               </tr>
+                               <tr>
+                                       <td><pre>public class TestClass
+{
+}</pre>
+                                       </td>
+                                       <td>EMPTY</td>
+                                       <td>0</td>
+                                       <td>0</td>
+                                       <td>0</td>
+                                       <td>0</td>
+                               </tr>
+                               <tr>
+                                       <td><pre>using NUnit.Framework;
+
+[TestFixture]
+public class TestClass
+{
+}</pre>
+                                       </td>
+                                       <td>TestClass</td>
+                                       <td>0</td>
+                                       <td>0</td>
+                                       <td>0</td>
+                                       <td>0</td>
+                               </tr>
+                               <tr>
+                                       <td><pre>using NUnit.Framework;
+
+[TestFixture]
+public class TestClass
+{
+    [Test]
+    public void T1() { }
+    [Test]
+    public void T2() { }
+    [Test]
+    public void T3() { }
+}</pre>
+                                       </td>
+                                       <td><pre>TestClass
+&gt;T1
+&gt;T2
+&gt;T3</pre>
+                                       </td>
+                                       <td>3</td>
+                                       <td>0</td>
+                                       <td>0</td>
+                                       <td>0</td>
+                               </tr>
+                               <tr>
+                                       <td><pre>using NUnit.Framework;
+
+[TestFixture]
+public class TestClass1
+{
+    [Test]
+    public void T1() { }
+}
+
+[TestFixture]
+public class TestClass2
+{
+    [Test]
+    public void T2() { }
+    [Test]
+    public void T3() { }
+}</pre>
+                                       </td>
+                                       <td><pre>TestClass1
+&gt;T1
+TestClass2
+&gt;T2
+&gt;T3</pre>
+                                       </td>
+                                       <td>3</td>
+                                       <td>0</td>
+                                       <td>0</td>
+                                       <td>0</td>
+                               </tr>
+                               <tr>
+                                       <td><pre>using NUnit.Framework;
+
+[TestFixture]
+public class TestClass
+{
+    [Test]
+    public void T1() { }
+    [Test, Ignore]
+    public void T2() { }
+    [Test]
+    public void T3() { }
+}</pre>
+                                       </td>
+                                       <td><pre>TestClass
+&gt;T1
+&gt;T2
+&gt;T3</pre>
+                                       </td>
+                                       <td>2</td>
+                                       <td>0</td>
+                                       <td>1</td>
+                                       <td>0</td>
+                               </tr>
+                               <tr>
+                                       <td><pre>using NUnit.Framework;
+
+[TestFixture]
+public class TestClass
+{
+    [Test]
+    public void T1() { }
+    [Test, Explicit]
+    public void T2() { }
+    [Test]
+    public void T3() { }
+}</pre>
+                                       </td>
+                                       <td><pre>TestClass
+&gt;T1
+&gt;T2
+&gt;T3</pre>
+                                       </td>
+                                       <td>2</td>
+                                       <td>1</td>
+                                       <td>0</td>
+                                       <td>0</td>
+                               </tr>
+                       </table>
+                       <h2>Summary Information</h2>
+                       <table BORDER cellSpacing="0" cellPadding="5">
+                               <tr>
+                                       <td colspan="2">fit.Summary</td>
+                               </tr>
+                       </table>
+       </body>
+</html>
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/NUnitTests.config b/trunk/Libraries/Json40r2/Source/Tools/NUnit/NUnitTests.config
new file mode 100644 (file)
index 0000000..de8a656
--- /dev/null
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+<!--
+        This is the configuration file for the NUnitTests.nunit test project. You may
+        need to create a similar configuration file for your own test project. 
+ -->    
+
+<!--
+        The <NUnit> section is only needed if you want to use a non-default value
+        for any of the settings. It is commented out below. If you are going to use
+   it, you must deifne the NUnit section group and the sections you need.
+   The syntax shown here works for most runtimes. If NUnit fails at startup, you
+   can try specifying the name of the assembly containing the NameValueSectionHandler:
+   
+      <section name="TestCaseBuilder" type="System.Configuration.NameValueSectionHandler, System" />
+      
+   If that fails, try the fully qualified name of the assembly:
+   
+      <section name="TestCaseBuilder" type="System.Configuration.NameValueSectionHandler, System, 
+             Version=2.0.50727.832, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+             
+   Unfortunately, this last approach makes your config file non-portable across runtimes.
+   -->
+
+<!--
+  <configSections>
+               <sectionGroup name="NUnit">
+                       <section name="TestCaseBuilder" type="System.Configuration.NameValueSectionHandler"/>
+                       <section name="TestRunner" type="System.Configuration.NameValueSectionHandler"/>
+               </sectionGroup>
+       </configSections>
+ -->
+
+  <appSettings>
+               <!--   User application and configured property settings go here.-->
+               <!--   Example: <add key="settingName" value="settingValue"/> -->
+               <add key="test.setting" value="54321" />
+       </appSettings>
+
+<!-- Sample NUnit section group showing all default values -->
+<!--
+       <NUnit>
+               <TestCaseBuilder>
+                       <add key="OldStyleTestCases" value="false" />
+               </TestCaseBuilder>
+               <TestRunner>
+                       <add key="ApartmentState" value="MTA" />
+                       <add key="ThreadPriority" value="Normal" />
+               </TestRunner>
+       </NUnit>
+-->
+  
+   <!--
+    The following <runtime> section allows running nunit tests under 
+    .NET 1.0 by redirecting assemblies. The appliesTo attribute
+    causes the section to be ignored except under .NET 1.0.
+   --> 
+       <runtime>
+               <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"
+                               appliesTo="v1.0.3705">
+                       <dependentAssembly>
+                               <assemblyIdentity name="System" publicKeyToken="b77a5c561934e089" culture="" />
+                               <bindingRedirect oldVersion="1.0.5000.0" newVersion="1.0.3300.0" />
+                       </dependentAssembly>
+                       <dependentAssembly>
+                               <assemblyIdentity name="System.Data" publicKeyToken="b77a5c561934e089" culture="" />
+                               <bindingRedirect oldVersion="1.0.5000.0" newVersion="1.0.3300.0" />
+                       </dependentAssembly>
+                       <dependentAssembly>
+                               <assemblyIdentity name="System.Drawing" publicKeyToken="b03f5f7f11d50a3a" culture="" />
+                               <bindingRedirect oldVersion="1.0.5000.0" newVersion="1.0.3300.0" />
+                       </dependentAssembly>
+                       <dependentAssembly>
+                               <assemblyIdentity name="System.Windows.Forms" publicKeyToken="b77a5c561934e089" culture="" />
+                               <bindingRedirect oldVersion="1.0.5000.0" newVersion="1.0.3300.0" />
+                       </dependentAssembly>
+                       <dependentAssembly>
+                               <assemblyIdentity name="System.Xml" publicKeyToken="b77a5c561934e089" culture="" />
+                               <bindingRedirect oldVersion="1.0.5000.0" newVersion="1.0.3300.0" />
+                       </dependentAssembly>
+               </assemblyBinding>
+       </runtime>
+</configuration> 
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/NUnitTests.nunit b/trunk/Libraries/Json40r2/Source/Tools/NUnit/NUnitTests.nunit
new file mode 100644 (file)
index 0000000..e7bb7f4
--- /dev/null
@@ -0,0 +1,14 @@
+<NUnitProject>
+  <Settings appbase="."/>
+  <Config name="Default" binpath="lib;tests;framework" runtimeFramework="v2.0">
+    <assembly path="tests/nunit.framework.tests.dll" />
+    <assembly path="tests/nunit.core.tests.dll" />
+    <assembly path="tests/nunit.util.tests.dll" />
+    <assembly path="tests/nunit.mocks.tests.dll" />
+    <assembly path="tests/nunit-console.tests.dll" />
+    <assembly path="tests/nunit.uiexception.tests.dll" />
+    <assembly path="tests/nunit.uikit.tests.dll" />
+    <assembly path="tests/nunit-gui.tests.dll" />
+    <assembly path="tests/nunit.fixtures.tests.dll" />
+  </Config>
+</NUnitProject>
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/agent.conf b/trunk/Libraries/Json40r2/Source/Tools/NUnit/agent.conf
new file mode 100644 (file)
index 0000000..ddbcd8e
--- /dev/null
@@ -0,0 +1,4 @@
+<AgentConfig>
+  <Port>8080</Port>
+  <PathToAssemblies>.</PathToAssemblies>
+</AgentConfig>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/agent.log.conf b/trunk/Libraries/Json40r2/Source/Tools/NUnit/agent.log.conf
new file mode 100644 (file)
index 0000000..4bd90ca
--- /dev/null
@@ -0,0 +1,18 @@
+<log4net>
+       <!-- A1 is set to be a ConsoleAppender -->
+       <appender name="A1" type="log4net.Appender.ConsoleAppender">
+
+               <!-- A1 uses PatternLayout -->
+               <layout type="log4net.Layout.PatternLayout">
+                       <!-- Print the date in ISO 8601 format -->
+                       <conversionPattern value="%-5level %logger - %message%newline" />
+               </layout>
+       </appender>
+       
+       <!-- Set root logger level to DEBUG and its only appender to A1 -->
+       <root>
+               <level value="DEBUG" />
+               <appender-ref ref="A1" />
+       </root>
+
+</log4net>
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/framework/nunit.framework.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/framework/nunit.framework.dll
new file mode 100644 (file)
index 0000000..639dbb0
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/framework/nunit.framework.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/framework/nunit.framework.xml b/trunk/Libraries/Json40r2/Source/Tools/NUnit/framework/nunit.framework.xml
new file mode 100644 (file)
index 0000000..e67b2cd
--- /dev/null
@@ -0,0 +1,10228 @@
+<?xml version="1.0"?>
+<doc>
+    <assembly>
+        <name>nunit.framework</name>
+    </assembly>
+    <members>
+        <member name="T:NUnit.Framework.Constraints.BinaryConstraint">
+            <summary>
+            BinaryConstraint is the abstract base of all constraints
+            that combine two other constraints in some fashion.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.Constraint">
+            <summary>
+            The Constraint class is the base of all built-in constraints
+            within NUnit. It provides the operator overloads used to combine 
+            constraints.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.IResolveConstraint">
+            <summary>
+            The IConstraintExpression interface is implemented by all
+            complete and resolvable constraints and expressions.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.IResolveConstraint.Resolve">
+            <summary>
+            Return the top-level constraint for this expression
+            </summary>
+            <returns></returns>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.Constraint.UNSET">
+            <summary>
+            Static UnsetObject used to detect derived constraints
+            failing to set the actual value.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.Constraint.actual">
+            <summary>
+            The actual value being tested against a constraint
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.Constraint.displayName">
+            <summary>
+            The display name of this Constraint for use by ToString()
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.Constraint.argcnt">
+            <summary>
+            Argument fields used by ToString();
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.Constraint.builder">
+            <summary>
+            The builder holding this constraint
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Constraint.#ctor">
+            <summary>
+            Construct a constraint with no arguments
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Constraint.#ctor(System.Object)">
+            <summary>
+            Construct a constraint with one argument
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Constraint.#ctor(System.Object,System.Object)">
+            <summary>
+            Construct a constraint with two arguments
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Constraint.SetBuilder(NUnit.Framework.Constraints.ConstraintBuilder)">
+            <summary>
+            Sets the ConstraintBuilder holding this constraint
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Constraint.WriteMessageTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the failure message to the MessageWriter provided
+            as an argument. The default implementation simply passes
+            the constraint and the actual value to the writer, which
+            then displays the constraint description and the value.
+            
+            Constraints that need to provide additional details,
+            such as where the error occured can override this.
+            </summary>
+            <param name="writer">The MessageWriter on which to display the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Constraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Constraint.Matches(NUnit.Framework.Constraints.ActualValueDelegate)">
+            <summary>
+            Test whether the constraint is satisfied by an
+            ActualValueDelegate that returns the value to be tested.
+            The default implementation simply evaluates the delegate
+            but derived classes may override it to provide for delayed 
+            processing.
+            </summary>
+            <param name="del">An ActualValueDelegate</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Constraint.Matches``1(``0@)">
+            <summary>
+            Test whether the constraint is satisfied by a given reference.
+            The default implementation simply dereferences the value but
+            derived classes may override it to provide for delayed processing.
+            </summary>
+            <param name="actual">A reference to the value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Constraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Constraint.WriteActualValueTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the actual value for a failing constraint test to a
+            MessageWriter. The default implementation simply writes
+            the raw value of actual, leaving it to the writer to
+            perform any formatting.
+            </summary>
+            <param name="writer">The writer on which the actual value is displayed</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Constraint.ToString">
+            <summary>
+            Default override of ToString returns the constraint DisplayName
+            followed by any arguments within angle brackets.
+            </summary>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Constraint.GetStringRepresentation">
+            <summary>
+            Returns the string representation of this constraint
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Constraint.op_BitwiseAnd(NUnit.Framework.Constraints.Constraint,NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            This operator creates a constraint that is satisfied only if both 
+            argument constraints are satisfied.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Constraint.op_BitwiseOr(NUnit.Framework.Constraints.Constraint,NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            This operator creates a constraint that is satisfied if either 
+            of the argument constraints is satisfied.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Constraint.op_LogicalNot(NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            This operator creates a constraint that is satisfied if the 
+            argument constraint is not satisfied.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Constraint.After(System.Int32)">
+            <summary>
+            Returns a DelayedConstraint with the specified delay time.
+            </summary>
+            <param name="delayInMilliseconds">The delay in milliseconds.</param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Constraint.After(System.Int32,System.Int32)">
+            <summary>
+            Returns a DelayedConstraint with the specified delay time
+            and polling interval.
+            </summary>
+            <param name="delayInMilliseconds">The delay in milliseconds.</param>
+            <param name="pollingInterval">The interval at which to test the constraint.</param>
+            <returns></returns>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.Constraint.DisplayName">
+            <summary>
+            The display name of this Constraint for use by ToString().
+            The default value is the name of the constraint with
+            trailing "Constraint" removed. Derived classes may set
+            this to another name in their constructors.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.Constraint.And">
+            <summary>
+            Returns a ConstraintExpression by appending And
+            to the current constraint.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.Constraint.With">
+            <summary>
+            Returns a ConstraintExpression by appending And
+            to the current constraint.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.Constraint.Or">
+            <summary>
+            Returns a ConstraintExpression by appending Or
+            to the current constraint.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.Constraint.UnsetObject">
+            <summary>
+            Class used to detect any derived constraints
+            that fail to set the actual value in their
+            Matches override.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.BinaryConstraint.left">
+            <summary>
+            The first constraint being combined
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.BinaryConstraint.right">
+            <summary>
+            The second constraint being combined
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.BinaryConstraint.#ctor(NUnit.Framework.Constraints.Constraint,NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Construct a BinaryConstraint from two other constraints
+            </summary>
+            <param name="left">The first constraint</param>
+            <param name="right">The second constraint</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.AndConstraint">
+            <summary>
+            AndConstraint succeeds only if both members succeed.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AndConstraint.#ctor(NUnit.Framework.Constraints.Constraint,NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Create an AndConstraint from two other constraints
+            </summary>
+            <param name="left">The first constraint</param>
+            <param name="right">The second constraint</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AndConstraint.Matches(System.Object)">
+            <summary>
+            Apply both member constraints to an actual value, succeeding 
+            succeeding only if both of them succeed.
+            </summary>
+            <param name="actual">The actual value</param>
+            <returns>True if the constraints both succeeded</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AndConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write a description for this contraint to a MessageWriter
+            </summary>
+            <param name="writer">The MessageWriter to receive the description</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AndConstraint.WriteActualValueTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the actual value for a failing constraint test to a
+            MessageWriter. The default implementation simply writes
+            the raw value of actual, leaving it to the writer to
+            perform any formatting.
+            </summary>
+            <param name="writer">The writer on which the actual value is displayed</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.OrConstraint">
+            <summary>
+            OrConstraint succeeds if either member succeeds
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.OrConstraint.#ctor(NUnit.Framework.Constraints.Constraint,NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Create an OrConstraint from two other constraints
+            </summary>
+            <param name="left">The first constraint</param>
+            <param name="right">The second constraint</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.OrConstraint.Matches(System.Object)">
+            <summary>
+            Apply the member constraints to an actual value, succeeding 
+            succeeding as soon as one of them succeeds.
+            </summary>
+            <param name="actual">The actual value</param>
+            <returns>True if either constraint succeeded</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.OrConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write a description for this contraint to a MessageWriter
+            </summary>
+            <param name="writer">The MessageWriter to receive the description</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.CollectionConstraint">
+            <summary>
+            CollectionConstraint is the abstract base class for
+            constraints that operate on collections.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionConstraint.#ctor">
+            <summary>
+            Construct an empty CollectionConstraint
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionConstraint.#ctor(System.Object)">
+            <summary>
+            Construct a CollectionConstraint
+            </summary>
+            <param name="arg"></param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionConstraint.IsEmpty(System.Collections.IEnumerable)">
+            <summary>
+            Determines whether the specified enumerable is empty.
+            </summary>
+            <param name="enumerable">The enumerable.</param>
+            <returns>
+               <c>true</c> if the specified enumerable is empty; otherwise, <c>false</c>.
+            </returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionConstraint.doMatch(System.Collections.IEnumerable)">
+            <summary>
+            Protected method to be implemented by derived classes
+            </summary>
+            <param name="collection"></param>
+            <returns></returns>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.CollectionItemsEqualConstraint">
+            <summary>
+            CollectionItemsEqualConstraint is the abstract base class for all
+            collection constraints that apply some notion of item equality
+            as a part of their operation.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionItemsEqualConstraint.#ctor">
+            <summary>
+            Construct an empty CollectionConstraint
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionItemsEqualConstraint.#ctor(System.Object)">
+            <summary>
+            Construct a CollectionConstraint
+            </summary>
+            <param name="arg"></param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionItemsEqualConstraint.Using(System.Collections.IComparer)">
+            <summary>
+            Flag the constraint to use the supplied IComparer object.
+            </summary>
+            <param name="comparer">The IComparer object to use.</param>
+            <returns>Self.</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionItemsEqualConstraint.Using``1(System.Collections.Generic.IComparer{``0})">
+            <summary>
+            Flag the constraint to use the supplied IComparer object.
+            </summary>
+            <param name="comparer">The IComparer object to use.</param>
+            <returns>Self.</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionItemsEqualConstraint.Using``1(System.Comparison{``0})">
+            <summary>
+            Flag the constraint to use the supplied Comparison object.
+            </summary>
+            <param name="comparer">The IComparer object to use.</param>
+            <returns>Self.</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionItemsEqualConstraint.Using(System.Collections.IEqualityComparer)">
+            <summary>
+            Flag the constraint to use the supplied IEqualityComparer object.
+            </summary>
+            <param name="comparer">The IComparer object to use.</param>
+            <returns>Self.</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionItemsEqualConstraint.Using``1(System.Collections.Generic.IEqualityComparer{``0})">
+            <summary>
+            Flag the constraint to use the supplied IEqualityComparer object.
+            </summary>
+            <param name="comparer">The IComparer object to use.</param>
+            <returns>Self.</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionItemsEqualConstraint.ItemsEqual(System.Object,System.Object)">
+            <summary>
+            Compares two collection members for equality
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionItemsEqualConstraint.Tally(System.Collections.IEnumerable)">
+            <summary>
+            Return a new CollectionTally for use in making tests
+            </summary>
+            <param name="c">The collection to be included in the tally</param>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.CollectionItemsEqualConstraint.IgnoreCase">
+            <summary>
+            Flag the constraint to ignore case and return self.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.EmptyCollectionConstraint">
+            <summary>
+            EmptyCollectionConstraint tests whether a collection is empty. 
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EmptyCollectionConstraint.doMatch(System.Collections.IEnumerable)">
+            <summary>
+            Check that the collection is empty
+            </summary>
+            <param name="collection"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EmptyCollectionConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer"></param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.UniqueItemsConstraint">
+            <summary>
+            UniqueItemsConstraint tests whether all the items in a 
+            collection are unique.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.UniqueItemsConstraint.doMatch(System.Collections.IEnumerable)">
+            <summary>
+            Check that all items are unique.
+            </summary>
+            <param name="actual"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.UniqueItemsConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write a description of this constraint to a MessageWriter
+            </summary>
+            <param name="writer"></param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.CollectionContainsConstraint">
+            <summary>
+            CollectionContainsConstraint is used to test whether a collection
+            contains an expected object as a member.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionContainsConstraint.#ctor(System.Object)">
+            <summary>
+            Construct a CollectionContainsConstraint
+            </summary>
+            <param name="expected"></param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionContainsConstraint.doMatch(System.Collections.IEnumerable)">
+            <summary>
+            Test whether the expected item is contained in the collection
+            </summary>
+            <param name="actual"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionContainsConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write a descripton of the constraint to a MessageWriter
+            </summary>
+            <param name="writer"></param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.CollectionEquivalentConstraint">
+            <summary>
+            CollectionEquivalentCOnstraint is used to determine whether two
+            collections are equivalent.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionEquivalentConstraint.#ctor(System.Collections.IEnumerable)">
+            <summary>
+            Construct a CollectionEquivalentConstraint
+            </summary>
+            <param name="expected"></param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionEquivalentConstraint.doMatch(System.Collections.IEnumerable)">
+            <summary>
+            Test whether two collections are equivalent
+            </summary>
+            <param name="actual"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionEquivalentConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write a description of this constraint to a MessageWriter
+            </summary>
+            <param name="writer"></param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.CollectionSubsetConstraint">
+            <summary>
+            CollectionSubsetConstraint is used to determine whether
+            one collection is a subset of another
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionSubsetConstraint.#ctor(System.Collections.IEnumerable)">
+            <summary>
+            Construct a CollectionSubsetConstraint
+            </summary>
+            <param name="expected">The collection that the actual value is expected to be a subset of</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionSubsetConstraint.doMatch(System.Collections.IEnumerable)">
+            <summary>
+            Test whether the actual collection is a subset of 
+            the expected collection provided.
+            </summary>
+            <param name="actual"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionSubsetConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write a description of this constraint to a MessageWriter
+            </summary>
+            <param name="writer"></param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.CollectionOrderedConstraint">
+            <summary>
+            CollectionOrderedConstraint is used to test whether a collection is ordered.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionOrderedConstraint.#ctor">
+            <summary>
+            Construct a CollectionOrderedConstraint
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionOrderedConstraint.Using(System.Collections.IComparer)">
+            <summary>
+            Modifies the constraint to use an IComparer and returns self.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionOrderedConstraint.Using``1(System.Collections.Generic.IComparer{``0})">
+            <summary>
+            Modifies the constraint to use an IComparer&lt;T&gt; and returns self.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionOrderedConstraint.Using``1(System.Comparison{``0})">
+            <summary>
+            Modifies the constraint to use a Comparison&lt;T&gt; and returns self.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionOrderedConstraint.By(System.String)">
+            <summary>
+            Modifies the constraint to test ordering by the value of
+            a specified property and returns self.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionOrderedConstraint.doMatch(System.Collections.IEnumerable)">
+            <summary>
+            Test whether the collection is ordered
+            </summary>
+            <param name="actual"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionOrderedConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write a description of the constraint to a MessageWriter
+            </summary>
+            <param name="writer"></param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionOrderedConstraint.GetStringRepresentation">
+            <summary>
+            Returns the string representation of the constraint.
+            </summary>
+            <returns></returns>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.CollectionOrderedConstraint.Descending">
+            <summary>
+             If used performs a reverse comparison
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.ComparisonConstraint">
+            <summary>
+            Abstract base class for constraints that compare values to
+            determine if one is greater than, equal to or less than
+            the other.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.ComparisonConstraint.expected">
+            <summary>
+            The value against which a comparison is to be made
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.ComparisonConstraint.ltOK">
+            <summary>
+            If true, less than returns success
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.ComparisonConstraint.eqOK">
+            <summary>
+            if true, equal returns success
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.ComparisonConstraint.gtOK">
+            <summary>
+            if true, greater than returns success
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.ComparisonConstraint.predicate">
+            <summary>
+            The predicate used as a part of the description
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.ComparisonConstraint.comparer">
+            <summary>
+            ComparisonAdapter to be used in making the comparison
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ComparisonConstraint.#ctor(System.Object,System.Boolean,System.Boolean,System.Boolean,System.String)">
+            <summary>
+            Initializes a new instance of the <see cref="T:ComparisonConstraint"/> class.
+            </summary>
+            <param name="value">The value against which to make a comparison.</param>
+            <param name="ltOK">if set to <c>true</c> less succeeds.</param>
+            <param name="eqOK">if set to <c>true</c> equal succeeds.</param>
+            <param name="gtOK">if set to <c>true</c> greater succeeds.</param>
+            <param name="predicate">String used in describing the constraint.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ComparisonConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ComparisonConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ComparisonConstraint.Using(System.Collections.IComparer)">
+            <summary>
+            Modifies the constraint to use an IComparer and returns self
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ComparisonConstraint.Using``1(System.Collections.Generic.IComparer{``0})">
+            <summary>
+            Modifies the constraint to use an IComparer&lt;T&gt; and returns self
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ComparisonConstraint.Using``1(System.Comparison{``0})">
+            <summary>
+            Modifies the constraint to use a Comparison&lt;T&gt; and returns self
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.GreaterThanConstraint">
+            <summary>
+            Tests whether a value is greater than the value supplied to its constructor
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.GreaterThanConstraint.#ctor(System.Object)">
+            <summary>
+            Initializes a new instance of the <see cref="T:GreaterThanConstraint"/> class.
+            </summary>
+            <param name="expected">The expected value.</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.GreaterThanOrEqualConstraint">
+            <summary>
+            Tests whether a value is greater than or equal to the value supplied to its constructor
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.GreaterThanOrEqualConstraint.#ctor(System.Object)">
+            <summary>
+            Initializes a new instance of the <see cref="T:GreaterThanOrEqualConstraint"/> class.
+            </summary>
+            <param name="expected">The expected value.</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.LessThanConstraint">
+            <summary>
+            Tests whether a value is less than the value supplied to its constructor
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.LessThanConstraint.#ctor(System.Object)">
+            <summary>
+            Initializes a new instance of the <see cref="T:LessThanConstraint"/> class.
+            </summary>
+            <param name="expected">The expected value.</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.LessThanOrEqualConstraint">
+            <summary>
+            Tests whether a value is less than or equal to the value supplied to its constructor
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.LessThanOrEqualConstraint.#ctor(System.Object)">
+            <summary>
+            Initializes a new instance of the <see cref="T:LessThanOrEqualConstraint"/> class.
+            </summary>
+            <param name="expected">The expected value.</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.ActualValueDelegate">
+            <summary>
+            Delegate used to delay evaluation of the actual value
+            to be used in evaluating a constraint
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.ConstraintBuilder">
+            <summary>
+            ConstraintBuilder maintains the stacks that are used in
+            processing a ConstraintExpression. An OperatorStack
+            is used to hold operators that are waiting for their
+            operands to be reognized. a ConstraintStack holds 
+            input constraints as well as the results of each
+            operator applied.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.#ctor">
+            <summary>
+            Initializes a new instance of the <see cref="T:ConstraintBuilder"/> class.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.Append(NUnit.Framework.Constraints.ConstraintOperator)">
+            <summary>
+            Appends the specified operator to the expression by first
+            reducing the operator stack and then pushing the new
+            operator on the stack.
+            </summary>
+            <param name="op">The operator to push.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.Append(NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Appends the specified constraint to the expresson by pushing
+            it on the constraint stack.
+            </summary>
+            <param name="constraint">The constraint to push.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.SetTopOperatorRightContext(System.Object)">
+            <summary>
+            Sets the top operator right context.
+            </summary>
+            <param name="rightContext">The right context.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.ReduceOperatorStack(System.Int32)">
+            <summary>
+            Reduces the operator stack until the topmost item
+            precedence is greater than or equal to the target precedence.
+            </summary>
+            <param name="targetPrecedence">The target precedence.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.Resolve">
+            <summary>
+            Resolves this instance, returning a Constraint. If the builder
+            is not currently in a resolvable state, an exception is thrown.
+            </summary>
+            <returns>The resolved constraint</returns>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintBuilder.IsResolvable">
+            <summary>
+            Gets a value indicating whether this instance is resolvable.
+            </summary>
+            <value>
+               <c>true</c> if this instance is resolvable; otherwise, <c>false</c>.
+            </value>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.ConstraintBuilder.OperatorStack">
+            <summary>
+            OperatorStack is a type-safe stack for holding ConstraintOperators
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.OperatorStack.#ctor(NUnit.Framework.Constraints.ConstraintBuilder)">
+            <summary>
+            Initializes a new instance of the <see cref="T:OperatorStack"/> class.
+            </summary>
+            <param name="builder">The builder.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.OperatorStack.Push(NUnit.Framework.Constraints.ConstraintOperator)">
+            <summary>
+            Pushes the specified operator onto the stack.
+            </summary>
+            <param name="op">The op.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.OperatorStack.Pop">
+            <summary>
+            Pops the topmost operator from the stack.
+            </summary>
+            <returns></returns>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintBuilder.OperatorStack.Empty">
+            <summary>
+            Gets a value indicating whether this <see cref="T:OpStack"/> is empty.
+            </summary>
+            <value><c>true</c> if empty; otherwise, <c>false</c>.</value>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintBuilder.OperatorStack.Top">
+            <summary>
+            Gets the topmost operator without modifying the stack.
+            </summary>
+            <value>The top.</value>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.ConstraintBuilder.ConstraintStack">
+            <summary>
+            ConstraintStack is a type-safe stack for holding Constraints
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.ConstraintStack.#ctor(NUnit.Framework.Constraints.ConstraintBuilder)">
+            <summary>
+            Initializes a new instance of the <see cref="T:ConstraintStack"/> class.
+            </summary>
+            <param name="builder">The builder.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.ConstraintStack.Push(NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Pushes the specified constraint. As a side effect,
+            the constraint's builder field is set to the 
+            ConstraintBuilder owning this stack.
+            </summary>
+            <param name="constraint">The constraint.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintBuilder.ConstraintStack.Pop">
+            <summary>
+            Pops this topmost constrait from the stack.
+            As a side effect, the constraint's builder
+            field is set to null.
+            </summary>
+            <returns></returns>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintBuilder.ConstraintStack.Empty">
+            <summary>
+            Gets a value indicating whether this <see cref="T:ConstraintStack"/> is empty.
+            </summary>
+            <value><c>true</c> if empty; otherwise, <c>false</c>.</value>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintBuilder.ConstraintStack.Top">
+            <summary>
+            Gets the topmost constraint without modifying the stack.
+            </summary>
+            <value>The topmost constraint</value>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.EmptyConstraint">
+            <summary>
+            EmptyConstraint tests a whether a string or collection is empty,
+            postponing the decision about which test is applied until the
+            type of the actual argument is known.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EmptyConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EmptyConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.EqualConstraint">
+            <summary>
+            EqualConstraint is able to compare an actual value with the
+            expected value provided in its constructor. Two objects are 
+            considered equal if both are null, or if both have the same 
+            value. NUnit has special semantics for some object types.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.EqualConstraint.clipStrings">
+            <summary>
+            If true, strings in error messages will be clipped
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.EqualConstraint.comparer">
+            <summary>
+            NUnitEqualityComparer used to test equality.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EqualConstraint.#ctor(System.Object)">
+            <summary>
+            Initializes a new instance of the <see cref="T:NUnit.Framework.Constraints.EqualConstraint"/> class.
+            </summary>
+            <param name="expected">The expected value.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EqualConstraint.Within(System.Object)">
+            <summary>
+            Flag the constraint to use a tolerance when determining equality.
+            </summary>
+            <param name="amount">Tolerance value to be used</param>
+            <returns>Self.</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EqualConstraint.Comparer(System.Collections.IComparer)">
+            <summary>
+            Flag the constraint to use the supplied IComparer object.
+            </summary>
+            <param name="comparer">The IComparer object to use.</param>
+            <returns>Self.</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EqualConstraint.Using(System.Collections.IComparer)">
+            <summary>
+            Flag the constraint to use the supplied IComparer object.
+            </summary>
+            <param name="comparer">The IComparer object to use.</param>
+            <returns>Self.</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EqualConstraint.Using``1(System.Collections.Generic.IComparer{``0})">
+            <summary>
+            Flag the constraint to use the supplied IComparer object.
+            </summary>
+            <param name="comparer">The IComparer object to use.</param>
+            <returns>Self.</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EqualConstraint.Using``1(System.Comparison{``0})">
+            <summary>
+            Flag the constraint to use the supplied Comparison object.
+            </summary>
+            <param name="comparer">The IComparer object to use.</param>
+            <returns>Self.</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EqualConstraint.Using(System.Collections.IEqualityComparer)">
+            <summary>
+            Flag the constraint to use the supplied IEqualityComparer object.
+            </summary>
+            <param name="comparer">The IComparer object to use.</param>
+            <returns>Self.</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EqualConstraint.Using``1(System.Collections.Generic.IEqualityComparer{``0})">
+            <summary>
+            Flag the constraint to use the supplied IEqualityComparer object.
+            </summary>
+            <param name="comparer">The IComparer object to use.</param>
+            <returns>Self.</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EqualConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EqualConstraint.WriteMessageTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write a failure message. Overridden to provide custom 
+            failure messages for EqualConstraint.
+            </summary>
+            <param name="writer">The MessageWriter to write to</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EqualConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write description of this constraint
+            </summary>
+            <param name="writer">The MessageWriter to write to</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EqualConstraint.DisplayCollectionDifferences(NUnit.Framework.Constraints.MessageWriter,System.Collections.ICollection,System.Collections.ICollection,System.Int32)">
+            <summary>
+            Display the failure information for two collections that did not match.
+            </summary>
+            <param name="writer">The MessageWriter on which to display</param>
+            <param name="expected">The expected collection.</param>
+            <param name="actual">The actual collection</param>
+            <param name="depth">The depth of this failure in a set of nested collections</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EqualConstraint.DisplayCollectionTypesAndSizes(NUnit.Framework.Constraints.MessageWriter,System.Collections.ICollection,System.Collections.ICollection,System.Int32)">
+            <summary>
+            Displays a single line showing the types and sizes of the expected
+            and actual collections or arrays. If both are identical, the value is 
+            only shown once.
+            </summary>
+            <param name="writer">The MessageWriter on which to display</param>
+            <param name="expected">The expected collection or array</param>
+            <param name="actual">The actual collection or array</param>
+            <param name="indent">The indentation level for the message line</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EqualConstraint.DisplayFailurePoint(NUnit.Framework.Constraints.MessageWriter,System.Collections.ICollection,System.Collections.ICollection,System.Int32,System.Int32)">
+            <summary>
+            Displays a single line showing the point in the expected and actual
+            arrays at which the comparison failed. If the arrays have different
+            structures or dimensions, both values are shown.
+            </summary>
+            <param name="writer">The MessageWriter on which to display</param>
+            <param name="expected">The expected array</param>
+            <param name="actual">The actual array</param>
+            <param name="failurePoint">Index of the failure point in the underlying collections</param>
+            <param name="indent">The indentation level for the message line</param>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.EqualConstraint.IgnoreCase">
+            <summary>
+            Flag the constraint to ignore case and return self.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.EqualConstraint.NoClip">
+            <summary>
+            Flag the constraint to suppress string clipping 
+            and return self.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.EqualConstraint.AsCollection">
+            <summary>
+            Flag the constraint to compare arrays as collections
+            and return self.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.EqualConstraint.Ulps">
+            <summary>
+            Switches the .Within() modifier to interpret its tolerance as
+            a distance in representable values (see remarks).
+            </summary>
+            <returns>Self.</returns>
+            <remarks>
+            Ulp stands for "unit in the last place" and describes the minimum
+            amount a given value can change. For any integers, an ulp is 1 whole
+            digit. For floating point values, the accuracy of which is better
+            for smaller numbers and worse for larger numbers, an ulp depends
+            on the size of the number. Using ulps for comparison of floating
+            point results instead of fixed tolerances is safer because it will
+            automatically compensate for the added inaccuracy of larger numbers.
+            </remarks>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.EqualConstraint.Percent">
+            <summary>
+            Switches the .Within() modifier to interpret its tolerance as
+            a percentage that the actual values is allowed to deviate from
+            the expected value.
+            </summary>
+            <returns>Self</returns>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.EqualConstraint.Days">
+            <summary>
+            Causes the tolerance to be interpreted as a TimeSpan in days.
+            </summary>
+            <returns>Self</returns>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.EqualConstraint.Hours">
+            <summary>
+            Causes the tolerance to be interpreted as a TimeSpan in hours.
+            </summary>
+            <returns>Self</returns>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.EqualConstraint.Minutes">
+            <summary>
+            Causes the tolerance to be interpreted as a TimeSpan in minutes.
+            </summary>
+            <returns>Self</returns>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.EqualConstraint.Seconds">
+            <summary>
+            Causes the tolerance to be interpreted as a TimeSpan in seconds.
+            </summary>
+            <returns>Self</returns>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.EqualConstraint.Milliseconds">
+            <summary>
+            Causes the tolerance to be interpreted as a TimeSpan in milliseconds.
+            </summary>
+            <returns>Self</returns>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.EqualConstraint.Ticks">
+            <summary>
+            Causes the tolerance to be interpreted as a TimeSpan in clock ticks.
+            </summary>
+            <returns>Self</returns>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.SameAsConstraint">
+            <summary>
+            SameAsConstraint tests whether an object is identical to
+            the object passed to its constructor
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.SameAsConstraint.#ctor(System.Object)">
+            <summary>
+            Initializes a new instance of the <see cref="T:SameAsConstraint"/> class.
+            </summary>
+            <param name="expected">The expected object.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.SameAsConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.SameAsConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.StringConstraint">
+            <summary>
+            StringConstraint is the abstract base for constraints
+            that operate on strings. It supports the IgnoreCase
+            modifier for string operations.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.StringConstraint.expected">
+            <summary>
+            The expected value
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.StringConstraint.caseInsensitive">
+            <summary>
+            Indicates whether tests should be case-insensitive
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.StringConstraint.#ctor(System.String)">
+            <summary>
+            Constructs a StringConstraint given an expected value
+            </summary>
+            <param name="expected">The expected value</param>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.StringConstraint.IgnoreCase">
+            <summary>
+            Modify the constraint to ignore case in matching.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.EmptyStringConstraint">
+            <summary>
+            EmptyStringConstraint tests whether a string is empty.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EmptyStringConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EmptyStringConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.NullOrEmptyStringConstraint">
+            <summary>
+            NullEmptyStringConstraint tests whether a string is either null or empty.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.NullOrEmptyStringConstraint.#ctor">
+            <summary>
+            Constructs a new NullOrEmptyStringConstraint
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.NullOrEmptyStringConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.NullOrEmptyStringConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.SubstringConstraint">
+            <summary>
+            SubstringConstraint can test whether a string contains
+            the expected substring.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.SubstringConstraint.#ctor(System.String)">
+            <summary>
+            Initializes a new instance of the <see cref="T:SubstringConstraint"/> class.
+            </summary>
+            <param name="expected">The expected.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.SubstringConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.SubstringConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.StartsWithConstraint">
+            <summary>
+            StartsWithConstraint can test whether a string starts
+            with an expected substring.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.StartsWithConstraint.#ctor(System.String)">
+            <summary>
+            Initializes a new instance of the <see cref="T:StartsWithConstraint"/> class.
+            </summary>
+            <param name="expected">The expected string</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.StartsWithConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is matched by the actual value.
+            This is a template method, which calls the IsMatch method
+            of the derived class.
+            </summary>
+            <param name="actual"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.StartsWithConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.EndsWithConstraint">
+            <summary>
+            EndsWithConstraint can test whether a string ends
+            with an expected substring.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EndsWithConstraint.#ctor(System.String)">
+            <summary>
+            Initializes a new instance of the <see cref="T:EndsWithConstraint"/> class.
+            </summary>
+            <param name="expected">The expected string</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EndsWithConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is matched by the actual value.
+            This is a template method, which calls the IsMatch method
+            of the derived class.
+            </summary>
+            <param name="actual"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EndsWithConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.RegexConstraint">
+            <summary>
+            RegexConstraint can test whether a string matches
+            the pattern provided.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.RegexConstraint.#ctor(System.String)">
+            <summary>
+            Initializes a new instance of the <see cref="T:RegexConstraint"/> class.
+            </summary>
+            <param name="pattern">The pattern.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.RegexConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.RegexConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.TypeConstraint">
+            <summary>
+            TypeConstraint is the abstract base for constraints
+            that take a Type as their expected value.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.TypeConstraint.expectedType">
+            <summary>
+            The expected Type used by the constraint
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.TypeConstraint.#ctor(System.Type)">
+            <summary>
+            Construct a TypeConstraint for a given Type
+            </summary>
+            <param name="type"></param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.TypeConstraint.WriteActualValueTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the actual value for a failing constraint test to a
+            MessageWriter. TypeConstraints override this method to write
+            the name of the type.
+            </summary>
+            <param name="writer">The writer on which the actual value is displayed</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.ExactTypeConstraint">
+            <summary>
+            ExactTypeConstraint is used to test that an object
+            is of the exact type provided in the constructor
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ExactTypeConstraint.#ctor(System.Type)">
+            <summary>
+            Construct an ExactTypeConstraint for a given Type
+            </summary>
+            <param name="type">The expected Type.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ExactTypeConstraint.Matches(System.Object)">
+            <summary>
+            Test that an object is of the exact type specified
+            </summary>
+            <param name="actual">The actual value.</param>
+            <returns>True if the tested object is of the exact type provided, otherwise false.</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ExactTypeConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the description of this constraint to a MessageWriter
+            </summary>
+            <param name="writer">The MessageWriter to use</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.InstanceOfTypeConstraint">
+            <summary>
+            InstanceOfTypeConstraint is used to test that an object
+            is of the same type provided or derived from it.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.InstanceOfTypeConstraint.#ctor(System.Type)">
+            <summary>
+            Construct an InstanceOfTypeConstraint for the type provided
+            </summary>
+            <param name="type">The expected Type</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.InstanceOfTypeConstraint.Matches(System.Object)">
+            <summary>
+            Test whether an object is of the specified type or a derived type
+            </summary>
+            <param name="actual">The object to be tested</param>
+            <returns>True if the object is of the provided type or derives from it, otherwise false.</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.InstanceOfTypeConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write a description of this constraint to a MessageWriter
+            </summary>
+            <param name="writer">The MessageWriter to use</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.AssignableFromConstraint">
+            <summary>
+            AssignableFromConstraint is used to test that an object
+            can be assigned from a given Type.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AssignableFromConstraint.#ctor(System.Type)">
+            <summary>
+            Construct an AssignableFromConstraint for the type provided
+            </summary>
+            <param name="type"></param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AssignableFromConstraint.Matches(System.Object)">
+            <summary>
+            Test whether an object can be assigned from the specified type
+            </summary>
+            <param name="actual">The object to be tested</param>
+            <returns>True if the object can be assigned a value of the expected Type, otherwise false.</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AssignableFromConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write a description of this constraint to a MessageWriter
+            </summary>
+            <param name="writer">The MessageWriter to use</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.AssignableToConstraint">
+            <summary>
+            AssignableToConstraint is used to test that an object
+            can be assigned to a given Type.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AssignableToConstraint.#ctor(System.Type)">
+            <summary>
+            Construct an AssignableToConstraint for the type provided
+            </summary>
+            <param name="type"></param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AssignableToConstraint.Matches(System.Object)">
+            <summary>
+            Test whether an object can be assigned to the specified type
+            </summary>
+            <param name="actual">The object to be tested</param>
+            <returns>True if the object can be assigned a value of the expected Type, otherwise false.</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AssignableToConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write a description of this constraint to a MessageWriter
+            </summary>
+            <param name="writer">The MessageWriter to use</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.ContainsConstraint">
+            <summary>
+            ContainsConstraint tests a whether a string contains a substring
+            or a collection contains an object. It postpones the decision of
+            which test to use until the type of the actual argument is known.
+            This allows testing whether a string is contained in a collection
+            or as a substring of another string using the same syntax.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ContainsConstraint.#ctor(System.Object)">
+            <summary>
+            Initializes a new instance of the <see cref="T:ContainsConstraint"/> class.
+            </summary>
+            <param name="expected">The expected.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ContainsConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ContainsConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ContainsConstraint.IgnoreCase">
+            <summary>
+            Flag the constraint to ignore case and return self.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.PropertyExistsConstraint">
+            <summary>
+            PropertyExistsConstraint tests that a named property
+            exists on the object provided through Match.
+            
+            Originally, PropertyConstraint provided this feature
+            in addition to making optional tests on the vaue
+            of the property. The two constraints are now separate.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.PropertyExistsConstraint.#ctor(System.String)">
+            <summary>
+            Initializes a new instance of the <see cref="T:PropertyExistConstraint"/> class.
+            </summary>
+            <param name="name">The name of the property.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.PropertyExistsConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the property exists for a given object
+            </summary>
+            <param name="actual">The object to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.PropertyExistsConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.PropertyExistsConstraint.WriteActualValueTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the actual value for a failing constraint test to a
+            MessageWriter.
+            </summary>
+            <param name="writer">The writer on which the actual value is displayed</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.PropertyExistsConstraint.GetStringRepresentation">
+            <summary>
+            Returns the string representation of the constraint.
+            </summary>
+            <returns></returns>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.PropertyConstraint">
+            <summary>
+            PropertyConstraint extracts a named property and uses
+            its value as the actual value for a chained constraint.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.PrefixConstraint">
+            <summary>
+            Abstract base class used for prefixes
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.PrefixConstraint.baseConstraint">
+            <summary>
+            The base constraint
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.PrefixConstraint.#ctor(NUnit.Framework.Constraints.IResolveConstraint)">
+            <summary>
+            Construct given a base constraint
+            </summary>
+            <param name="resolvable"></param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.PropertyConstraint.#ctor(System.String,NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Initializes a new instance of the <see cref="T:PropertyConstraint"/> class.
+            </summary>
+            <param name="name">The name.</param>
+            <param name="baseConstraint">The constraint to apply to the property.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.PropertyConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.PropertyConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.PropertyConstraint.WriteActualValueTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the actual value for a failing constraint test to a
+            MessageWriter. The default implementation simply writes
+            the raw value of actual, leaving it to the writer to
+            perform any formatting.
+            </summary>
+            <param name="writer">The writer on which the actual value is displayed</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.PropertyConstraint.GetStringRepresentation">
+            <summary>
+            Returns the string representation of the constraint.
+            </summary>
+            <returns></returns>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.NotConstraint">
+            <summary>
+            NotConstraint negates the effect of some other constraint
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.NotConstraint.#ctor(NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Initializes a new instance of the <see cref="T:NotConstraint"/> class.
+            </summary>
+            <param name="baseConstraint">The base constraint to be negated.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.NotConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for if the base constraint fails, false if it succeeds</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.NotConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.NotConstraint.WriteActualValueTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the actual value for a failing constraint test to a MessageWriter.
+            </summary>
+            <param name="writer">The writer on which the actual value is displayed</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.AllItemsConstraint">
+            <summary>
+            AllItemsConstraint applies another constraint to each
+            item in a collection, succeeding if they all succeed.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AllItemsConstraint.#ctor(NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Construct an AllItemsConstraint on top of an existing constraint
+            </summary>
+            <param name="itemConstraint"></param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AllItemsConstraint.Matches(System.Object)">
+            <summary>
+            Apply the item constraint to each item in the collection,
+            failing if any item fails.
+            </summary>
+            <param name="actual"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AllItemsConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write a description of this constraint to a MessageWriter
+            </summary>
+            <param name="writer"></param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.SomeItemsConstraint">
+            <summary>
+            SomeItemsConstraint applies another constraint to each
+            item in a collection, succeeding if any of them succeeds.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.SomeItemsConstraint.#ctor(NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Construct a SomeItemsConstraint on top of an existing constraint
+            </summary>
+            <param name="itemConstraint"></param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.SomeItemsConstraint.Matches(System.Object)">
+            <summary>
+            Apply the item constraint to each item in the collection,
+            succeeding if any item succeeds.
+            </summary>
+            <param name="actual"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.SomeItemsConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write a description of this constraint to a MessageWriter
+            </summary>
+            <param name="writer"></param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.NoItemConstraint">
+            <summary>
+            NoItemConstraint applies another constraint to each
+            item in a collection, failing if any of them succeeds.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.NoItemConstraint.#ctor(NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Construct a SomeItemsConstraint on top of an existing constraint
+            </summary>
+            <param name="itemConstraint"></param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.NoItemConstraint.Matches(System.Object)">
+            <summary>
+            Apply the item constraint to each item in the collection,
+            failing if any item fails.
+            </summary>
+            <param name="actual"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.NoItemConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write a description of this constraint to a MessageWriter
+            </summary>
+            <param name="writer"></param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.Numerics">
+            <summary>
+            The Numerics class contains common operations on numeric values.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Numerics.IsNumericType(System.Object)">
+            <summary>
+            Checks the type of the object, returning true if
+            the object is a numeric type.
+            </summary>
+            <param name="obj">The object to check</param>
+            <returns>true if the object is a numeric type</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Numerics.IsFloatingPointNumeric(System.Object)">
+            <summary>
+            Checks the type of the object, returning true if
+            the object is a floating point numeric type.
+            </summary>
+            <param name="obj">The object to check</param>
+            <returns>true if the object is a floating point numeric type</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Numerics.IsFixedPointNumeric(System.Object)">
+            <summary>
+            Checks the type of the object, returning true if
+            the object is a fixed point numeric type.
+            </summary>
+            <param name="obj">The object to check</param>
+            <returns>true if the object is a fixed point numeric type</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Numerics.AreEqual(System.Object,System.Object,NUnit.Framework.Constraints.Tolerance@)">
+            <summary>
+            Test two numeric values for equality, performing the usual numeric 
+            conversions and using a provided or default tolerance. If the tolerance 
+            provided is Empty, this method may set it to a default tolerance.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="tolerance">A reference to the tolerance in effect</param>
+            <returns>True if the values are equal</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Numerics.Compare(System.Object,System.Object)">
+            <summary>
+            Compare two numeric values, performing the usual numeric conversions.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <returns>The relationship of the values to each other</returns>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.MessageWriter">
+            <summary>
+            MessageWriter is the abstract base for classes that write
+            constraint descriptions and messages in some form. The
+            class has separate methods for writing various components
+            of a message, allowing implementations to tailor the
+            presentation as needed.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.MessageWriter.#ctor">
+            <summary>
+            Construct a MessageWriter given a culture
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.MessageWriter.WriteMessageLine(System.String,System.Object[])">
+            <summary>
+            Method to write single line  message with optional args, usually
+            written to precede the general failure message.
+            </summary>
+            <param name="message">The message to be written</param>
+            <param name="args">Any arguments used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.MessageWriter.WriteMessageLine(System.Int32,System.String,System.Object[])">
+            <summary>
+            Method to write single line  message with optional args, usually
+            written to precede the general failure message, at a givel 
+            indentation level.
+            </summary>
+            <param name="level">The indentation level of the message</param>
+            <param name="message">The message to be written</param>
+            <param name="args">Any arguments used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.MessageWriter.DisplayDifferences(NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Display Expected and Actual lines for a constraint. This
+            is called by MessageWriter's default implementation of 
+            WriteMessageTo and provides the generic two-line display. 
+            </summary>
+            <param name="constraint">The constraint that failed</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.MessageWriter.DisplayDifferences(System.Object,System.Object)">
+            <summary>
+            Display Expected and Actual lines for given values. This
+            method may be called by constraints that need more control over
+            the display of actual and expected values than is provided
+            by the default implementation.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value causing the failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.MessageWriter.DisplayDifferences(System.Object,System.Object,NUnit.Framework.Constraints.Tolerance)">
+            <summary>
+            Display Expected and Actual lines for given values, including
+            a tolerance value on the Expected line.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value causing the failure</param>
+            <param name="tolerance">The tolerance within which the test was made</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.MessageWriter.DisplayStringDifferences(System.String,System.String,System.Int32,System.Boolean,System.Boolean)">
+            <summary>
+            Display the expected and actual string values on separate lines.
+            If the mismatch parameter is >=0, an additional line is displayed
+            line containing a caret that points to the mismatch point.
+            </summary>
+            <param name="expected">The expected string value</param>
+            <param name="actual">The actual string value</param>
+            <param name="mismatch">The point at which the strings don't match or -1</param>
+            <param name="ignoreCase">If true, case is ignored in locating the point where the strings differ</param>
+            <param name="clipping">If true, the strings should be clipped to fit the line</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.MessageWriter.WriteConnector(System.String)">
+            <summary>
+            Writes the text for a connector.
+            </summary>
+            <param name="connector">The connector.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.MessageWriter.WritePredicate(System.String)">
+            <summary>
+            Writes the text for a predicate.
+            </summary>
+            <param name="predicate">The predicate.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.MessageWriter.WriteExpectedValue(System.Object)">
+            <summary>
+            Writes the text for an expected value.
+            </summary>
+            <param name="expected">The expected value.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.MessageWriter.WriteModifier(System.String)">
+            <summary>
+            Writes the text for a modifier
+            </summary>
+            <param name="modifier">The modifier.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.MessageWriter.WriteActualValue(System.Object)">
+            <summary>
+            Writes the text for an actual value.
+            </summary>
+            <param name="actual">The actual value.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.MessageWriter.WriteValue(System.Object)">
+            <summary>
+            Writes the text for a generalized value.
+            </summary>
+            <param name="val">The value.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.MessageWriter.WriteCollectionElements(System.Collections.ICollection,System.Int32,System.Int32)">
+            <summary>
+            Writes the text for a collection value,
+            starting at a particular point, to a max length
+            </summary>
+            <param name="collection">The collection containing elements to write.</param>
+            <param name="start">The starting point of the elements to write</param>
+            <param name="max">The maximum number of elements to write</param>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.MessageWriter.MaxLineLength">
+            <summary>
+            Abstract method to get the max line length
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.MsgUtils">
+            <summary>
+            Static methods used in creating messages
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.MsgUtils.ELLIPSIS">
+            <summary>
+            Static string used when strings are clipped
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.MsgUtils.GetTypeRepresentation(System.Object)">
+            <summary>
+            Returns the representation of a type as used in NUnitLite.
+            This is the same as Type.ToString() except for arrays,
+            which are displayed with their declared sizes.
+            </summary>
+            <param name="obj"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.MsgUtils.EscapeControlChars(System.String)">
+            <summary>
+            Converts any control characters in a string 
+            to their escaped representation.
+            </summary>
+            <param name="s">The string to be converted</param>
+            <returns>The converted string</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.MsgUtils.GetArrayIndicesAsString(System.Int32[])">
+            <summary>
+            Return the a string representation for a set of indices into an array
+            </summary>
+            <param name="indices">Array of indices for which a string is needed</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.MsgUtils.GetArrayIndicesFromCollectionIndex(System.Collections.ICollection,System.Int32)">
+            <summary>
+            Get an array of indices representing the point in a collection or
+            array corresponding to a single int index into the collection.
+            </summary>
+            <param name="collection">The collection to which the indices apply</param>
+            <param name="index">Index in the collection</param>
+            <returns>Array of indices</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.MsgUtils.ClipString(System.String,System.Int32,System.Int32)">
+            <summary>
+            Clip a string to a given length, starting at a particular offset, returning the clipped
+            string with ellipses representing the removed parts
+            </summary>
+            <param name="s">The string to be clipped</param>
+            <param name="maxStringLength">The maximum permitted length of the result string</param>
+            <param name="clipStart">The point at which to start clipping</param>
+            <returns>The clipped string</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.MsgUtils.ClipExpectedAndActual(System.String@,System.String@,System.Int32,System.Int32)">
+            <summary>
+            Clip the expected and actual strings in a coordinated fashion, 
+            so that they may be displayed together.
+            </summary>
+            <param name="expected"></param>
+            <param name="actual"></param>
+            <param name="maxDisplayLength"></param>
+            <param name="mismatch"></param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.MsgUtils.FindMismatchPosition(System.String,System.String,System.Int32,System.Boolean)">
+            <summary>
+            Shows the position two strings start to differ.  Comparison 
+            starts at the start index.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The actual string</param>
+            <param name="istart">The index in the strings at which comparison should start</param>
+            <param name="ignoreCase">Boolean indicating whether case should be ignored</param>
+            <returns>-1 if no mismatch found, or the index where mismatch found</returns>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.PathConstraint">
+            <summary>
+            PathConstraint serves as the abstract base of constraints
+            that operate on paths and provides several helper methods.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.PathConstraint.expected">
+            <summary>
+            The expected path used in the constraint
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.PathConstraint.caseInsensitive">
+            <summary>
+            Flag indicating whether a caseInsensitive comparison should be made
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.PathConstraint.#ctor(System.String)">
+            <summary>
+            Construct a PathConstraint for a give expected path
+            </summary>
+            <param name="expected">The expected path</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.PathConstraint.GetStringRepresentation">
+            <summary>
+            Returns the string representation of this constraint
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.PathConstraint.Canonicalize(System.String)">
+            <summary>
+            Canonicalize the provided path
+            </summary>
+            <param name="path"></param>
+            <returns>The path in standardized form</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.PathConstraint.IsSamePath(System.String,System.String)">
+            <summary>
+            Test whether two paths are the same
+            </summary>
+            <param name="path1">The first path</param>
+            <param name="path2">The second path</param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.PathConstraint.IsSamePathOrUnder(System.String,System.String)">
+            <summary>
+            Test whether one path is the same as or under another path
+            </summary>
+            <param name="path1">The first path - supposed to be the parent path</param>
+            <param name="path2">The second path - supposed to be the child path</param>
+            <returns></returns>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.PathConstraint.IgnoreCase">
+            <summary>
+            Modifies the current instance to be case-insensitve
+            and returns it.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.PathConstraint.RespectCase">
+            <summary>
+            Modifies the current instance to be case-sensitve
+            and returns it.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.SamePathConstraint">
+            <summary>
+            Summary description for SamePathConstraint.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.SamePathConstraint.#ctor(System.String)">
+            <summary>
+            Initializes a new instance of the <see cref="T:SamePathConstraint"/> class.
+            </summary>
+            <param name="expected">The expected path</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.SamePathConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.SamePathConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.SamePathOrUnderConstraint">
+            <summary>
+            SamePathOrUnderConstraint tests that one path is under another
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.SamePathOrUnderConstraint.#ctor(System.String)">
+            <summary>
+            Initializes a new instance of the <see cref="T:SamePathOrUnderConstraint"/> class.
+            </summary>
+            <param name="expected">The expected path</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.SamePathOrUnderConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.SamePathOrUnderConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.EmptyDirectoryContraint">
+            <summary>
+            EmptyDirectoryConstraint is used to test that a directory is empty
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EmptyDirectoryContraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EmptyDirectoryContraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EmptyDirectoryContraint.WriteActualValueTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the actual value for a failing constraint test to a
+            MessageWriter. The default implementation simply writes
+            the raw value of actual, leaving it to the writer to
+            perform any formatting.
+            </summary>
+            <param name="writer">The writer on which the actual value is displayed</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.SubDirectoryConstraint">
+            <summary>
+            SubDirectoryConstraint is used to test that one directory is a subdirectory of another.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.SubDirectoryConstraint.#ctor(System.IO.DirectoryInfo)">
+            <summary>
+            Initializes a new instance of the <see cref="T:SubDirectoryConstraint"/> class.
+            </summary>
+            <param name="dirInfo">The dir info.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.SubDirectoryConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.SubDirectoryConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.SubDirectoryConstraint.BuildDirectoryList(System.IO.DirectoryInfo)">
+            <summary>
+            Builds a list of DirectoryInfo objects, recursing where necessary
+            </summary>
+            <param name="StartingDirectory">directory to recurse</param>
+            <returns>list of DirectoryInfo objects from the top level</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.SubDirectoryConstraint.IsDirectoryOnPath(System.IO.DirectoryInfo,System.IO.DirectoryInfo)">
+            <summary>
+            private method to determine whether a directory is within the path
+            </summary>
+            <param name="ParentDirectory">top-level directory to search</param>
+            <param name="SearchDirectory">directory to search for</param>
+            <returns>true if found, false if not</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.SubDirectoryConstraint.DirectoriesEqual(System.IO.DirectoryInfo,System.IO.DirectoryInfo)">
+            <summary>
+            Method to compare two DirectoryInfo objects
+            </summary>
+            <param name="expected">first directory to compare</param>
+            <param name="actual">second directory to compare</param>
+            <returns>true if equivalent, false if not</returns>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.ThrowsConstraint">
+            <summary>
+            ThrowsConstraint is used to test the exception thrown by 
+            a delegate by applying a constraint to it.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ThrowsConstraint.#ctor(NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Initializes a new instance of the <see cref="T:ThrowsConstraint"/> class,
+            using a constraint to be applied to the exception.
+            </summary>
+            <param name="baseConstraint">A constraint to apply to the caught exception.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ThrowsConstraint.Matches(System.Object)">
+            <summary>
+            Executes the code of the delegate and captures any exception.
+            If a non-null base constraint was provided, it applies that
+            constraint to the exception.
+            </summary>
+            <param name="actual">A delegate representing the code to be tested</param>
+            <returns>True if an exception is thrown and the constraint succeeds, otherwise false</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ThrowsConstraint.Matches(NUnit.Framework.Constraints.ActualValueDelegate)">
+            <summary>
+            Converts an ActualValueDelegate to a TestDelegate
+            before calling the primary overload.
+            </summary>
+            <param name="del"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ThrowsConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ThrowsConstraint.WriteActualValueTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the actual value for a failing constraint test to a
+            MessageWriter. The default implementation simply writes
+            the raw value of actual, leaving it to the writer to
+            perform any formatting.
+            </summary>
+            <param name="writer">The writer on which the actual value is displayed</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ThrowsConstraint.GetStringRepresentation">
+            <summary>
+            Returns the string representation of this constraint
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ThrowsConstraint.ActualException">
+            <summary>
+            Get the actual exception thrown - used by Assert.Throws.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.ThrowsNothingConstraint">
+            <summary>
+            ThrowsNothingConstraint tests that a delegate does not
+            throw an exception.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ThrowsNothingConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True if no exception is thrown, otherwise false</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ThrowsNothingConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ThrowsNothingConstraint.WriteActualValueTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the actual value for a failing constraint test to a
+            MessageWriter. The default implementation simply writes
+            the raw value of actual, leaving it to the writer to
+            perform any formatting.
+            </summary>
+            <param name="writer">The writer on which the actual value is displayed</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.RangeConstraint">
+            <summary>
+            RangeConstraint tests whethe two values are within a 
+            specified range.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.RangeConstraint.#ctor(System.IComparable,System.IComparable)">
+            <summary>
+            Initializes a new instance of the <see cref="T:RangeConstraint"/> class.
+            </summary>
+            <param name="from">From.</param>
+            <param name="to">To.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.RangeConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.RangeConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.RangeConstraint.Using(System.Collections.IComparer)">
+            <summary>
+            Modifies the constraint to use an IComparer and returns self.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.RangeConstraint.Using``1(System.Collections.Generic.IComparer{``0})">
+            <summary>
+            Modifies the constraint to use an IComparer&lt;T&gt; and returns self.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.RangeConstraint.Using``1(System.Comparison{``0})">
+            <summary>
+            Modifies the constraint to use a Comparison&lt;T&gt; and returns self.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.ConstraintFactory">
+            <summary>
+            Helper class with properties and methods that supply
+            a number of constraints used in Asserts.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.Property(System.String)">
+            <summary>
+            Returns a new PropertyConstraintExpression, which will either
+            test for the existence of the named property on the object
+            being tested or apply any following constraint to that property.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.Attribute(System.Type)">
+            <summary>
+            Returns a new AttributeConstraint checking for the
+            presence of a particular attribute on an object.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.Attribute``1">
+            <summary>
+            Returns a new AttributeConstraint checking for the
+            presence of a particular attribute on an object.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.EqualTo(System.Object)">
+            <summary>
+            Returns a constraint that tests two items for equality
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.SameAs(System.Object)">
+            <summary>
+            Returns a constraint that tests that two references are the same object
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.GreaterThan(System.Object)">
+            <summary>
+            Returns a constraint that tests whether the
+            actual value is greater than the suppled argument
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.GreaterThanOrEqualTo(System.Object)">
+            <summary>
+            Returns a constraint that tests whether the
+            actual value is greater than or equal to the suppled argument
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.AtLeast(System.Object)">
+            <summary>
+            Returns a constraint that tests whether the
+            actual value is greater than or equal to the suppled argument
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.LessThan(System.Object)">
+            <summary>
+            Returns a constraint that tests whether the
+            actual value is less than the suppled argument
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.LessThanOrEqualTo(System.Object)">
+            <summary>
+            Returns a constraint that tests whether the
+            actual value is less than or equal to the suppled argument
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.AtMost(System.Object)">
+            <summary>
+            Returns a constraint that tests whether the
+            actual value is less than or equal to the suppled argument
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.TypeOf(System.Type)">
+            <summary>
+            Returns a constraint that tests whether the actual
+            value is of the exact type supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.TypeOf``1">
+            <summary>
+            Returns a constraint that tests whether the actual
+            value is of the exact type supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.InstanceOf(System.Type)">
+            <summary>
+            Returns a constraint that tests whether the actual value
+            is of the type supplied as an argument or a derived type.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.InstanceOf``1">
+            <summary>
+            Returns a constraint that tests whether the actual value
+            is of the type supplied as an argument or a derived type.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.InstanceOfType(System.Type)">
+            <summary>
+            Returns a constraint that tests whether the actual value
+            is of the type supplied as an argument or a derived type.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.InstanceOfType``1">
+            <summary>
+            Returns a constraint that tests whether the actual value
+            is of the type supplied as an argument or a derived type.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.AssignableFrom(System.Type)">
+            <summary>
+            Returns a constraint that tests whether the actual value
+            is assignable from the type supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.AssignableFrom``1">
+            <summary>
+            Returns a constraint that tests whether the actual value
+            is assignable from the type supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.AssignableTo(System.Type)">
+            <summary>
+            Returns a constraint that tests whether the actual value
+            is assignable from the type supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.AssignableTo``1">
+            <summary>
+            Returns a constraint that tests whether the actual value
+            is assignable from the type supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.EquivalentTo(System.Collections.IEnumerable)">
+            <summary>
+            Returns a constraint that tests whether the actual value
+            is a collection containing the same elements as the 
+            collection supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.SubsetOf(System.Collections.IEnumerable)">
+            <summary>
+            Returns a constraint that tests whether the actual value
+            is a subset of the collection supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.Member(System.Object)">
+            <summary>
+            Returns a new CollectionContainsConstraint checking for the
+            presence of a particular object in the collection.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.Contains(System.Object)">
+            <summary>
+            Returns a new CollectionContainsConstraint checking for the
+            presence of a particular object in the collection.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.Contains(System.String)">
+            <summary>
+            Returns a new ContainsConstraint. This constraint
+            will, in turn, make use of the appropriate second-level
+            constraint, depending on the type of the actual argument. 
+            This overload is only used if the item sought is a string,
+            since any other type implies that we are looking for a 
+            collection member.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.StringContaining(System.String)">
+            <summary>
+            Returns a constraint that succeeds if the actual
+            value contains the substring supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.ContainsSubstring(System.String)">
+            <summary>
+            Returns a constraint that succeeds if the actual
+            value contains the substring supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.DoesNotContain(System.String)">
+            <summary>
+            Returns a constraint that fails if the actual
+            value contains the substring supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.StartsWith(System.String)">
+            <summary>
+            Returns a constraint that succeeds if the actual
+            value starts with the substring supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.StringStarting(System.String)">
+            <summary>
+            Returns a constraint that succeeds if the actual
+            value starts with the substring supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.DoesNotStartWith(System.String)">
+            <summary>
+            Returns a constraint that fails if the actual
+            value starts with the substring supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.EndsWith(System.String)">
+            <summary>
+            Returns a constraint that succeeds if the actual
+            value ends with the substring supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.StringEnding(System.String)">
+            <summary>
+            Returns a constraint that succeeds if the actual
+            value ends with the substring supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.DoesNotEndWith(System.String)">
+            <summary>
+            Returns a constraint that fails if the actual
+            value ends with the substring supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.Matches(System.String)">
+            <summary>
+            Returns a constraint that succeeds if the actual
+            value matches the Regex pattern supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.StringMatching(System.String)">
+            <summary>
+            Returns a constraint that succeeds if the actual
+            value matches the Regex pattern supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.DoesNotMatch(System.String)">
+            <summary>
+            Returns a constraint that fails if the actual
+            value matches the pattern supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.SamePath(System.String)">
+            <summary>
+            Returns a constraint that tests whether the path provided 
+            is the same as an expected path after canonicalization.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.SamePathOrUnder(System.String)">
+            <summary>
+            Returns a constraint that tests whether the path provided 
+            is the same path or under an expected path after canonicalization.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintFactory.InRange(System.IComparable,System.IComparable)">
+            <summary>
+            Returns a constraint that tests whether the actual value falls 
+            within a specified range.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintFactory.Not">
+            <summary>
+            Returns a ConstraintExpression that negates any
+            following constraint.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintFactory.No">
+            <summary>
+            Returns a ConstraintExpression that negates any
+            following constraint.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintFactory.All">
+            <summary>
+            Returns a ConstraintExpression, which will apply
+            the following constraint to all members of a collection,
+            succeeding if all of them succeed.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintFactory.Some">
+            <summary>
+            Returns a ConstraintExpression, which will apply
+            the following constraint to all members of a collection,
+            succeeding if at least one of them succeeds.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintFactory.None">
+            <summary>
+            Returns a ConstraintExpression, which will apply
+            the following constraint to all members of a collection,
+            succeeding if all of them fail.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintFactory.Length">
+            <summary>
+            Returns a new ConstraintExpression, which will apply the following
+            constraint to the Length property of the object being tested.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintFactory.Count">
+            <summary>
+            Returns a new ConstraintExpression, which will apply the following
+            constraint to the Count property of the object being tested.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintFactory.Message">
+            <summary>
+            Returns a new ConstraintExpression, which will apply the following
+            constraint to the Message property of the object being tested.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintFactory.InnerException">
+            <summary>
+            Returns a new ConstraintExpression, which will apply the following
+            constraint to the InnerException property of the object being tested.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintFactory.Null">
+            <summary>
+            Returns a constraint that tests for null
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintFactory.True">
+            <summary>
+            Returns a constraint that tests for True
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintFactory.False">
+            <summary>
+            Returns a constraint that tests for False
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintFactory.NaN">
+            <summary>
+            Returns a constraint that tests for NaN
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintFactory.Empty">
+            <summary>
+            Returns a constraint that tests for empty
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintFactory.Unique">
+            <summary>
+            Returns a constraint that tests whether a collection 
+            contains all unique items.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintFactory.BinarySerializable">
+            <summary>
+            Returns a constraint that tests whether an object graph is serializable in binary format.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintFactory.XmlSerializable">
+            <summary>
+            Returns a constraint that tests whether an object graph is serializable in xml format.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintFactory.Ordered">
+            <summary>
+            Returns a constraint that tests whether a collection is ordered
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.ConstraintOperator">
+            <summary>
+            The ConstraintOperator class is used internally by a
+            ConstraintBuilder to represent an operator that 
+            modifies or combines constraints. 
+            
+            Constraint operators use left and right precedence
+            values to determine whether the top operator on the
+            stack should be reduced before pushing a new operator.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.ConstraintOperator.left_precedence">
+            <summary>
+            The precedence value used when the operator
+            is about to be pushed to the stack.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.ConstraintOperator.right_precedence">
+            <summary>
+            The precedence value used when the operator
+            is on the top of the stack.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintOperator.Reduce(NUnit.Framework.Constraints.ConstraintBuilder.ConstraintStack)">
+            <summary>
+            Reduce produces a constraint from the operator and 
+            any arguments. It takes the arguments from the constraint 
+            stack and pushes the resulting constraint on it.
+            </summary>
+            <param name="stack"></param>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintOperator.LeftContext">
+            <summary>
+            The syntax element preceding this operator
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintOperator.RightContext">
+            <summary>
+            The syntax element folowing this operator
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintOperator.LeftPrecedence">
+            <summary>
+            The precedence value used when the operator
+            is about to be pushed to the stack.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintOperator.RightPrecedence">
+            <summary>
+            The precedence value used when the operator
+            is on the top of the stack.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.PrefixOperator">
+            <summary>
+            PrefixOperator takes a single constraint and modifies
+            it's action in some way.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.PrefixOperator.Reduce(NUnit.Framework.Constraints.ConstraintBuilder.ConstraintStack)">
+            <summary>
+            Reduce produces a constraint from the operator and 
+            any arguments. It takes the arguments from the constraint 
+            stack and pushes the resulting constraint on it.
+            </summary>
+            <param name="stack"></param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.PrefixOperator.ApplyPrefix(NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Returns the constraint created by applying this
+            prefix to another constraint.
+            </summary>
+            <param name="constraint"></param>
+            <returns></returns>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.NotOperator">
+            <summary>
+            Negates the test of the constraint it wraps.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.NotOperator.#ctor">
+            <summary>
+            Constructs a new NotOperator
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.NotOperator.ApplyPrefix(NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Returns a NotConstraint applied to its argument.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.CollectionOperator">
+            <summary>
+            Abstract base for operators that indicate how to
+            apply a constraint to items in a collection.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionOperator.#ctor">
+            <summary>
+            Constructs a CollectionOperator
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.AllOperator">
+            <summary>
+            Represents a constraint that succeeds if all the 
+            members of a collection match a base constraint.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AllOperator.ApplyPrefix(NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Returns a constraint that will apply the argument
+            to the members of a collection, succeeding if
+            they all succeed.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.SomeOperator">
+            <summary>
+            Represents a constraint that succeeds if any of the 
+            members of a collection match a base constraint.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.SomeOperator.ApplyPrefix(NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Returns a constraint that will apply the argument
+            to the members of a collection, succeeding if
+            any of them succeed.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.NoneOperator">
+            <summary>
+            Represents a constraint that succeeds if none of the 
+            members of a collection match a base constraint.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.NoneOperator.ApplyPrefix(NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Returns a constraint that will apply the argument
+            to the members of a collection, succeeding if
+            none of them succeed.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.WithOperator">
+            <summary>
+            Represents a constraint that simply wraps the
+            constraint provided as an argument, without any
+            further functionality, but which modifes the
+            order of evaluation because of its precedence.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.WithOperator.#ctor">
+            <summary>
+            Constructor for the WithOperator
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.WithOperator.ApplyPrefix(NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Returns a constraint that wraps its argument
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.SelfResolvingOperator">
+            <summary>
+            Abstract base class for operators that are able to reduce to a 
+            constraint whether or not another syntactic element follows.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.PropOperator">
+            <summary>
+            Operator used to test for the presence of a named Property
+            on an object and optionally apply further tests to the
+            value of that property.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.PropOperator.#ctor(System.String)">
+            <summary>
+            Constructs a PropOperator for a particular named property
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.PropOperator.Reduce(NUnit.Framework.Constraints.ConstraintBuilder.ConstraintStack)">
+            <summary>
+            Reduce produces a constraint from the operator and 
+            any arguments. It takes the arguments from the constraint 
+            stack and pushes the resulting constraint on it.
+            </summary>
+            <param name="stack"></param>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.PropOperator.Name">
+            <summary>
+            Gets the name of the property to which the operator applies
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.AttributeOperator">
+            <summary>
+            Operator that tests for the presence of a particular attribute
+            on a type and optionally applies further tests to the attribute.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AttributeOperator.#ctor(System.Type)">
+            <summary>
+            Construct an AttributeOperator for a particular Type
+            </summary>
+            <param name="type">The Type of attribute tested</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AttributeOperator.Reduce(NUnit.Framework.Constraints.ConstraintBuilder.ConstraintStack)">
+            <summary>
+            Reduce produces a constraint from the operator and 
+            any arguments. It takes the arguments from the constraint 
+            stack and pushes the resulting constraint on it.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.ThrowsOperator">
+            <summary>
+            Operator that tests that an exception is thrown and
+            optionally applies further tests to the exception.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ThrowsOperator.#ctor">
+            <summary>
+            Construct a ThrowsOperator
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ThrowsOperator.Reduce(NUnit.Framework.Constraints.ConstraintBuilder.ConstraintStack)">
+            <summary>
+            Reduce produces a constraint from the operator and 
+            any arguments. It takes the arguments from the constraint 
+            stack and pushes the resulting constraint on it.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.BinaryOperator">
+            <summary>
+            Abstract base class for all binary operators
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.BinaryOperator.Reduce(NUnit.Framework.Constraints.ConstraintBuilder.ConstraintStack)">
+            <summary>
+            Reduce produces a constraint from the operator and 
+            any arguments. It takes the arguments from the constraint 
+            stack and pushes the resulting constraint on it.
+            </summary>
+            <param name="stack"></param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.BinaryOperator.ApplyOperator(NUnit.Framework.Constraints.Constraint,NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Abstract method that produces a constraint by applying
+            the operator to its left and right constraint arguments.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.BinaryOperator.LeftPrecedence">
+            <summary>
+            Gets the left precedence of the operator
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.BinaryOperator.RightPrecedence">
+            <summary>
+            Gets the right precedence of the operator
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.AndOperator">
+            <summary>
+            Operator that requires both it's arguments to succeed
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AndOperator.#ctor">
+            <summary>
+            Construct an AndOperator
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AndOperator.ApplyOperator(NUnit.Framework.Constraints.Constraint,NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Apply the operator to produce an AndConstraint
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.OrOperator">
+            <summary>
+            Operator that requires at least one of it's arguments to succeed
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.OrOperator.#ctor">
+            <summary>
+            Construct an OrOperator
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.OrOperator.ApplyOperator(NUnit.Framework.Constraints.Constraint,NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Apply the operator to produce an OrConstraint
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.ConstraintExpression">
+            <summary>
+            ConstraintExpression represents a compound constraint in the 
+            process of being constructed from a series of syntactic elements.
+            
+            Individual elements are appended to the expression as they are
+            reognized. Once an actual Constraint is appended, the expression
+            returns a resolvable Constraint.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.ConstraintExpressionBase">
+            <summary>
+            ConstraintExpressionBase is the abstract base class for the 
+            generated ConstraintExpression class, which represents a 
+            compound constraint in the process of being constructed 
+            from a series of syntactic elements.
+            
+            NOTE: ConstraintExpressionBase is aware of some of its
+            derived classes, which is an apparent violation of 
+            encapsulation. Ideally, these classes would be a 
+            single class, but they must be separated in order to
+            allow parts to be generated under .NET 1.x and to
+            provide proper user feedback in syntactically 
+            aware IDEs.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.ConstraintExpressionBase.builder">
+            <summary>
+            The ConstraintBuilder holding the elements recognized so far
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpressionBase.#ctor">
+            <summary>
+            Initializes a new instance of the <see cref="T:ConstraintExpressionBase"/> class.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpressionBase.#ctor(NUnit.Framework.Constraints.ConstraintBuilder)">
+            <summary>
+            Initializes a new instance of the <see cref="T:ConstraintExpressionBase"/> 
+            class passing in a ConstraintBuilder, which may be pre-populated.
+            </summary>
+            <param name="builder">The builder.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpressionBase.ToString">
+            <summary>
+            Returns a string representation of the expression as it
+            currently stands. This should only be used for testing,
+            since it has the side-effect of resolving the expression.
+            </summary>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpressionBase.Append(NUnit.Framework.Constraints.ConstraintOperator)">
+            <summary>
+            Appends an operator to the expression and returns the
+            resulting expression itself.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpressionBase.Append(NUnit.Framework.Constraints.SelfResolvingOperator)">
+            <summary>
+            Appends a self-resolving operator to the expression and
+            returns a new ResolvableConstraintExpression.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpressionBase.Append(NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Appends a constraint to the expression and returns that
+            constraint, which is associated with the current state
+            of the expression being built.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.#ctor">
+            <summary>
+            Initializes a new instance of the <see cref="T:ConstraintExpression"/> class.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.#ctor(NUnit.Framework.Constraints.ConstraintBuilder)">
+            <summary>
+            Initializes a new instance of the <see cref="T:ConstraintExpression"/> 
+            class passing in a ConstraintBuilder, which may be pre-populated.
+            </summary>
+            <param name="builder">The builder.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.Property(System.String)">
+            <summary>
+            Returns a new PropertyConstraintExpression, which will either
+            test for the existence of the named property on the object
+            being tested or apply any following constraint to that property.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.Attribute(System.Type)">
+            <summary>
+            Returns a new AttributeConstraint checking for the
+            presence of a particular attribute on an object.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.Attribute``1">
+            <summary>
+            Returns a new AttributeConstraint checking for the
+            presence of a particular attribute on an object.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.Matches(NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Returns the constraint provided as an argument - used to allow custom
+            custom constraints to easily participate in the syntax.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.Matches``1(System.Predicate{``0})">
+            <summary>
+            Returns the constraint provided as an argument - used to allow custom
+            custom constraints to easily participate in the syntax.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.EqualTo(System.Object)">
+            <summary>
+            Returns a constraint that tests two items for equality
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.SameAs(System.Object)">
+            <summary>
+            Returns a constraint that tests that two references are the same object
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.GreaterThan(System.Object)">
+            <summary>
+            Returns a constraint that tests whether the
+            actual value is greater than the suppled argument
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.GreaterThanOrEqualTo(System.Object)">
+            <summary>
+            Returns a constraint that tests whether the
+            actual value is greater than or equal to the suppled argument
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.AtLeast(System.Object)">
+            <summary>
+            Returns a constraint that tests whether the
+            actual value is greater than or equal to the suppled argument
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.LessThan(System.Object)">
+            <summary>
+            Returns a constraint that tests whether the
+            actual value is less than the suppled argument
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.LessThanOrEqualTo(System.Object)">
+            <summary>
+            Returns a constraint that tests whether the
+            actual value is less than or equal to the suppled argument
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.AtMost(System.Object)">
+            <summary>
+            Returns a constraint that tests whether the
+            actual value is less than or equal to the suppled argument
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.TypeOf(System.Type)">
+            <summary>
+            Returns a constraint that tests whether the actual
+            value is of the exact type supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.TypeOf``1">
+            <summary>
+            Returns a constraint that tests whether the actual
+            value is of the exact type supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.InstanceOf(System.Type)">
+            <summary>
+            Returns a constraint that tests whether the actual value
+            is of the type supplied as an argument or a derived type.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.InstanceOf``1">
+            <summary>
+            Returns a constraint that tests whether the actual value
+            is of the type supplied as an argument or a derived type.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.InstanceOfType(System.Type)">
+            <summary>
+            Returns a constraint that tests whether the actual value
+            is of the type supplied as an argument or a derived type.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.InstanceOfType``1">
+            <summary>
+            Returns a constraint that tests whether the actual value
+            is of the type supplied as an argument or a derived type.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.AssignableFrom(System.Type)">
+            <summary>
+            Returns a constraint that tests whether the actual value
+            is assignable from the type supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.AssignableFrom``1">
+            <summary>
+            Returns a constraint that tests whether the actual value
+            is assignable from the type supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.AssignableTo(System.Type)">
+            <summary>
+            Returns a constraint that tests whether the actual value
+            is assignable from the type supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.AssignableTo``1">
+            <summary>
+            Returns a constraint that tests whether the actual value
+            is assignable from the type supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.EquivalentTo(System.Collections.IEnumerable)">
+            <summary>
+            Returns a constraint that tests whether the actual value
+            is a collection containing the same elements as the 
+            collection supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.SubsetOf(System.Collections.IEnumerable)">
+            <summary>
+            Returns a constraint that tests whether the actual value
+            is a subset of the collection supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.Member(System.Object)">
+            <summary>
+            Returns a new CollectionContainsConstraint checking for the
+            presence of a particular object in the collection.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.Contains(System.Object)">
+            <summary>
+            Returns a new CollectionContainsConstraint checking for the
+            presence of a particular object in the collection.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.Contains(System.String)">
+            <summary>
+            Returns a new ContainsConstraint. This constraint
+            will, in turn, make use of the appropriate second-level
+            constraint, depending on the type of the actual argument. 
+            This overload is only used if the item sought is a string,
+            since any other type implies that we are looking for a 
+            collection member.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.StringContaining(System.String)">
+            <summary>
+            Returns a constraint that succeeds if the actual
+            value contains the substring supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.ContainsSubstring(System.String)">
+            <summary>
+            Returns a constraint that succeeds if the actual
+            value contains the substring supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.StartsWith(System.String)">
+            <summary>
+            Returns a constraint that succeeds if the actual
+            value starts with the substring supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.StringStarting(System.String)">
+            <summary>
+            Returns a constraint that succeeds if the actual
+            value starts with the substring supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.EndsWith(System.String)">
+            <summary>
+            Returns a constraint that succeeds if the actual
+            value ends with the substring supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.StringEnding(System.String)">
+            <summary>
+            Returns a constraint that succeeds if the actual
+            value ends with the substring supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.Matches(System.String)">
+            <summary>
+            Returns a constraint that succeeds if the actual
+            value matches the Regex pattern supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.StringMatching(System.String)">
+            <summary>
+            Returns a constraint that succeeds if the actual
+            value matches the Regex pattern supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.SamePath(System.String)">
+            <summary>
+            Returns a constraint that tests whether the path provided 
+            is the same as an expected path after canonicalization.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.SamePathOrUnder(System.String)">
+            <summary>
+            Returns a constraint that tests whether the path provided 
+            is the same path or under an expected path after canonicalization.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ConstraintExpression.InRange(System.IComparable,System.IComparable)">
+            <summary>
+            Returns a constraint that tests whether the actual value falls 
+            within a specified range.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintExpression.Not">
+            <summary>
+            Returns a ConstraintExpression that negates any
+            following constraint.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintExpression.No">
+            <summary>
+            Returns a ConstraintExpression that negates any
+            following constraint.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintExpression.All">
+            <summary>
+            Returns a ConstraintExpression, which will apply
+            the following constraint to all members of a collection,
+            succeeding if all of them succeed.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintExpression.Some">
+            <summary>
+            Returns a ConstraintExpression, which will apply
+            the following constraint to all members of a collection,
+            succeeding if at least one of them succeeds.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintExpression.None">
+            <summary>
+            Returns a ConstraintExpression, which will apply
+            the following constraint to all members of a collection,
+            succeeding if all of them fail.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintExpression.Length">
+            <summary>
+            Returns a new ConstraintExpression, which will apply the following
+            constraint to the Length property of the object being tested.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintExpression.Count">
+            <summary>
+            Returns a new ConstraintExpression, which will apply the following
+            constraint to the Count property of the object being tested.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintExpression.Message">
+            <summary>
+            Returns a new ConstraintExpression, which will apply the following
+            constraint to the Message property of the object being tested.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintExpression.InnerException">
+            <summary>
+            Returns a new ConstraintExpression, which will apply the following
+            constraint to the InnerException property of the object being tested.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintExpression.With">
+            <summary>
+            With is currently a NOP - reserved for future use.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintExpression.Null">
+            <summary>
+            Returns a constraint that tests for null
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintExpression.True">
+            <summary>
+            Returns a constraint that tests for True
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintExpression.False">
+            <summary>
+            Returns a constraint that tests for False
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintExpression.NaN">
+            <summary>
+            Returns a constraint that tests for NaN
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintExpression.Empty">
+            <summary>
+            Returns a constraint that tests for empty
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintExpression.Unique">
+            <summary>
+            Returns a constraint that tests whether a collection 
+            contains all unique items.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintExpression.BinarySerializable">
+            <summary>
+            Returns a constraint that tests whether an object graph is serializable in binary format.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintExpression.XmlSerializable">
+            <summary>
+            Returns a constraint that tests whether an object graph is serializable in xml format.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ConstraintExpression.Ordered">
+            <summary>
+            Returns a constraint that tests whether a collection is ordered
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.BinarySerializableConstraint">
+            <summary>
+            BinarySerializableConstraint tests whether 
+            an object is serializable in binary format.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.BinarySerializableConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.BinarySerializableConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.BinarySerializableConstraint.WriteActualValueTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the actual value for a failing constraint test to a
+            MessageWriter. The default implementation simply writes
+            the raw value of actual, leaving it to the writer to
+            perform any formatting.
+            </summary>
+            <param name="writer">The writer on which the actual value is displayed</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.BinarySerializableConstraint.GetStringRepresentation">
+            <summary>
+            Returns the string representation
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.XmlSerializableConstraint">
+            <summary>
+            BinarySerializableConstraint tests whether 
+            an object is serializable in binary format.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.XmlSerializableConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.XmlSerializableConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.XmlSerializableConstraint.WriteActualValueTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the actual value for a failing constraint test to a
+            MessageWriter. The default implementation simply writes
+            the raw value of actual, leaving it to the writer to
+            perform any formatting.
+            </summary>
+            <param name="writer">The writer on which the actual value is displayed</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.XmlSerializableConstraint.GetStringRepresentation">
+            <summary>
+            Returns the string representation of this constraint
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.BasicConstraint">
+            <summary>
+            BasicConstraint is the abstract base for constraints that
+            perform a simple comparison to a constant value.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.BasicConstraint.#ctor(System.Object,System.String)">
+            <summary>
+            Initializes a new instance of the <see cref="T:BasicConstraint"/> class.
+            </summary>
+            <param name="expected">The expected.</param>
+            <param name="description">The description.</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.BasicConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.BasicConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.NullConstraint">
+            <summary>
+            NullConstraint tests that the actual value is null
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.NullConstraint.#ctor">
+            <summary>
+            Initializes a new instance of the <see cref="T:NullConstraint"/> class.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.TrueConstraint">
+            <summary>
+            TrueConstraint tests that the actual value is true
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.TrueConstraint.#ctor">
+            <summary>
+            Initializes a new instance of the <see cref="T:TrueConstraint"/> class.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.FalseConstraint">
+            <summary>
+            FalseConstraint tests that the actual value is false
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.FalseConstraint.#ctor">
+            <summary>
+            Initializes a new instance of the <see cref="T:FalseConstraint"/> class.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.NaNConstraint">
+            <summary>
+            NaNConstraint tests that the actual value is a double or float NaN
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.NaNConstraint.Matches(System.Object)">
+            <summary>
+            Test that the actual value is an NaN
+            </summary>
+            <param name="actual"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.NaNConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the constraint description to a specified writer
+            </summary>
+            <param name="writer"></param>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.AttributeExistsConstraint">
+            <summary>
+            AttributeExistsConstraint tests for the presence of a
+            specified attribute on  a Type.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AttributeExistsConstraint.#ctor(System.Type)">
+            <summary>
+            Constructs an AttributeExistsConstraint for a specific attribute Type
+            </summary>
+            <param name="type"></param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AttributeExistsConstraint.Matches(System.Object)">
+            <summary>
+            Tests whether the object provides the expected attribute.
+            </summary>
+            <param name="actual">A Type, MethodInfo, or other ICustomAttributeProvider</param>
+            <returns>True if the expected attribute is present, otherwise false</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AttributeExistsConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Writes the description of the constraint to the specified writer
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.AttributeConstraint">
+            <summary>
+            AttributeConstraint tests that a specified attribute is present
+            on a Type or other provider and that the value of the attribute
+            satisfies some other constraint.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AttributeConstraint.#ctor(System.Type,NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Constructs an AttributeConstraint for a specified attriute
+            Type and base constraint.
+            </summary>
+            <param name="type"></param>
+            <param name="baseConstraint"></param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AttributeConstraint.Matches(System.Object)">
+            <summary>
+            Determines whether the Type or other provider has the 
+            expected attribute and if its value matches the
+            additional constraint specified.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AttributeConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Writes a description of the attribute to the specified writer.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AttributeConstraint.WriteActualValueTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Writes the actual value supplied to the specified writer.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.AttributeConstraint.GetStringRepresentation">
+            <summary>
+            Returns a string representation of the constraint.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.ResolvableConstraintExpression">
+            <summary>
+            ResolvableConstraintExpression is used to represent a compound
+            constraint being constructed at a point where the last operator
+            may either terminate the expression or may have additional 
+            qualifying constraints added to it. 
+            
+            It is used, for example, for a Property element or for
+            an Exception element, either of which may be optionally
+            followed by constraints that apply to the property or 
+            exception.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ResolvableConstraintExpression.#ctor">
+            <summary>
+            Create a new instance of ResolvableConstraintExpression
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ResolvableConstraintExpression.#ctor(NUnit.Framework.Constraints.ConstraintBuilder)">
+            <summary>
+            Create a new instance of ResolvableConstraintExpression,
+            passing in a pre-populated ConstraintBuilder.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ResolvableConstraintExpression.NUnit#Framework#Constraints#IResolveConstraint#Resolve">
+            <summary>
+            Resolve the current expression to a Constraint
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ResolvableConstraintExpression.And">
+            <summary>
+            Appends an And Operator to the expression
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ResolvableConstraintExpression.Or">
+            <summary>
+            Appends an Or operator to the expression.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.DelayedConstraint">
+            <summary>
+             Applies a delay to the match so that a match can be evaluated in the future.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.DelayedConstraint.#ctor(NUnit.Framework.Constraints.Constraint,System.Int32)">
+            <summary>
+             Creates a new DelayedConstraint
+            </summary>
+            <param name="baseConstraint">The inner constraint two decorate</param>
+            <param name="delayInMilliseconds">The time interval after which the match is performed</param>
+            <exception cref="T:System.InvalidOperationException">If the value of <paramref name="delayInMilliseconds"/> is less than 0</exception>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.DelayedConstraint.#ctor(NUnit.Framework.Constraints.Constraint,System.Int32,System.Int32)">
+            <summary>
+             Creates a new DelayedConstraint
+            </summary>
+            <param name="baseConstraint">The inner constraint two decorate</param>
+            <param name="delayInMilliseconds">The time interval after which the match is performed</param>
+            <param name="pollingInterval">The time interval used for polling</param>
+            <exception cref="T:System.InvalidOperationException">If the value of <paramref name="delayInMilliseconds"/> is less than 0</exception>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.DelayedConstraint.Matches(System.Object)">
+            <summary>
+            Test whether the constraint is satisfied by a given value
+            </summary>
+            <param name="actual">The value to be tested</param>
+            <returns>True for if the base constraint fails, false if it succeeds</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.DelayedConstraint.Matches(NUnit.Framework.Constraints.ActualValueDelegate)">
+            <summary>
+            Test whether the constraint is satisfied by a delegate
+            </summary>
+            <param name="del">The delegate whose value is to be tested</param>
+            <returns>True for if the base constraint fails, false if it succeeds</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.DelayedConstraint.Matches``1(``0@)">
+            <summary>
+            Test whether the constraint is satisfied by a given reference.
+            Overridden to wait for the specified delay period before
+            calling the base constraint with the dereferenced value.
+            </summary>
+            <param name="actual">A reference to the value to be tested</param>
+            <returns>True for success, false for failure</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.DelayedConstraint.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the constraint description to a MessageWriter
+            </summary>
+            <param name="writer">The writer on which the description is displayed</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.DelayedConstraint.WriteActualValueTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Write the actual value for a failing constraint test to a MessageWriter.
+            </summary>
+            <param name="writer">The writer on which the actual value is displayed</param>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.DelayedConstraint.GetStringRepresentation">
+            <summary>
+            Returns the string representation of the constraint.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.FloatingPointNumerics">
+            <summary>Helper routines for working with floating point numbers</summary>
+            <remarks>
+              <para>
+                The floating point comparison code is based on this excellent article:
+                http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
+              </para>
+              <para>
+                "ULP" means Unit in the Last Place and in the context of this library refers to
+                the distance between two adjacent floating point numbers. IEEE floating point
+                numbers can only represent a finite subset of natural numbers, with greater
+                accuracy for smaller numbers and lower accuracy for very large numbers.
+              </para>
+              <para>
+                If a comparison is allowed "2 ulps" of deviation, that means the values are
+                allowed to deviate by up to 2 adjacent floating point values, which might be
+                as low as 0.0000001 for small numbers or as high as 10.0 for large numbers.
+              </para>
+            </remarks>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.FloatingPointNumerics.AreAlmostEqualUlps(System.Single,System.Single,System.Int32)">
+            <summary>Compares two floating point values for equality</summary>
+            <param name="left">First floating point value to be compared</param>
+            <param name="right">Second floating point value t be compared</param>
+            <param name="maxUlps">
+              Maximum number of representable floating point values that are allowed to
+              be between the left and the right floating point values
+            </param>
+            <returns>True if both numbers are equal or close to being equal</returns>
+            <remarks>
+              <para>
+                Floating point values can only represent a finite subset of natural numbers.
+                For example, the values 2.00000000 and 2.00000024 can be stored in a float,
+                but nothing inbetween them.
+              </para>
+              <para>
+                This comparison will count how many possible floating point values are between
+                the left and the right number. If the number of possible values between both
+                numbers is less than or equal to maxUlps, then the numbers are considered as
+                being equal.
+              </para>
+              <para>
+                Implementation partially follows the code outlined here:
+                http://www.anttirt.net/2007/08/19/proper-floating-point-comparisons/
+              </para>
+            </remarks>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.FloatingPointNumerics.AreAlmostEqualUlps(System.Double,System.Double,System.Int64)">
+            <summary>Compares two double precision floating point values for equality</summary>
+            <param name="left">First double precision floating point value to be compared</param>
+            <param name="right">Second double precision floating point value t be compared</param>
+            <param name="maxUlps">
+              Maximum number of representable double precision floating point values that are
+              allowed to be between the left and the right double precision floating point values
+            </param>
+            <returns>True if both numbers are equal or close to being equal</returns>
+            <remarks>
+              <para>
+                Double precision floating point values can only represent a limited series of
+                natural numbers. For example, the values 2.0000000000000000 and 2.0000000000000004
+                can be stored in a double, but nothing inbetween them.
+              </para>
+              <para>
+                This comparison will count how many possible double precision floating point
+                values are between the left and the right number. If the number of possible
+                values between both numbers is less than or equal to maxUlps, then the numbers
+                are considered as being equal.
+              </para>
+              <para>
+                Implementation partially follows the code outlined here:
+                http://www.anttirt.net/2007/08/19/proper-floating-point-comparisons/
+              </para>
+            </remarks>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.FloatingPointNumerics.ReinterpretAsInt(System.Single)">
+            <summary>
+              Reinterprets the memory contents of a floating point value as an integer value
+            </summary>
+            <param name="value">
+              Floating point value whose memory contents to reinterpret
+            </param>
+            <returns>
+              The memory contents of the floating point value interpreted as an integer
+            </returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.FloatingPointNumerics.ReinterpretAsLong(System.Double)">
+            <summary>
+              Reinterprets the memory contents of a double precision floating point
+              value as an integer value
+            </summary>
+            <param name="value">
+              Double precision floating point value whose memory contents to reinterpret
+            </param>
+            <returns>
+              The memory contents of the double precision floating point value
+              interpreted as an integer
+            </returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.FloatingPointNumerics.ReinterpretAsFloat(System.Int32)">
+            <summary>
+              Reinterprets the memory contents of an integer as a floating point value
+            </summary>
+            <param name="value">Integer value whose memory contents to reinterpret</param>
+            <returns>
+              The memory contents of the integer value interpreted as a floating point value
+            </returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.FloatingPointNumerics.ReinterpretAsDouble(System.Int64)">
+            <summary>
+              Reinterprets the memory contents of an integer value as a double precision
+              floating point value
+            </summary>
+            <param name="value">Integer whose memory contents to reinterpret</param>
+            <returns>
+              The memory contents of the integer interpreted as a double precision
+              floating point value
+            </returns>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.FloatingPointNumerics.FloatIntUnion">
+            <summary>Union of a floating point variable and an integer</summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.FloatingPointNumerics.FloatIntUnion.Float">
+            <summary>The union's value as a floating point variable</summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.FloatingPointNumerics.FloatIntUnion.Int">
+            <summary>The union's value as an integer</summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.FloatingPointNumerics.FloatIntUnion.UInt">
+            <summary>The union's value as an unsigned integer</summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.FloatingPointNumerics.DoubleLongUnion">
+            <summary>Union of a double precision floating point variable and a long</summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.FloatingPointNumerics.DoubleLongUnion.Double">
+            <summary>The union's value as a double precision floating point variable</summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.FloatingPointNumerics.DoubleLongUnion.Long">
+            <summary>The union's value as a long</summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.FloatingPointNumerics.DoubleLongUnion.ULong">
+            <summary>The union's value as an unsigned long</summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.ToleranceMode">
+            <summary>
+            Modes in which the tolerance value for a comparison can
+            be interpreted.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.ToleranceMode.None">
+            <summary>
+            The tolerance was created with a value, without specifying 
+            how the value would be used. This is used to prevent setting
+            the mode more than once and is generally changed to Linear
+            upon execution of the test.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.ToleranceMode.Linear">
+            <summary>
+            The tolerance is used as a numeric range within which
+            two compared values are considered to be equal.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.ToleranceMode.Percent">
+            <summary>
+            Interprets the tolerance as the percentage by which
+            the two compared values my deviate from each other.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.ToleranceMode.Ulps">
+            <summary>
+            Compares two values based in their distance in
+            representable numbers.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.Tolerance">
+            <summary>
+            The Tolerance class generalizes the notion of a tolerance
+            within which an equality test succeeds. Normally, it is
+            used with numeric types, but it can be used with any
+            type that supports taking a difference between two 
+            objects and comparing that difference to a value.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Tolerance.#ctor(System.Object)">
+            <summary>
+            Constructs a linear tolerance of a specdified amount
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Tolerance.#ctor(System.Object,NUnit.Framework.Constraints.ToleranceMode)">
+            <summary>
+            Constructs a tolerance given an amount and ToleranceMode
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.Tolerance.CheckLinearAndNumeric">
+            <summary>
+            Tests that the current Tolerance is linear with a 
+            numeric value, throwing an exception if it is not.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.Tolerance.Empty">
+            <summary>
+            Returns an empty Tolerance object, equivalent to 
+            specifying an exact match.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.Tolerance.Mode">
+            <summary>
+            Gets the ToleranceMode for the current Tolerance
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.Tolerance.Value">
+            <summary>
+            Gets the value of the current Tolerance instance.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.Tolerance.Percent">
+            <summary>
+            Returns a new tolerance, using the current amount as a percentage.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.Tolerance.Ulps">
+            <summary>
+            Returns a new tolerance, using the current amount in Ulps.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.Tolerance.Days">
+            <summary>
+            Returns a new tolerance with a TimeSpan as the amount, using 
+            the current amount as a number of days.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.Tolerance.Hours">
+            <summary>
+            Returns a new tolerance with a TimeSpan as the amount, using 
+            the current amount as a number of hours.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.Tolerance.Minutes">
+            <summary>
+            Returns a new tolerance with a TimeSpan as the amount, using 
+            the current amount as a number of minutes.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.Tolerance.Seconds">
+            <summary>
+            Returns a new tolerance with a TimeSpan as the amount, using 
+            the current amount as a number of seconds.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.Tolerance.Milliseconds">
+            <summary>
+            Returns a new tolerance with a TimeSpan as the amount, using 
+            the current amount as a number of milliseconds.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.Tolerance.Ticks">
+            <summary>
+            Returns a new tolerance with a TimeSpan as the amount, using 
+            the current amount as a number of clock ticks.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.Tolerance.IsEmpty">
+            <summary>
+            Returns true if the current tolerance is empty.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.ComparisonAdapter">
+            <summary>
+            ComparisonAdapter class centralizes all comparisons of
+            values in NUnit, adapting to the use of any provided
+            IComparer, IComparer&lt;T&gt; or Comparison&lt;T&gt;
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ComparisonAdapter.For(System.Collections.IComparer)">
+            <summary>
+            Returns a ComparisonAdapter that wraps an IComparer
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ComparisonAdapter.For``1(System.Collections.Generic.IComparer{``0})">
+            <summary>
+            Returns a ComparisonAdapter that wraps an IComparer&lt;T&gt;
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ComparisonAdapter.For``1(System.Comparison{``0})">
+            <summary>
+            Returns a ComparisonAdapter that wraps a Comparison&lt;T&gt;
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ComparisonAdapter.Compare(System.Object,System.Object)">
+            <summary>
+            Compares two objects
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.ComparisonAdapter.Default">
+            <summary>
+            Gets the default ComparisonAdapter, which wraps an
+            NUnitComparer object.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ComparisonAdapter.ComparerAdapter.#ctor(System.Collections.IComparer)">
+            <summary>
+            Construct a ComparisonAdapter for an IComparer
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ComparisonAdapter.ComparerAdapter.Compare(System.Object,System.Object)">
+            <summary>
+            Compares two objects
+            </summary>
+            <param name="expected"></param>
+            <param name="actual"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ComparisonAdapter.DefaultComparisonAdapter.#ctor">
+            <summary>
+            Construct a default ComparisonAdapter
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.ComparisonAdapter.ComparerAdapter`1">
+            <summary>
+            ComparisonAdapter&lt;T&gt; extends ComparisonAdapter and
+            allows use of an IComparer&lt;T&gt; or Comparison&lt;T&gt;
+            to actually perform the comparison.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ComparisonAdapter.ComparerAdapter`1.#ctor(System.Collections.Generic.IComparer{`0})">
+            <summary>
+            Construct a ComparisonAdapter for an IComparer&lt;T&gt;
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ComparisonAdapter.ComparerAdapter`1.Compare(System.Object,System.Object)">
+            <summary>
+            Compare a Type T to an object
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ComparisonAdapter.ComparisonAdapterForComparison`1.#ctor(System.Comparison{`0})">
+            <summary>
+            Construct a ComparisonAdapter for a Comparison&lt;T&gt;
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.ComparisonAdapter.ComparisonAdapterForComparison`1.Compare(System.Object,System.Object)">
+            <summary>
+            Compare a Type T to an object
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.EqualityAdapter">
+            <summary>
+            EqualityAdapter class handles all equality comparisons
+            that use an IEqualityComparer, IEqualityComparer&lt;T&gt;
+            or a ComparisonAdapter.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EqualityAdapter.ObjectsEqual(System.Object,System.Object)">
+            <summary>
+            Compares two objects, returning true if they are equal
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EqualityAdapter.For(System.Collections.IComparer)">
+            <summary>
+            Returns an EqualityAdapter that wraps an IComparer.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EqualityAdapter.For(System.Collections.IEqualityComparer)">
+            <summary>
+            Returns an EqualityAdapter that wraps an IEqualityComparer.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EqualityAdapter.For``1(System.Collections.Generic.IEqualityComparer{``0})">
+            <summary>
+            Returns an EqualityAdapter that wraps an IEqualityComparer&lt;T&gt;.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EqualityAdapter.For``1(System.Collections.Generic.IComparer{``0})">
+            <summary>
+            Returns an EqualityAdapter that wraps an IComparer&lt;T&gt;.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.EqualityAdapter.For``1(System.Comparison{``0})">
+            <summary>
+            Returns an EqualityAdapter that wraps a Comparison&lt;T&gt;.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.NUnitComparer">
+            <summary>
+            NUnitComparer encapsulates NUnit's default behavior
+            in comparing two objects.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.NUnitComparer.Compare(System.Object,System.Object)">
+            <summary>
+            Compares two objects
+            </summary>
+            <param name="x"></param>
+            <param name="y"></param>
+            <returns></returns>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.NUnitComparer.Default">
+            <summary>
+            Returns the default NUnitComparer.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.NUnitEqualityComparer">
+            <summary>
+            NUnitEqualityComparer encapsulates NUnit's handling of
+            equality tests between objects.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.NUnitEqualityComparer.caseInsensitive">
+            <summary>
+            If true, all string comparisons will ignore case
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.NUnitEqualityComparer.compareAsCollection">
+            <summary>
+            If true, arrays will be treated as collections, allowing
+            those of different dimensions to be compared
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.NUnitEqualityComparer.tolerance">
+            <summary>
+            If non-zero, equality comparisons within the specified 
+            tolerance will succeed.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.Constraints.NUnitEqualityComparer.externalComparer">
+            <summary>
+            Comparison object used in comparisons for some constraints.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.NUnitEqualityComparer.ObjectsEqual(System.Object,System.Object)">
+            <summary>
+            Compares two objects for equality.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.NUnitEqualityComparer.ArraysEqual(System.Array,System.Array)">
+            <summary>
+            Helper method to compare two arrays
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.NUnitEqualityComparer.DirectoriesEqual(System.IO.DirectoryInfo,System.IO.DirectoryInfo)">
+            <summary>
+            Method to compare two DirectoryInfo objects
+            </summary>
+            <param name="x">first directory to compare</param>
+            <param name="y">second directory to compare</param>
+            <returns>true if equivalent, false if not</returns>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.NUnitEqualityComparer.Default">
+            <summary>
+            Returns the default NUnitEqualityComparer
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.NUnitEqualityComparer.IgnoreCase">
+            <summary>
+            Gets and sets a flag indicating whether case should
+            be ignored in determining equality.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.NUnitEqualityComparer.CompareAsCollection">
+            <summary>
+            Gets and sets a flag indicating that arrays should be
+            compared as collections, without regard to their shape.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.NUnitEqualityComparer.ExternalComparer">
+            <summary>
+            Gets and sets an external comparer to be used to
+            test for equality. It is applied to members of
+            collections, in place of NUnit's own logic.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.NUnitEqualityComparer.Tolerance">
+            <summary>
+            Gets and sets a tolerance used to compare objects of 
+            certin types.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.NUnitEqualityComparer.FailurePoints">
+            <summary>
+            Gets the list of failure points for the last Match performed.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.PredicateConstraint`1">
+            <summary>
+            Predicate constraint wraps a Predicate in a constraint,
+            returning success if the predicate is true.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.PredicateConstraint`1.#ctor(System.Predicate{`0})">
+            <summary>
+            Construct a PredicateConstraint from a predicate
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.PredicateConstraint`1.Matches(System.Object)">
+            <summary>
+            Determines whether the predicate succeeds when applied
+            to the actual value.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.PredicateConstraint`1.WriteDescriptionTo(NUnit.Framework.Constraints.MessageWriter)">
+            <summary>
+            Writes the description to a MessageWriter
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Constraints.CollectionTally">
+            <summary>
+            CollectionTally counts (tallies) the number of
+            occurences of each object in one or more enumerations.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionTally.#ctor(NUnit.Framework.Constraints.NUnitEqualityComparer,System.Collections.IEnumerable)">
+            <summary>
+            Construct a CollectionTally object from a comparer and a collection
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionTally.TryRemove(System.Object)">
+            <summary>
+            Try to remove an object from the tally
+            </summary>
+            <param name="o">The object to remove</param>
+            <returns>True if successful, false if the object was not found</returns>
+        </member>
+        <member name="M:NUnit.Framework.Constraints.CollectionTally.TryRemove(System.Collections.IEnumerable)">
+            <summary>
+            Try to remove a set of objects from the tally
+            </summary>
+            <param name="c">The objects to remove</param>
+            <returns>True if successful, false if any object was not found</returns>
+        </member>
+        <member name="P:NUnit.Framework.Constraints.CollectionTally.Count">
+            <summary>
+            The number of objects remaining in the tally
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.SetUpFixtureAttribute">
+            <summary>
+            SetUpFixtureAttribute is used to identify a SetUpFixture
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.StringAssert">
+            <summary>
+            Basic Asserts on strings.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.Equals(System.Object,System.Object)">
+            <summary>
+            The Equals method throws an AssertionException. This is done 
+            to make sure there is no mistake by calling this function.
+            </summary>
+            <param name="a"></param>
+            <param name="b"></param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.ReferenceEquals(System.Object,System.Object)">
+            <summary>
+            override the default ReferenceEquals to throw an AssertionException. This 
+            implementation makes sure there is no mistake in calling this function 
+            as part of Assert. 
+            </summary>
+            <param name="a"></param>
+            <param name="b"></param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.Contains(System.String,System.String,System.String,System.Object[])">
+            <summary>
+            Asserts that a string is found within another string.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The string to be examined</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Arguments used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.Contains(System.String,System.String,System.String)">
+            <summary>
+            Asserts that a string is found within another string.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The string to be examined</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.Contains(System.String,System.String)">
+            <summary>
+            Asserts that a string is found within another string.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The string to be examined</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.DoesNotContain(System.String,System.String,System.String,System.Object[])">
+            <summary>
+            Asserts that a string is not found within another string.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The string to be examined</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Arguments used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.DoesNotContain(System.String,System.String,System.String)">
+            <summary>
+            Asserts that a string is found within another string.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The string to be examined</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.DoesNotContain(System.String,System.String)">
+            <summary>
+            Asserts that a string is found within another string.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The string to be examined</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.StartsWith(System.String,System.String,System.String,System.Object[])">
+            <summary>
+            Asserts that a string starts with another string.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The string to be examined</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Arguments used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.StartsWith(System.String,System.String,System.String)">
+            <summary>
+            Asserts that a string starts with another string.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The string to be examined</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.StartsWith(System.String,System.String)">
+            <summary>
+            Asserts that a string starts with another string.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The string to be examined</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.DoesNotStartWith(System.String,System.String,System.String,System.Object[])">
+            <summary>
+            Asserts that a string does not start with another string.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The string to be examined</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Arguments used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.DoesNotStartWith(System.String,System.String,System.String)">
+            <summary>
+            Asserts that a string does not start with another string.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The string to be examined</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.DoesNotStartWith(System.String,System.String)">
+            <summary>
+            Asserts that a string does not start with another string.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The string to be examined</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.EndsWith(System.String,System.String,System.String,System.Object[])">
+            <summary>
+            Asserts that a string ends with another string.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The string to be examined</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Arguments used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.EndsWith(System.String,System.String,System.String)">
+            <summary>
+            Asserts that a string ends with another string.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The string to be examined</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.EndsWith(System.String,System.String)">
+            <summary>
+            Asserts that a string ends with another string.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The string to be examined</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.DoesNotEndWith(System.String,System.String,System.String,System.Object[])">
+            <summary>
+            Asserts that a string does not end with another string.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The string to be examined</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Arguments used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.DoesNotEndWith(System.String,System.String,System.String)">
+            <summary>
+            Asserts that a string does not end with another string.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The string to be examined</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.DoesNotEndWith(System.String,System.String)">
+            <summary>
+            Asserts that a string does not end with another string.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The string to be examined</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.AreEqualIgnoringCase(System.String,System.String,System.String,System.Object[])">
+            <summary>
+            Asserts that two strings are equal, without regard to case.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The actual string</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Arguments used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.AreEqualIgnoringCase(System.String,System.String,System.String)">
+            <summary>
+            Asserts that two strings are equal, without regard to case.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The actual string</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.AreEqualIgnoringCase(System.String,System.String)">
+            <summary>
+            Asserts that two strings are equal, without regard to case.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The actual string</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.AreNotEqualIgnoringCase(System.String,System.String,System.String,System.Object[])">
+            <summary>
+            Asserts that two strings are not equal, without regard to case.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The actual string</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Arguments used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.AreNotEqualIgnoringCase(System.String,System.String,System.String)">
+            <summary>
+            Asserts that two strings are Notequal, without regard to case.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The actual string</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.AreNotEqualIgnoringCase(System.String,System.String)">
+            <summary>
+            Asserts that two strings are not equal, without regard to case.
+            </summary>
+            <param name="expected">The expected string</param>
+            <param name="actual">The actual string</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.IsMatch(System.String,System.String,System.String,System.Object[])">
+            <summary>
+            Asserts that a string matches an expected regular expression pattern.
+            </summary>
+            <param name="pattern">The regex pattern to be matched</param>
+            <param name="actual">The actual string</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Arguments used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.IsMatch(System.String,System.String,System.String)">
+            <summary>
+            Asserts that a string matches an expected regular expression pattern.
+            </summary>
+            <param name="pattern">The regex pattern to be matched</param>
+            <param name="actual">The actual string</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.IsMatch(System.String,System.String)">
+            <summary>
+            Asserts that a string matches an expected regular expression pattern.
+            </summary>
+            <param name="pattern">The regex pattern to be matched</param>
+            <param name="actual">The actual string</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.DoesNotMatch(System.String,System.String,System.String,System.Object[])">
+            <summary>
+            Asserts that a string does not match an expected regular expression pattern.
+            </summary>
+            <param name="pattern">The regex pattern to be used</param>
+            <param name="actual">The actual string</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Arguments used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.DoesNotMatch(System.String,System.String,System.String)">
+            <summary>
+            Asserts that a string does not match an expected regular expression pattern.
+            </summary>
+            <param name="pattern">The regex pattern to be used</param>
+            <param name="actual">The actual string</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.StringAssert.DoesNotMatch(System.String,System.String)">
+            <summary>
+            Asserts that a string does not match an expected regular expression pattern.
+            </summary>
+            <param name="pattern">The regex pattern to be used</param>
+            <param name="actual">The actual string</param>
+        </member>
+        <member name="T:NUnit.Framework.PropertyAttribute">
+            <summary>
+            PropertyAttribute is used to attach information to a test as a name/value pair..
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.PropertyAttribute.#ctor(System.String,System.String)">
+            <summary>
+            Construct a PropertyAttribute with a name and string value
+            </summary>
+            <param name="propertyName">The name of the property</param>
+            <param name="propertyValue">The property value</param>
+        </member>
+        <member name="M:NUnit.Framework.PropertyAttribute.#ctor(System.String,System.Int32)">
+            <summary>
+            Construct a PropertyAttribute with a name and int value
+            </summary>
+            <param name="propertyName">The name of the property</param>
+            <param name="propertyValue">The property value</param>
+        </member>
+        <member name="M:NUnit.Framework.PropertyAttribute.#ctor(System.String,System.Double)">
+            <summary>
+            Construct a PropertyAttribute with a name and double value
+            </summary>
+            <param name="propertyName">The name of the property</param>
+            <param name="propertyValue">The property value</param>
+        </member>
+        <member name="M:NUnit.Framework.PropertyAttribute.#ctor">
+            <summary>
+            Constructor for derived classes that set the
+            property dictionary directly.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.PropertyAttribute.#ctor(System.Object)">
+            <summary>
+            Constructor for use by derived classes that use the
+            name of the type as the property name. Derived classes
+            must ensure that the Type of the property value is
+            a standard type supported by the BCL. Any custom
+            types will cause a serialization Exception when
+            in the client.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.PropertyAttribute.Properties">
+            <summary>
+            Gets the property dictionary for this attribute
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.CollectionAssert">
+            <summary>
+            A set of Assert methods operationg on one or more collections
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.Equals(System.Object,System.Object)">
+            <summary>
+            The Equals method throws an AssertionException. This is done 
+            to make sure there is no mistake by calling this function.
+            </summary>
+            <param name="a"></param>
+            <param name="b"></param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.ReferenceEquals(System.Object,System.Object)">
+            <summary>
+            override the default ReferenceEquals to throw an AssertionException. This 
+            implementation makes sure there is no mistake in calling this function 
+            as part of Assert. 
+            </summary>
+            <param name="a"></param>
+            <param name="b"></param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AllItemsAreInstancesOfType(System.Collections.IEnumerable,System.Type)">
+            <summary>
+            Asserts that all items contained in collection are of the type specified by expectedType.
+            </summary>
+            <param name="collection">IEnumerable containing objects to be considered</param>
+            <param name="expectedType">System.Type that all objects in collection must be instances of</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AllItemsAreInstancesOfType(System.Collections.IEnumerable,System.Type,System.String)">
+            <summary>
+            Asserts that all items contained in collection are of the type specified by expectedType.
+            </summary>
+            <param name="collection">IEnumerable containing objects to be considered</param>
+            <param name="expectedType">System.Type that all objects in collection must be instances of</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AllItemsAreInstancesOfType(System.Collections.IEnumerable,System.Type,System.String,System.Object[])">
+            <summary>
+            Asserts that all items contained in collection are of the type specified by expectedType.
+            </summary>
+            <param name="collection">IEnumerable containing objects to be considered</param>
+            <param name="expectedType">System.Type that all objects in collection must be instances of</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AllItemsAreNotNull(System.Collections.IEnumerable)">
+            <summary>
+            Asserts that all items contained in collection are not equal to null.
+            </summary>
+            <param name="collection">IEnumerable containing objects to be considered</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AllItemsAreNotNull(System.Collections.IEnumerable,System.String)">
+            <summary>
+            Asserts that all items contained in collection are not equal to null.
+            </summary>
+            <param name="collection">IEnumerable containing objects to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AllItemsAreNotNull(System.Collections.IEnumerable,System.String,System.Object[])">
+            <summary>
+            Asserts that all items contained in collection are not equal to null.
+            </summary>
+            <param name="collection">IEnumerable of objects to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AllItemsAreUnique(System.Collections.IEnumerable)">
+            <summary>
+            Ensures that every object contained in collection exists within the collection
+            once and only once.
+            </summary>
+            <param name="collection">IEnumerable of objects to be considered</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AllItemsAreUnique(System.Collections.IEnumerable,System.String)">
+            <summary>
+            Ensures that every object contained in collection exists within the collection
+            once and only once.
+            </summary>
+            <param name="collection">IEnumerable of objects to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AllItemsAreUnique(System.Collections.IEnumerable,System.String,System.Object[])">
+            <summary>
+            Ensures that every object contained in collection exists within the collection
+            once and only once.
+            </summary>
+            <param name="collection">IEnumerable of objects to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreEqual(System.Collections.IEnumerable,System.Collections.IEnumerable)">
+            <summary>
+            Asserts that expected and actual are exactly equal.  The collections must have the same count, 
+            and contain the exact same objects in the same order.
+            </summary>
+            <param name="expected">The first IEnumerable of objects to be considered</param>
+            <param name="actual">The second IEnumerable of objects to be considered</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreEqual(System.Collections.IEnumerable,System.Collections.IEnumerable,System.Collections.IComparer)">
+            <summary>
+            Asserts that expected and actual are exactly equal.  The collections must have the same count, 
+            and contain the exact same objects in the same order.
+            If comparer is not null then it will be used to compare the objects.
+            </summary>
+            <param name="expected">The first IEnumerable of objects to be considered</param>
+            <param name="actual">The second IEnumerable of objects to be considered</param>
+            <param name="comparer">The IComparer to use in comparing objects from each IEnumerable</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreEqual(System.Collections.IEnumerable,System.Collections.IEnumerable,System.String)">
+            <summary>
+            Asserts that expected and actual are exactly equal.  The collections must have the same count, 
+            and contain the exact same objects in the same order.
+            </summary>
+            <param name="expected">The first IEnumerable of objects to be considered</param>
+            <param name="actual">The second IEnumerable of objects to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreEqual(System.Collections.IEnumerable,System.Collections.IEnumerable,System.Collections.IComparer,System.String)">
+            <summary>
+            Asserts that expected and actual are exactly equal.  The collections must have the same count, 
+            and contain the exact same objects in the same order.
+            If comparer is not null then it will be used to compare the objects.
+            </summary>
+            <param name="expected">The first IEnumerable of objects to be considered</param>
+            <param name="actual">The second IEnumerable of objects to be considered</param>
+            <param name="comparer">The IComparer to use in comparing objects from each IEnumerable</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreEqual(System.Collections.IEnumerable,System.Collections.IEnumerable,System.String,System.Object[])">
+            <summary>
+            Asserts that expected and actual are exactly equal.  The collections must have the same count, 
+            and contain the exact same objects in the same order.
+            </summary>
+            <param name="expected">The first IEnumerable of objects to be considered</param>
+            <param name="actual">The second IEnumerable of objects to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreEqual(System.Collections.IEnumerable,System.Collections.IEnumerable,System.Collections.IComparer,System.String,System.Object[])">
+            <summary>
+            Asserts that expected and actual are exactly equal.  The collections must have the same count, 
+            and contain the exact same objects in the same order.
+            If comparer is not null then it will be used to compare the objects.
+            </summary>
+            <param name="expected">The first IEnumerable of objects to be considered</param>
+            <param name="actual">The second IEnumerable of objects to be considered</param>
+            <param name="comparer">The IComparer to use in comparing objects from each IEnumerable</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreEquivalent(System.Collections.IEnumerable,System.Collections.IEnumerable)">
+            <summary>
+            Asserts that expected and actual are equivalent, containing the same objects but the match may be in any order.
+            </summary>
+            <param name="expected">The first IEnumerable of objects to be considered</param>
+            <param name="actual">The second IEnumerable of objects to be considered</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreEquivalent(System.Collections.IEnumerable,System.Collections.IEnumerable,System.String)">
+            <summary>
+            Asserts that expected and actual are equivalent, containing the same objects but the match may be in any order.
+            </summary>
+            <param name="expected">The first IEnumerable of objects to be considered</param>
+            <param name="actual">The second IEnumerable of objects to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreEquivalent(System.Collections.IEnumerable,System.Collections.IEnumerable,System.String,System.Object[])">
+            <summary>
+            Asserts that expected and actual are equivalent, containing the same objects but the match may be in any order.
+            </summary>
+            <param name="expected">The first IEnumerable of objects to be considered</param>
+            <param name="actual">The second IEnumerable of objects to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreNotEqual(System.Collections.IEnumerable,System.Collections.IEnumerable)">
+            <summary>
+            Asserts that expected and actual are not exactly equal.
+            </summary>
+            <param name="expected">The first IEnumerable of objects to be considered</param>
+            <param name="actual">The second IEnumerable of objects to be considered</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreNotEqual(System.Collections.IEnumerable,System.Collections.IEnumerable,System.Collections.IComparer)">
+            <summary>
+            Asserts that expected and actual are not exactly equal.
+            If comparer is not null then it will be used to compare the objects.
+            </summary>
+            <param name="expected">The first IEnumerable of objects to be considered</param>
+            <param name="actual">The second IEnumerable of objects to be considered</param>
+            <param name="comparer">The IComparer to use in comparing objects from each IEnumerable</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreNotEqual(System.Collections.IEnumerable,System.Collections.IEnumerable,System.String)">
+            <summary>
+            Asserts that expected and actual are not exactly equal.
+            </summary>
+            <param name="expected">The first IEnumerable of objects to be considered</param>
+            <param name="actual">The second IEnumerable of objects to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreNotEqual(System.Collections.IEnumerable,System.Collections.IEnumerable,System.Collections.IComparer,System.String)">
+            <summary>
+            Asserts that expected and actual are not exactly equal.
+            If comparer is not null then it will be used to compare the objects.
+            </summary>
+            <param name="expected">The first IEnumerable of objects to be considered</param>
+            <param name="actual">The second IEnumerable of objects to be considered</param>
+            <param name="comparer">The IComparer to use in comparing objects from each IEnumerable</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreNotEqual(System.Collections.IEnumerable,System.Collections.IEnumerable,System.String,System.Object[])">
+            <summary>
+            Asserts that expected and actual are not exactly equal.
+            </summary>
+            <param name="expected">The first IEnumerable of objects to be considered</param>
+            <param name="actual">The second IEnumerable of objects to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreNotEqual(System.Collections.IEnumerable,System.Collections.IEnumerable,System.Collections.IComparer,System.String,System.Object[])">
+            <summary>
+            Asserts that expected and actual are not exactly equal.
+            If comparer is not null then it will be used to compare the objects.
+            </summary>
+            <param name="expected">The first IEnumerable of objects to be considered</param>
+            <param name="actual">The second IEnumerable of objects to be considered</param>
+            <param name="comparer">The IComparer to use in comparing objects from each IEnumerable</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreNotEquivalent(System.Collections.IEnumerable,System.Collections.IEnumerable)">
+            <summary>
+            Asserts that expected and actual are not equivalent.
+            </summary>
+            <param name="expected">The first IEnumerable of objects to be considered</param>
+            <param name="actual">The second IEnumerable of objects to be considered</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreNotEquivalent(System.Collections.IEnumerable,System.Collections.IEnumerable,System.String)">
+            <summary>
+            Asserts that expected and actual are not equivalent.
+            </summary>
+            <param name="expected">The first IEnumerable of objects to be considered</param>
+            <param name="actual">The second IEnumerable of objects to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.AreNotEquivalent(System.Collections.IEnumerable,System.Collections.IEnumerable,System.String,System.Object[])">
+            <summary>
+            Asserts that expected and actual are not equivalent.
+            </summary>
+            <param name="expected">The first IEnumerable of objects to be considered</param>
+            <param name="actual">The second IEnumerable of objects to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.Contains(System.Collections.IEnumerable,System.Object)">
+            <summary>
+            Asserts that collection contains actual as an item.
+            </summary>
+            <param name="collection">IEnumerable of objects to be considered</param>
+            <param name="actual">Object to be found within collection</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.Contains(System.Collections.IEnumerable,System.Object,System.String)">
+            <summary>
+            Asserts that collection contains actual as an item.
+            </summary>
+            <param name="collection">IEnumerable of objects to be considered</param>
+            <param name="actual">Object to be found within collection</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.Contains(System.Collections.IEnumerable,System.Object,System.String,System.Object[])">
+            <summary>
+            Asserts that collection contains actual as an item.
+            </summary>
+            <param name="collection">IEnumerable of objects to be considered</param>
+            <param name="actual">Object to be found within collection</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.DoesNotContain(System.Collections.IEnumerable,System.Object)">
+            <summary>
+            Asserts that collection does not contain actual as an item.
+            </summary>
+            <param name="collection">IEnumerable of objects to be considered</param>
+            <param name="actual">Object that cannot exist within collection</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.DoesNotContain(System.Collections.IEnumerable,System.Object,System.String)">
+            <summary>
+            Asserts that collection does not contain actual as an item.
+            </summary>
+            <param name="collection">IEnumerable of objects to be considered</param>
+            <param name="actual">Object that cannot exist within collection</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.DoesNotContain(System.Collections.IEnumerable,System.Object,System.String,System.Object[])">
+            <summary>
+            Asserts that collection does not contain actual as an item.
+            </summary>
+            <param name="collection">IEnumerable of objects to be considered</param>
+            <param name="actual">Object that cannot exist within collection</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.IsNotSubsetOf(System.Collections.IEnumerable,System.Collections.IEnumerable)">
+            <summary>
+            Asserts that superset is not a subject of subset.
+            </summary>
+            <param name="subset">The IEnumerable superset to be considered</param>
+            <param name="superset">The IEnumerable subset to be considered</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.IsNotSubsetOf(System.Collections.IEnumerable,System.Collections.IEnumerable,System.String)">
+            <summary>
+            Asserts that superset is not a subject of subset.
+            </summary>
+            <param name="subset">The IEnumerable superset to be considered</param>
+            <param name="superset">The IEnumerable subset to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.IsNotSubsetOf(System.Collections.IEnumerable,System.Collections.IEnumerable,System.String,System.Object[])">
+            <summary>
+            Asserts that superset is not a subject of subset.
+            </summary>
+            <param name="subset">The IEnumerable superset to be considered</param>
+            <param name="superset">The IEnumerable subset to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.IsSubsetOf(System.Collections.IEnumerable,System.Collections.IEnumerable)">
+            <summary>
+            Asserts that superset is a subset of subset.
+            </summary>
+            <param name="subset">The IEnumerable superset to be considered</param>
+            <param name="superset">The IEnumerable subset to be considered</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.IsSubsetOf(System.Collections.IEnumerable,System.Collections.IEnumerable,System.String)">
+            <summary>
+            Asserts that superset is a subset of subset.
+            </summary>
+            <param name="subset">The IEnumerable superset to be considered</param>
+            <param name="superset">The IEnumerable subset to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.IsSubsetOf(System.Collections.IEnumerable,System.Collections.IEnumerable,System.String,System.Object[])">
+            <summary>
+            Asserts that superset is a subset of subset.
+            </summary>
+            <param name="subset">The IEnumerable superset to be considered</param>
+            <param name="superset">The IEnumerable subset to be considered</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.IsEmpty(System.Collections.IEnumerable,System.String,System.Object[])">
+            <summary>
+            Assert that an array, list or other collection is empty
+            </summary>
+            <param name="collection">An array, list or other collection implementing IEnumerable</param>
+            <param name="message">The message to be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.IsEmpty(System.Collections.IEnumerable,System.String)">
+            <summary>
+            Assert that an array, list or other collection is empty
+            </summary>
+            <param name="collection">An array, list or other collection implementing IEnumerable</param>
+            <param name="message">The message to be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.IsEmpty(System.Collections.IEnumerable)">
+            <summary>
+            Assert that an array,list or other collection is empty
+            </summary>
+            <param name="collection">An array, list or other collection implementing IEnumerable</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.IsNotEmpty(System.Collections.IEnumerable,System.String,System.Object[])">
+            <summary>
+            Assert that an array, list or other collection is empty
+            </summary>
+            <param name="collection">An array, list or other collection implementing IEnumerable</param>
+            <param name="message">The message to be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.IsNotEmpty(System.Collections.IEnumerable,System.String)">
+            <summary>
+            Assert that an array, list or other collection is empty
+            </summary>
+            <param name="collection">An array, list or other collection implementing IEnumerable</param>
+            <param name="message">The message to be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.IsNotEmpty(System.Collections.IEnumerable)">
+            <summary>
+            Assert that an array,list or other collection is empty
+            </summary>
+            <param name="collection">An array, list or other collection implementing IEnumerable</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.IsOrdered(System.Collections.IEnumerable,System.String,System.Object[])">
+            <summary>
+            Assert that an array, list or other collection is ordered
+            </summary>
+            <param name="collection">An array, list or other collection implementing IEnumerable</param>
+            <param name="message">The message to be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.IsOrdered(System.Collections.IEnumerable,System.String)">
+            <summary>
+            Assert that an array, list or other collection is ordered
+            </summary>
+            <param name="collection">An array, list or other collection implementing IEnumerable</param>
+            <param name="message">The message to be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.IsOrdered(System.Collections.IEnumerable)">
+            <summary>
+            Assert that an array, list or other collection is ordered
+            </summary>
+            <param name="collection">An array, list or other collection implementing IEnumerable</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.IsOrdered(System.Collections.IEnumerable,System.Collections.IComparer,System.String,System.Object[])">
+            <summary>
+            Assert that an array, list or other collection is ordered
+            </summary>
+            <param name="collection">An array, list or other collection implementing IEnumerable</param>
+            <param name="comparer">A custom comparer to perform the comparisons</param>
+            <param name="message">The message to be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.IsOrdered(System.Collections.IEnumerable,System.Collections.IComparer,System.String)">
+            <summary>
+            Assert that an array, list or other collection is ordered
+            </summary>
+            <param name="collection">An array, list or other collection implementing IEnumerable</param>
+            <param name="comparer">A custom comparer to perform the comparisons</param>
+            <param name="message">The message to be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.CollectionAssert.IsOrdered(System.Collections.IEnumerable,System.Collections.IComparer)">
+            <summary>
+            Assert that an array, list or other collection is ordered
+            </summary>
+            <param name="collection">An array, list or other collection implementing IEnumerable</param>
+            <param name="comparer">A custom comparer to perform the comparisons</param>
+        </member>
+        <member name="T:NUnit.Framework.FileAssert">
+            <summary>
+            Summary description for FileAssert.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.Equals(System.Object,System.Object)">
+            <summary>
+            The Equals method throws an AssertionException. This is done 
+            to make sure there is no mistake by calling this function.
+            </summary>
+            <param name="a"></param>
+            <param name="b"></param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.ReferenceEquals(System.Object,System.Object)">
+            <summary>
+            override the default ReferenceEquals to throw an AssertionException. This 
+            implementation makes sure there is no mistake in calling this function 
+            as part of Assert. 
+            </summary>
+            <param name="a"></param>
+            <param name="b"></param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.#ctor">
+            <summary>
+            We don't actually want any instances of this object, but some people
+            like to inherit from it to add other static methods. Hence, the
+            protected constructor disallows any instances of this object. 
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreEqual(System.IO.Stream,System.IO.Stream,System.String,System.Object[])">
+            <summary>
+            Verifies that two Streams are equal.  Two Streams are considered
+            equal if both are null, or if both have the same value byte for byte.
+            If they are not equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected Stream</param>
+            <param name="actual">The actual Stream</param>
+            <param name="message">The message to display if Streams are not equal</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreEqual(System.IO.Stream,System.IO.Stream,System.String)">
+            <summary>
+            Verifies that two Streams are equal.  Two Streams are considered
+            equal if both are null, or if both have the same value byte for byte.
+            If they are not equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected Stream</param>
+            <param name="actual">The actual Stream</param>
+            <param name="message">The message to display if objects are not equal</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreEqual(System.IO.Stream,System.IO.Stream)">
+            <summary>
+            Verifies that two Streams are equal.  Two Streams are considered
+            equal if both are null, or if both have the same value byte for byte.
+            If they are not equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected Stream</param>
+            <param name="actual">The actual Stream</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreEqual(System.IO.FileInfo,System.IO.FileInfo,System.String,System.Object[])">
+            <summary>
+            Verifies that two files are equal.  Two files are considered
+            equal if both are null, or if both have the same value byte for byte.
+            If they are not equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">A file containing the value that is expected</param>
+            <param name="actual">A file containing the actual value</param>
+            <param name="message">The message to display if Streams are not equal</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreEqual(System.IO.FileInfo,System.IO.FileInfo,System.String)">
+            <summary>
+            Verifies that two files are equal.  Two files are considered
+            equal if both are null, or if both have the same value byte for byte.
+            If they are not equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">A file containing the value that is expected</param>
+            <param name="actual">A file containing the actual value</param>
+            <param name="message">The message to display if objects are not equal</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreEqual(System.IO.FileInfo,System.IO.FileInfo)">
+            <summary>
+            Verifies that two files are equal.  Two files are considered
+            equal if both are null, or if both have the same value byte for byte.
+            If they are not equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">A file containing the value that is expected</param>
+            <param name="actual">A file containing the actual value</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreEqual(System.String,System.String,System.String,System.Object[])">
+            <summary>
+            Verifies that two files are equal.  Two files are considered
+            equal if both are null, or if both have the same value byte for byte.
+            If they are not equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The path to a file containing the value that is expected</param>
+            <param name="actual">The path to a file containing the actual value</param>
+            <param name="message">The message to display if Streams are not equal</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreEqual(System.String,System.String,System.String)">
+            <summary>
+            Verifies that two files are equal.  Two files are considered
+            equal if both are null, or if both have the same value byte for byte.
+            If they are not equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The path to a file containing the value that is expected</param>
+            <param name="actual">The path to a file containing the actual value</param>
+            <param name="message">The message to display if objects are not equal</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreEqual(System.String,System.String)">
+            <summary>
+            Verifies that two files are equal.  Two files are considered
+            equal if both are null, or if both have the same value byte for byte.
+            If they are not equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The path to a file containing the value that is expected</param>
+            <param name="actual">The path to a file containing the actual value</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreNotEqual(System.IO.Stream,System.IO.Stream,System.String,System.Object[])">
+            <summary>
+            Asserts that two Streams are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected Stream</param>
+            <param name="actual">The actual Stream</param>
+            <param name="message">The message to be displayed when the two Stream are the same.</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreNotEqual(System.IO.Stream,System.IO.Stream,System.String)">
+            <summary>
+            Asserts that two Streams are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected Stream</param>
+            <param name="actual">The actual Stream</param>
+            <param name="message">The message to be displayed when the Streams are the same.</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreNotEqual(System.IO.Stream,System.IO.Stream)">
+            <summary>
+            Asserts that two Streams are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected Stream</param>
+            <param name="actual">The actual Stream</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreNotEqual(System.IO.FileInfo,System.IO.FileInfo,System.String,System.Object[])">
+            <summary>
+            Asserts that two files are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">A file containing the value that is expected</param>
+            <param name="actual">A file containing the actual value</param>
+            <param name="message">The message to display if Streams are not equal</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreNotEqual(System.IO.FileInfo,System.IO.FileInfo,System.String)">
+            <summary>
+            Asserts that two files are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">A file containing the value that is expected</param>
+            <param name="actual">A file containing the actual value</param>
+            <param name="message">The message to display if objects are not equal</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreNotEqual(System.IO.FileInfo,System.IO.FileInfo)">
+            <summary>
+            Asserts that two files are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">A file containing the value that is expected</param>
+            <param name="actual">A file containing the actual value</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreNotEqual(System.String,System.String,System.String,System.Object[])">
+            <summary>
+            Asserts that two files are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The path to a file containing the value that is expected</param>
+            <param name="actual">The path to a file containing the actual value</param>
+            <param name="message">The message to display if Streams are not equal</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreNotEqual(System.String,System.String,System.String)">
+            <summary>
+            Asserts that two files are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The path to a file containing the value that is expected</param>
+            <param name="actual">The path to a file containing the actual value</param>
+            <param name="message">The message to display if objects are not equal</param>
+        </member>
+        <member name="M:NUnit.Framework.FileAssert.AreNotEqual(System.String,System.String)">
+            <summary>
+            Asserts that two files are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The path to a file containing the value that is expected</param>
+            <param name="actual">The path to a file containing the actual value</param>
+        </member>
+        <member name="T:NUnit.Framework.DescriptionAttribute">
+            <summary>
+            Attribute used to provide descriptive text about a 
+            test case or fixture.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.DescriptionAttribute.#ctor(System.String)">
+            <summary>
+            Construct the attribute
+            </summary>
+            <param name="description">Text describing the test</param>
+        </member>
+        <member name="P:NUnit.Framework.DescriptionAttribute.Description">
+            <summary>
+            Gets the test description
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.IExpectException">
+            <summary>
+            Interface implemented by a user fixture in order to
+            validate any expected exceptions. It is only called
+            for test methods marked with the ExpectedException
+            attribute.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.IExpectException.HandleException(System.Exception)">
+            <summary>
+            Method to handle an expected exception
+            </summary>
+            <param name="ex">The exception to be handled</param>
+        </member>
+        <member name="T:NUnit.Framework.TextMessageWriter">
+            <summary>
+            TextMessageWriter writes constraint descriptions and messages
+            in displayable form as a text stream. It tailors the display
+            of individual message components to form the standard message
+            format of NUnit assertion failure messages.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.TextMessageWriter.Pfx_Expected">
+            <summary>
+            Prefix used for the expected value line of a message
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.TextMessageWriter.Pfx_Actual">
+            <summary>
+            Prefix used for the actual value line of a message
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.TextMessageWriter.PrefixLength">
+            <summary>
+            Length of a message prefix
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.#ctor">
+            <summary>
+            Construct a TextMessageWriter
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.#ctor(System.String,System.Object[])">
+            <summary>
+            Construct a TextMessageWriter, specifying a user message
+            and optional formatting arguments.
+            </summary>
+            <param name="userMessage"></param>
+            <param name="args"></param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.WriteMessageLine(System.Int32,System.String,System.Object[])">
+            <summary>
+            Method to write single line  message with optional args, usually
+            written to precede the general failure message, at a givel 
+            indentation level.
+            </summary>
+            <param name="level">The indentation level of the message</param>
+            <param name="message">The message to be written</param>
+            <param name="args">Any arguments used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.DisplayDifferences(NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Display Expected and Actual lines for a constraint. This
+            is called by MessageWriter's default implementation of 
+            WriteMessageTo and provides the generic two-line display. 
+            </summary>
+            <param name="constraint">The constraint that failed</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.DisplayDifferences(System.Object,System.Object)">
+            <summary>
+            Display Expected and Actual lines for given values. This
+            method may be called by constraints that need more control over
+            the display of actual and expected values than is provided
+            by the default implementation.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value causing the failure</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.DisplayDifferences(System.Object,System.Object,NUnit.Framework.Constraints.Tolerance)">
+            <summary>
+            Display Expected and Actual lines for given values, including
+            a tolerance value on the expected line.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value causing the failure</param>
+            <param name="tolerance">The tolerance within which the test was made</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.DisplayStringDifferences(System.String,System.String,System.Int32,System.Boolean,System.Boolean)">
+            <summary>
+            Display the expected and actual string values on separate lines.
+            If the mismatch parameter is >=0, an additional line is displayed
+            line containing a caret that points to the mismatch point.
+            </summary>
+            <param name="expected">The expected string value</param>
+            <param name="actual">The actual string value</param>
+            <param name="mismatch">The point at which the strings don't match or -1</param>
+            <param name="ignoreCase">If true, case is ignored in string comparisons</param>
+            <param name="clipping">If true, clip the strings to fit the max line length</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.WriteConnector(System.String)">
+            <summary>
+            Writes the text for a connector.
+            </summary>
+            <param name="connector">The connector.</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.WritePredicate(System.String)">
+            <summary>
+            Writes the text for a predicate.
+            </summary>
+            <param name="predicate">The predicate.</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.WriteModifier(System.String)">
+            <summary>
+            Write the text for a modifier.
+            </summary>
+            <param name="modifier">The modifier.</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.WriteExpectedValue(System.Object)">
+            <summary>
+            Writes the text for an expected value.
+            </summary>
+            <param name="expected">The expected value.</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.WriteActualValue(System.Object)">
+            <summary>
+            Writes the text for an actual value.
+            </summary>
+            <param name="actual">The actual value.</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.WriteValue(System.Object)">
+            <summary>
+            Writes the text for a generalized value.
+            </summary>
+            <param name="val">The value.</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.WriteCollectionElements(System.Collections.ICollection,System.Int32,System.Int32)">
+            <summary>
+            Writes the text for a collection value,
+            starting at a particular point, to a max length
+            </summary>
+            <param name="collection">The collection containing elements to write.</param>
+            <param name="start">The starting point of the elements to write</param>
+            <param name="max">The maximum number of elements to write</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.WriteExpectedLine(NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Write the generic 'Expected' line for a constraint
+            </summary>
+            <param name="constraint">The constraint that failed</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.WriteExpectedLine(System.Object)">
+            <summary>
+            Write the generic 'Expected' line for a given value
+            </summary>
+            <param name="expected">The expected value</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.WriteExpectedLine(System.Object,NUnit.Framework.Constraints.Tolerance)">
+            <summary>
+            Write the generic 'Expected' line for a given value
+            and tolerance.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="tolerance">The tolerance within which the test was made</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.WriteActualLine(NUnit.Framework.Constraints.Constraint)">
+            <summary>
+            Write the generic 'Actual' line for a constraint
+            </summary>
+            <param name="constraint">The constraint for which the actual value is to be written</param>
+        </member>
+        <member name="M:NUnit.Framework.TextMessageWriter.WriteActualLine(System.Object)">
+            <summary>
+            Write the generic 'Actual' line for a given value
+            </summary>
+            <param name="actual">The actual value causing a failure</param>
+        </member>
+        <member name="P:NUnit.Framework.TextMessageWriter.MaxLineLength">
+            <summary>
+            Gets or sets the maximum line length for this writer
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.AssertionHelper">
+            <summary>
+            AssertionHelper is an optional base class for user tests,
+            allowing the use of shorter names for constraints and
+            asserts and avoiding conflict with the definition of 
+            <see cref="T:NUnit.Framework.Is"/>, from which it inherits much of its
+            behavior, in certain mock object frameworks.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.AssertionHelper.Expect(System.Object,NUnit.Framework.Constraints.IResolveConstraint)">
+            <summary>
+            Apply a constraint to an actual value, succeeding if the constraint
+            is satisfied and throwing an assertion exception on failure. Works
+            identically to <see cref="M:NUnit.Framework.Assert.That(System.Object,NUnit.Framework.Constraints.IResolveConstraint)"/>
+            </summary>
+            <param name="constraint">A Constraint to be applied</param>
+            <param name="actual">The actual value to test</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionHelper.Expect(System.Object,NUnit.Framework.Constraints.IResolveConstraint,System.String)">
+            <summary>
+            Apply a constraint to an actual value, succeeding if the constraint
+            is satisfied and throwing an assertion exception on failure. Works
+            identically to <see cref="M:NUnit.Framework.Assert.That(System.Object,NUnit.Framework.Constraints.IResolveConstraint,System.String)"/>
+            </summary>
+            <param name="constraint">A Constraint to be applied</param>
+            <param name="actual">The actual value to test</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionHelper.Expect(System.Object,NUnit.Framework.Constraints.IResolveConstraint,System.String,System.Object[])">
+            <summary>
+            Apply a constraint to an actual value, succeeding if the constraint
+            is satisfied and throwing an assertion exception on failure. Works
+            identically to <see cref="M:NUnit.Framework.Assert.That(System.Object,NUnit.Framework.Constraints.IResolveConstraint,System.String,System.Object[])"/>
+            </summary>
+            <param name="constraint">A Constraint to be applied</param>
+            <param name="actual">The actual value to test</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionHelper.Expect(NUnit.Framework.Constraints.ActualValueDelegate,NUnit.Framework.Constraints.IResolveConstraint)">
+            <summary>
+            Apply a constraint to an actual value, succeeding if the constraint
+            is satisfied and throwing an assertion exception on failure.
+            </summary>
+            <param name="expr">A Constraint expression to be applied</param>
+            <param name="del">An ActualValueDelegate returning the value to be tested</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionHelper.Expect(NUnit.Framework.Constraints.ActualValueDelegate,NUnit.Framework.Constraints.IResolveConstraint,System.String)">
+            <summary>
+            Apply a constraint to an actual value, succeeding if the constraint
+            is satisfied and throwing an assertion exception on failure.
+            </summary>
+            <param name="expr">A Constraint expression to be applied</param>
+            <param name="del">An ActualValueDelegate returning the value to be tested</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionHelper.Expect(NUnit.Framework.Constraints.ActualValueDelegate,NUnit.Framework.Constraints.IResolveConstraint,System.String,System.Object[])">
+            <summary>
+            Apply a constraint to an actual value, succeeding if the constraint
+            is satisfied and throwing an assertion exception on failure.
+            </summary>
+            <param name="del">An ActualValueDelegate returning the value to be tested</param>
+            <param name="expr">A Constraint expression to be applied</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionHelper.Expect``1(``0@,NUnit.Framework.Constraints.IResolveConstraint)">
+            <summary>
+            Apply a constraint to a referenced value, succeeding if the constraint
+            is satisfied and throwing an assertion exception on failure.
+            </summary>
+            <param name="constraint">A Constraint to be applied</param>
+            <param name="actual">The actual value to test</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionHelper.Expect``1(``0@,NUnit.Framework.Constraints.IResolveConstraint,System.String)">
+            <summary>
+            Apply a constraint to a referenced value, succeeding if the constraint
+            is satisfied and throwing an assertion exception on failure.
+            </summary>
+            <param name="constraint">A Constraint to be applied</param>
+            <param name="actual">The actual value to test</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionHelper.Expect``1(``0@,NUnit.Framework.Constraints.IResolveConstraint,System.String,System.Object[])">
+            <summary>
+            Apply a constraint to a referenced value, succeeding if the constraint
+            is satisfied and throwing an assertion exception on failure.
+            </summary>
+            <param name="expression">A Constraint to be applied</param>
+            <param name="actual">The actual value to test</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionHelper.Expect(System.Boolean,System.String,System.Object[])">
+            <summary>
+            Asserts that a condition is true. If the condition is false the method throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>. Works Identically to 
+            <see cref="M:NUnit.Framework.Assert.That(System.Boolean,System.String,System.Object[])"/>.
+            </summary> 
+            <param name="condition">The evaluated condition</param>
+            <param name="message">The message to display if the condition is false</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionHelper.Expect(System.Boolean,System.String)">
+            <summary>
+            Asserts that a condition is true. If the condition is false the method throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>. Works Identically to 
+            <see cref="M:NUnit.Framework.Assert.That(System.Boolean,System.String)"/>.
+            </summary>
+            <param name="condition">The evaluated condition</param>
+            <param name="message">The message to display if the condition is false</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionHelper.Expect(System.Boolean)">
+            <summary>
+            Asserts that a condition is true. If the condition is false the method throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>. Works Identically to <see cref="M:NUnit.Framework.Assert.That(System.Boolean)"/>.
+            </summary>
+            <param name="condition">The evaluated condition</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionHelper.Expect(NUnit.Framework.TestDelegate,NUnit.Framework.Constraints.IResolveConstraint)">
+            <summary>
+            Asserts that the code represented by a delegate throws an exception
+            that satisfies the constraint provided.
+            </summary>
+            <param name="code">A TestDelegate to be executed</param>
+            <param name="constraint">A ThrowsConstraint used in the test</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionHelper.Map(System.Collections.ICollection)">
+            <summary>
+            Returns a ListMapper based on a collection.
+            </summary>
+            <param name="original">The original collection</param>
+            <returns></returns>
+        </member>
+        <member name="T:NUnit.Framework.IncludeExcludeAttribute">
+            <summary>
+            Abstract base for Attributes that are used to include tests
+            in the test run based on environmental settings.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.IncludeExcludeAttribute.#ctor">
+            <summary>
+            Constructor with no included items specified, for use
+            with named property syntax.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.IncludeExcludeAttribute.#ctor(System.String)">
+            <summary>
+            Constructor taking one or more included items
+            </summary>
+            <param name="include">Comma-delimited list of included items</param>
+        </member>
+        <member name="P:NUnit.Framework.IncludeExcludeAttribute.Include">
+            <summary>
+            Name of the item that is needed in order for
+            a test to run. Multiple itemss may be given,
+            separated by a comma.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.IncludeExcludeAttribute.Exclude">
+            <summary>
+            Name of the item to be excluded. Multiple items
+            may be given, separated by a comma.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.IncludeExcludeAttribute.Reason">
+            <summary>
+            The reason for including or excluding the test
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.PlatformAttribute">
+            <summary>
+            PlatformAttribute is used to mark a test fixture or an
+            individual method as applying to a particular platform only.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.PlatformAttribute.#ctor">
+            <summary>
+            Constructor with no platforms specified, for use
+            with named property syntax.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.PlatformAttribute.#ctor(System.String)">
+            <summary>
+            Constructor taking one or more platforms
+            </summary>
+            <param name="platforms">Comma-deliminted list of platforms</param>
+        </member>
+        <member name="T:NUnit.Framework.CultureAttribute">
+            <summary>
+            CultureAttribute is used to mark a test fixture or an
+            individual method as applying to a particular Culture only.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.CultureAttribute.#ctor">
+            <summary>
+            Constructor with no cultures specified, for use
+            with named property syntax.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.CultureAttribute.#ctor(System.String)">
+            <summary>
+            Constructor taking one or more cultures
+            </summary>
+            <param name="cultures">Comma-deliminted list of cultures</param>
+        </member>
+        <member name="T:NUnit.Framework.SetCultureAttribute">
+            <summary>
+            Summary description for SetCultureAttribute.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.SetCultureAttribute.#ctor(System.String)">
+            <summary>
+            Construct given the name of a culture
+            </summary>
+            <param name="culture"></param>
+        </member>
+        <member name="T:NUnit.Framework.GlobalSettings">
+            <summary>
+            GlobalSettings is a place for setting default values used
+            by the framework in performing asserts.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.GlobalSettings.DefaultFloatingPointTolerance">
+            <summary>
+            Default tolerance for floating point equality
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.DirectoryAssert">
+            <summary>
+            Summary description for DirectoryAssert
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.Equals(System.Object,System.Object)">
+            <summary>
+            The Equals method throws an AssertionException. This is done 
+            to make sure there is no mistake by calling this function.
+            </summary>
+            <param name="a"></param>
+            <param name="b"></param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.ReferenceEquals(System.Object,System.Object)">
+            <summary>
+            override the default ReferenceEquals to throw an AssertionException. This 
+            implementation makes sure there is no mistake in calling this function 
+            as part of Assert. 
+            </summary>
+            <param name="a"></param>
+            <param name="b"></param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.#ctor">
+            <summary>
+            We don't actually want any instances of this object, but some people
+            like to inherit from it to add other static methods. Hence, the
+            protected constructor disallows any instances of this object. 
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.AreEqual(System.IO.DirectoryInfo,System.IO.DirectoryInfo,System.String,System.Object[])">
+            <summary>
+            Verifies that two directories are equal.  Two directories are considered
+            equal if both are null, or if both have the same value byte for byte.
+            If they are not equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">A directory containing the value that is expected</param>
+            <param name="actual">A directory containing the actual value</param>
+            <param name="message">The message to display if directories are not equal</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.AreEqual(System.IO.DirectoryInfo,System.IO.DirectoryInfo,System.String)">
+            <summary>
+            Verifies that two directories are equal.  Two directories are considered
+            equal if both are null, or if both have the same value byte for byte.
+            If they are not equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">A directory containing the value that is expected</param>
+            <param name="actual">A directory containing the actual value</param>
+            <param name="message">The message to display if directories are not equal</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.AreEqual(System.IO.DirectoryInfo,System.IO.DirectoryInfo)">
+            <summary>
+            Verifies that two directories are equal.  Two directories are considered
+            equal if both are null, or if both have the same value byte for byte.
+            If they are not equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">A directory containing the value that is expected</param>
+            <param name="actual">A directory containing the actual value</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.AreEqual(System.String,System.String,System.String,System.Object[])">
+            <summary>
+            Verifies that two directories are equal.  Two directories are considered
+            equal if both are null, or if both have the same value byte for byte.
+            If they are not equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">A directory path string containing the value that is expected</param>
+            <param name="actual">A directory path string containing the actual value</param>
+            <param name="message">The message to display if directories are not equal</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.AreEqual(System.String,System.String,System.String)">
+            <summary>
+            Verifies that two directories are equal.  Two directories are considered
+            equal if both are null, or if both have the same value byte for byte.
+            If they are not equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">A directory path string containing the value that is expected</param>
+            <param name="actual">A directory path string containing the actual value</param>
+            <param name="message">The message to display if directories are not equal</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.AreEqual(System.String,System.String)">
+            <summary>
+            Verifies that two directories are equal.  Two directories are considered
+            equal if both are null, or if both have the same value byte for byte.
+            If they are not equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">A directory path string containing the value that is expected</param>
+            <param name="actual">A directory path string containing the actual value</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.AreNotEqual(System.IO.DirectoryInfo,System.IO.DirectoryInfo,System.String,System.Object[])">
+            <summary>
+            Asserts that two directories are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">A directory containing the value that is expected</param>
+            <param name="actual">A directory containing the actual value</param>
+            <param name="message">The message to display if directories are not equal</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.AreNotEqual(System.IO.DirectoryInfo,System.IO.DirectoryInfo,System.String)">
+            <summary>
+            Asserts that two directories are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">A directory containing the value that is expected</param>
+            <param name="actual">A directory containing the actual value</param>
+            <param name="message">The message to display if directories are not equal</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.AreNotEqual(System.IO.DirectoryInfo,System.IO.DirectoryInfo)">
+            <summary>
+            Asserts that two directories are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">A directory containing the value that is expected</param>
+            <param name="actual">A directory containing the actual value</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.AreNotEqual(System.String,System.String,System.String,System.Object[])">
+            <summary>
+            Asserts that two directories are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">A directory path string containing the value that is expected</param>
+            <param name="actual">A directory path string containing the actual value</param>
+            <param name="message">The message to display if directories are equal</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.AreNotEqual(System.String,System.String,System.String)">
+            <summary>
+            Asserts that two directories are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">A directory path string containing the value that is expected</param>
+            <param name="actual">A directory path string containing the actual value</param>
+            <param name="message">The message to display if directories are equal</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.AreNotEqual(System.String,System.String)">
+            <summary>
+            Asserts that two directories are not equal. If they are equal
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">A directory path string containing the value that is expected</param>
+            <param name="actual">A directory path string containing the actual value</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.IsEmpty(System.IO.DirectoryInfo,System.String,System.Object[])">
+            <summary>
+            Asserts that the directory is empty. If it is not empty
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="directory">A directory to search</param>
+            <param name="message">The message to display if directories are not equal</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.IsEmpty(System.IO.DirectoryInfo,System.String)">
+            <summary>
+            Asserts that the directory is empty. If it is not empty
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="directory">A directory to search</param>
+            <param name="message">The message to display if directories are not equal</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.IsEmpty(System.IO.DirectoryInfo)">
+            <summary>
+            Asserts that the directory is empty. If it is not empty
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="directory">A directory to search</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.IsEmpty(System.String,System.String,System.Object[])">
+            <summary>
+            Asserts that the directory is empty. If it is not empty
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="directory">A directory to search</param>
+            <param name="message">The message to display if directories are not equal</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.IsEmpty(System.String,System.String)">
+            <summary>
+            Asserts that the directory is empty. If it is not empty
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="directory">A directory to search</param>
+            <param name="message">The message to display if directories are not equal</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.IsEmpty(System.String)">
+            <summary>
+            Asserts that the directory is empty. If it is not empty
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="directory">A directory to search</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.IsNotEmpty(System.IO.DirectoryInfo,System.String,System.Object[])">
+            <summary>
+            Asserts that the directory is not empty. If it is empty
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="directory">A directory to search</param>
+            <param name="message">The message to display if directories are not equal</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.IsNotEmpty(System.IO.DirectoryInfo,System.String)">
+            <summary>
+            Asserts that the directory is not empty. If it is empty
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="directory">A directory to search</param>
+            <param name="message">The message to display if directories are not equal</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.IsNotEmpty(System.IO.DirectoryInfo)">
+            <summary>
+            Asserts that the directory is not empty. If it is empty
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="directory">A directory to search</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.IsNotEmpty(System.String,System.String,System.Object[])">
+            <summary>
+            Asserts that the directory is not empty. If it is empty
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="directory">A directory to search</param>
+            <param name="message">The message to display if directories are not equal</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.IsNotEmpty(System.String,System.String)">
+            <summary>
+            Asserts that the directory is not empty. If it is empty
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="directory">A directory to search</param>
+            <param name="message">The message to display if directories are not equal</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.IsNotEmpty(System.String)">
+            <summary>
+            Asserts that the directory is not empty. If it is empty
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="directory">A directory to search</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.IsWithin(System.IO.DirectoryInfo,System.IO.DirectoryInfo,System.String,System.Object[])">
+            <summary>
+            Asserts that path contains actual as a subdirectory or
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="directory">A directory to search</param>
+            <param name="actual">sub-directory asserted to exist under directory</param>
+            <param name="message">The message to display if directory is not within the path</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.IsWithin(System.IO.DirectoryInfo,System.IO.DirectoryInfo,System.String)">
+            <summary>
+            Asserts that path contains actual as a subdirectory or
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="directory">A directory to search</param>
+            <param name="actual">sub-directory asserted to exist under directory</param>
+            <param name="message">The message to display if directory is not within the path</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.IsWithin(System.IO.DirectoryInfo,System.IO.DirectoryInfo)">
+            <summary>
+            Asserts that path contains actual as a subdirectory or
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="directory">A directory to search</param>
+            <param name="actual">sub-directory asserted to exist under directory</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.IsWithin(System.String,System.String,System.String,System.Object[])">
+            <summary>
+            Asserts that path contains actual as a subdirectory or
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="directory">A directory to search</param>
+            <param name="actual">sub-directory asserted to exist under directory</param>
+            <param name="message">The message to display if directory is not within the path</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.IsWithin(System.String,System.String,System.String)">
+            <summary>
+            Asserts that path contains actual as a subdirectory or
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="directory">A directory to search</param>
+            <param name="actual">sub-directory asserted to exist under directory</param>
+            <param name="message">The message to display if directory is not within the path</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.IsWithin(System.String,System.String)">
+            <summary>
+            Asserts that path contains actual as a subdirectory or
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="directory">A directory to search</param>
+            <param name="actual">sub-directory asserted to exist under directory</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.IsNotWithin(System.IO.DirectoryInfo,System.IO.DirectoryInfo,System.String,System.Object[])">
+            <summary>
+            Asserts that path does not contain actual as a subdirectory or
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="directory">A directory to search</param>
+            <param name="actual">sub-directory asserted to exist under directory</param>
+            <param name="message">The message to display if directory is not within the path</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.IsNotWithin(System.IO.DirectoryInfo,System.IO.DirectoryInfo,System.String)">
+            <summary>
+            Asserts that path does not contain actual as a subdirectory or
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="directory">A directory to search</param>
+            <param name="actual">sub-directory asserted to exist under directory</param>
+            <param name="message">The message to display if directory is not within the path</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.IsNotWithin(System.IO.DirectoryInfo,System.IO.DirectoryInfo)">
+            <summary>
+            Asserts that path does not contain actual as a subdirectory or
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="directory">A directory to search</param>
+            <param name="actual">sub-directory asserted to exist under directory</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.IsNotWithin(System.String,System.String,System.String,System.Object[])">
+            <summary>
+            Asserts that path does not contain actual as a subdirectory or
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="directory">A directory to search</param>
+            <param name="actual">sub-directory asserted to exist under directory</param>
+            <param name="message">The message to display if directory is not within the path</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.IsNotWithin(System.String,System.String,System.String)">
+            <summary>
+            Asserts that path does not contain actual as a subdirectory or
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="directory">A directory to search</param>
+            <param name="actual">sub-directory asserted to exist under directory</param>
+            <param name="message">The message to display if directory is not within the path</param>
+        </member>
+        <member name="M:NUnit.Framework.DirectoryAssert.IsNotWithin(System.String,System.String)">
+            <summary>
+            Asserts that path does not contain actual as a subdirectory or
+            an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="directory">A directory to search</param>
+            <param name="actual">sub-directory asserted to exist under directory</param>
+        </member>
+        <member name="T:NUnit.Framework.TestCaseAttribute">
+            <summary>
+            TestCaseAttribute is used to mark parameterized test cases
+            and provide them with their arguments.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.ITestCaseData">
+            <summary>
+            The ITestCaseData interface is implemented by a class
+            that is able to return complete testcases for use by
+            a parameterized test method.
+            
+            NOTE: This interface is used in both the framework
+            and the core, even though that results in two different
+            types. However, sharing the source code guarantees that
+            the various implementations will be compatible and that
+            the core is able to reflect successfully over the
+            framework implementations of ITestCaseData.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.ITestCaseData.Arguments">
+            <summary>
+            Gets the argument list to be provided to the test
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.ITestCaseData.Result">
+            <summary>
+            Gets the expected result
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.ITestCaseData.ExpectedException">
+            <summary>
+             Gets the expected exception Type
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.ITestCaseData.ExpectedExceptionName">
+            <summary>
+            Gets the FullName of the expected exception
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.ITestCaseData.TestName">
+            <summary>
+            Gets the name to be used for the test
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.ITestCaseData.Description">
+            <summary>
+            Gets the description of the test
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.ITestCaseData.Ignored">
+            <summary>
+            Gets a value indicating whether this <see cref="T:NUnit.Framework.ITestCaseData"/> is ignored.
+            </summary>
+            <value><c>true</c> if ignored; otherwise, <c>false</c>.</value>
+        </member>
+        <member name="P:NUnit.Framework.ITestCaseData.IgnoreReason">
+            <summary>
+            Gets the ignore reason.
+            </summary>
+            <value>The ignore reason.</value>
+        </member>
+        <member name="M:NUnit.Framework.TestCaseAttribute.#ctor(System.Object[])">
+            <summary>
+            Construct a TestCaseAttribute with a list of arguments.
+            This constructor is not CLS-Compliant
+            </summary>
+            <param name="arguments"></param>
+        </member>
+        <member name="M:NUnit.Framework.TestCaseAttribute.#ctor(System.Object)">
+            <summary>
+            Construct a TestCaseAttribute with a single argument
+            </summary>
+            <param name="arg"></param>
+        </member>
+        <member name="M:NUnit.Framework.TestCaseAttribute.#ctor(System.Object,System.Object)">
+            <summary>
+            Construct a TestCaseAttribute with a two arguments
+            </summary>
+            <param name="arg1"></param>
+            <param name="arg2"></param>
+        </member>
+        <member name="M:NUnit.Framework.TestCaseAttribute.#ctor(System.Object,System.Object,System.Object)">
+            <summary>
+            Construct a TestCaseAttribute with a three arguments
+            </summary>
+            <param name="arg1"></param>
+            <param name="arg2"></param>
+            <param name="arg3"></param>
+        </member>
+        <member name="P:NUnit.Framework.TestCaseAttribute.Arguments">
+            <summary>
+            Gets the list of arguments to a test case
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.TestCaseAttribute.Result">
+            <summary>
+            Gets or sets the expected result.
+            </summary>
+            <value>The result.</value>
+        </member>
+        <member name="P:NUnit.Framework.TestCaseAttribute.ExpectedException">
+            <summary>
+            Gets or sets the expected exception.
+            </summary>
+            <value>The expected exception.</value>
+        </member>
+        <member name="P:NUnit.Framework.TestCaseAttribute.ExpectedExceptionName">
+            <summary>
+            Gets or sets the name the expected exception.
+            </summary>
+            <value>The expected name of the exception.</value>
+        </member>
+        <member name="P:NUnit.Framework.TestCaseAttribute.ExpectedMessage">
+            <summary>
+            Gets or sets the expected message of the expected exception
+            </summary>
+            <value>The expected message of the exception.</value>
+        </member>
+        <member name="P:NUnit.Framework.TestCaseAttribute.MatchType">
+            <summary>
+             Gets or sets the type of match to be performed on the expected message
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.TestCaseAttribute.Description">
+            <summary>
+            Gets or sets the description.
+            </summary>
+            <value>The description.</value>
+        </member>
+        <member name="P:NUnit.Framework.TestCaseAttribute.TestName">
+            <summary>
+            Gets or sets the name of the test.
+            </summary>
+            <value>The name of the test.</value>
+        </member>
+        <member name="P:NUnit.Framework.TestCaseAttribute.Ignore">
+            <summary>
+            Gets or sets the ignored status of the test
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.TestCaseAttribute.Ignored">
+            <summary>
+            Gets or sets the ignored status of the test
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.TestCaseAttribute.IgnoreReason">
+            <summary>
+            Gets the ignore reason.
+            </summary>
+            <value>The ignore reason.</value>
+        </member>
+        <member name="T:NUnit.Framework.TestCaseData">
+            <summary>
+            The TestCaseData class represents a set of arguments
+            and other parameter info to be used for a parameterized
+            test case. It provides a number of instance modifiers
+            for use in initializing the test case.
+            
+            Note: Instance modifiers are getters that return
+            the same instance after modifying it's state.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.TestCaseData.arguments">
+            <summary>
+            The argument list to be provided to the test
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.TestCaseData.result">
+            <summary>
+            The expected result to be returned
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.TestCaseData.expectedExceptionType">
+            <summary>
+             The expected exception Type
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.TestCaseData.expectedExceptionName">
+            <summary>
+            The FullName of the expected exception
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.TestCaseData.testName">
+            <summary>
+            The name to be used for the test
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.TestCaseData.description">
+            <summary>
+            The description of the test
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.TestCaseData.properties">
+            <summary>
+            A dictionary of properties, used to add information
+            to tests without requiring the class to change.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.TestCaseData.isIgnored">
+            <summary>
+            If true, indicates that the test case is to be ignored
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.TestCaseData.ignoreReason">
+            <summary>
+            The reason for ignoring a test case
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.TestCaseData.#ctor(System.Object[])">
+            <summary>
+            Initializes a new instance of the <see cref="T:TestCaseData"/> class.
+            </summary>
+            <param name="args">The arguments.</param>
+        </member>
+        <member name="M:NUnit.Framework.TestCaseData.#ctor(System.Object)">
+            <summary>
+            Initializes a new instance of the <see cref="T:TestCaseData"/> class.
+            </summary>
+            <param name="arg">The argument.</param>
+        </member>
+        <member name="M:NUnit.Framework.TestCaseData.#ctor(System.Object,System.Object)">
+            <summary>
+            Initializes a new instance of the <see cref="T:TestCaseData"/> class.
+            </summary>
+            <param name="arg1">The first argument.</param>
+            <param name="arg2">The second argument.</param>
+        </member>
+        <member name="M:NUnit.Framework.TestCaseData.#ctor(System.Object,System.Object,System.Object)">
+            <summary>
+            Initializes a new instance of the <see cref="T:TestCaseData"/> class.
+            </summary>
+            <param name="arg1">The first argument.</param>
+            <param name="arg2">The second argument.</param>
+            <param name="arg3">The third argument.</param>
+        </member>
+        <member name="M:NUnit.Framework.TestCaseData.Returns(System.Object)">
+            <summary>
+            Sets the expected result for the test
+            </summary>
+            <param name="result">The expected result</param>
+            <returns>A modified TestCaseData</returns>
+        </member>
+        <member name="M:NUnit.Framework.TestCaseData.Throws(System.Type)">
+            <summary>
+            Sets the expected exception type for the test
+            </summary>
+            <param name="exceptionType">Type of the expected exception.</param>
+            <returns>The modified TestCaseData instance</returns>
+        </member>
+        <member name="M:NUnit.Framework.TestCaseData.Throws(System.String)">
+            <summary>
+            Sets the expected exception type for the test
+            </summary>
+            <param name="exceptionName">FullName of the expected exception.</param>
+            <returns>The modified TestCaseData instance</returns>
+        </member>
+        <member name="M:NUnit.Framework.TestCaseData.SetName(System.String)">
+            <summary>
+            Sets the name of the test case
+            </summary>
+            <returns>The modified TestCaseData instance</returns>
+        </member>
+        <member name="M:NUnit.Framework.TestCaseData.SetDescription(System.String)">
+            <summary>
+            Sets the description for the test case
+            being constructed.
+            </summary>
+            <param name="description">The description.</param>
+            <returns>The modified TestCaseData instance.</returns>
+        </member>
+        <member name="M:NUnit.Framework.TestCaseData.SetCategory(System.String)">
+            <summary>
+            Applies a category to the test
+            </summary>
+            <param name="category"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.TestCaseData.SetProperty(System.String,System.String)">
+            <summary>
+            Applies a named property to the test
+            </summary>
+            <param name="propName"></param>
+            <param name="propValue"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.TestCaseData.SetProperty(System.String,System.Int32)">
+            <summary>
+            Applies a named property to the test
+            </summary>
+            <param name="propName"></param>
+            <param name="propValue"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.TestCaseData.SetProperty(System.String,System.Double)">
+            <summary>
+            Applies a named property to the test
+            </summary>
+            <param name="propName"></param>
+            <param name="propValue"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.TestCaseData.Ignore">
+            <summary>
+            Ignores this TestCase.
+            </summary>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.TestCaseData.Ignore(System.String)">
+            <summary>
+            Ignores this TestCase, specifying the reason.
+            </summary>
+            <param name="reason">The reason.</param>
+            <returns></returns>
+        </member>
+        <member name="P:NUnit.Framework.TestCaseData.Arguments">
+            <summary>
+            Gets the argument list to be provided to the test
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.TestCaseData.Result">
+            <summary>
+            Gets the expected result
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.TestCaseData.ExpectedException">
+            <summary>
+             Gets the expected exception Type
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.TestCaseData.ExpectedExceptionName">
+            <summary>
+            Gets the FullName of the expected exception
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.TestCaseData.TestName">
+            <summary>
+            Gets the name to be used for the test
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.TestCaseData.Description">
+            <summary>
+            Gets the description of the test
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.TestCaseData.Ignored">
+            <summary>
+            Gets a value indicating whether this <see cref="T:NUnit.Framework.ITestCaseData"/> is ignored.
+            </summary>
+            <value><c>true</c> if ignored; otherwise, <c>false</c>.</value>
+        </member>
+        <member name="P:NUnit.Framework.TestCaseData.IgnoreReason">
+            <summary>
+            Gets the ignore reason.
+            </summary>
+            <value>The ignore reason.</value>
+        </member>
+        <member name="P:NUnit.Framework.TestCaseData.Categories">
+            <summary>
+            Gets a list of categories associated with this test.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.TestCaseData.Properties">
+            <summary>
+            Gets the property dictionary for this test
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.SuccessException">
+            <summary>
+            Thrown when an assertion failed.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.SuccessException.#ctor(System.String)">
+            <param name="message"></param>
+        </member>
+        <member name="M:NUnit.Framework.SuccessException.#ctor(System.String,System.Exception)">
+            <param name="message">The error message that explains 
+            the reason for the exception</param>
+            <param name="inner">The exception that caused the 
+            current exception</param>
+        </member>
+        <member name="M:NUnit.Framework.SuccessException.#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)">
+            <summary>
+            Serialization Constructor
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.InconclusiveException">
+            <summary>
+            Thrown when a test executes inconclusively.
+            </summary>
+            
+        </member>
+        <member name="M:NUnit.Framework.InconclusiveException.#ctor(System.String)">
+            <param name="message">The error message that explains 
+            the reason for the exception</param>
+        </member>
+        <member name="M:NUnit.Framework.InconclusiveException.#ctor(System.String,System.Exception)">
+            <param name="message">The error message that explains 
+            the reason for the exception</param>
+            <param name="inner">The exception that caused the 
+            current exception</param>
+        </member>
+        <member name="M:NUnit.Framework.InconclusiveException.#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)">
+            <summary>
+            Serialization Constructor
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.TestFixtureSetUpAttribute">
+            <summary>
+            Attribute used to identify a method that is 
+            called before any tests in a fixture are run.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.TestFixtureTearDownAttribute">
+            <summary>
+            Attribute used to identify a method that is called after
+            all the tests in a fixture have run. The method is 
+            guaranteed to be called, even if an exception is thrown.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.ExplicitAttribute">
+            <summary>
+            ExplicitAttribute marks a test or test fixture so that it will
+            only be run if explicitly executed from the gui or command line
+            or if it is included by use of a filter. The test will not be
+            run simply because an enclosing suite is run.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.ExplicitAttribute.#ctor">
+            <summary>
+            Default constructor
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.ExplicitAttribute.#ctor(System.String)">
+            <summary>
+            Constructor with a reason
+            </summary>
+            <param name="reason">The reason test is marked explicit</param>
+        </member>
+        <member name="P:NUnit.Framework.ExplicitAttribute.Reason">
+            <summary>
+            The reason test is marked explicit
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.AssertionException">
+            <summary>
+            Thrown when an assertion failed.
+            </summary>
+            
+        </member>
+        <member name="M:NUnit.Framework.AssertionException.#ctor(System.String)">
+            <param name="message">The error message that explains 
+            the reason for the exception</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionException.#ctor(System.String,System.Exception)">
+            <param name="message">The error message that explains 
+            the reason for the exception</param>
+            <param name="inner">The exception that caused the 
+            current exception</param>
+        </member>
+        <member name="M:NUnit.Framework.AssertionException.#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)">
+            <summary>
+            Serialization Constructor
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.IgnoreException">
+            <summary>
+            Thrown when an assertion failed.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.IgnoreException.#ctor(System.String)">
+            <param name="message"></param>
+        </member>
+        <member name="M:NUnit.Framework.IgnoreException.#ctor(System.String,System.Exception)">
+            <param name="message">The error message that explains 
+            the reason for the exception</param>
+            <param name="inner">The exception that caused the 
+            current exception</param>
+        </member>
+        <member name="M:NUnit.Framework.IgnoreException.#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)">
+            <summary>
+            Serialization Constructor
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.MessageMatch">
+            <summary>
+            Enumeration indicating how the expected message parameter is to be used
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.MessageMatch.Exact">
+            Expect an exact match
+        </member>
+        <member name="F:NUnit.Framework.MessageMatch.Contains">
+            Expect a message containing the parameter string
+        </member>
+        <member name="F:NUnit.Framework.MessageMatch.Regex">
+            Match the regular expression provided as a parameter
+        </member>
+        <member name="F:NUnit.Framework.MessageMatch.StartsWith">
+            Expect a message that starts with the parameter string
+        </member>
+        <member name="T:NUnit.Framework.ExpectedExceptionAttribute">
+            <summary>
+            ExpectedExceptionAttribute
+            </summary>
+            
+        </member>
+        <member name="M:NUnit.Framework.ExpectedExceptionAttribute.#ctor">
+            <summary>
+            Constructor for a non-specific exception
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.ExpectedExceptionAttribute.#ctor(System.Type)">
+            <summary>
+            Constructor for a given type of exception
+            </summary>
+            <param name="exceptionType">The type of the expected exception</param>
+        </member>
+        <member name="M:NUnit.Framework.ExpectedExceptionAttribute.#ctor(System.String)">
+            <summary>
+            Constructor for a given exception name
+            </summary>
+            <param name="exceptionName">The full name of the expected exception</param>
+        </member>
+        <member name="P:NUnit.Framework.ExpectedExceptionAttribute.ExpectedException">
+            <summary>
+            Gets or sets the expected exception type
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.ExpectedExceptionAttribute.ExpectedExceptionName">
+            <summary>
+            Gets or sets the full Type name of the expected exception
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.ExpectedExceptionAttribute.ExpectedMessage">
+            <summary>
+            Gets or sets the expected message text
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.ExpectedExceptionAttribute.UserMessage">
+            <summary>
+            Gets or sets the user message displayed in case of failure
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.ExpectedExceptionAttribute.MatchType">
+            <summary>
+             Gets or sets the type of match to be performed on the expected message
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.ExpectedExceptionAttribute.Handler">
+            <summary>
+             Gets the name of a method to be used as an exception handler
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.IgnoreAttribute">
+            <summary>
+            Attribute used to mark a test that is to be ignored.
+            Ignored tests result in a warning message when the
+            tests are run.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.IgnoreAttribute.#ctor">
+            <summary>
+            Constructs the attribute without giving a reason 
+            for ignoring the test.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.IgnoreAttribute.#ctor(System.String)">
+            <summary>
+            Constructs the attribute giving a reason for ignoring the test
+            </summary>
+            <param name="reason">The reason for ignoring the test</param>
+        </member>
+        <member name="P:NUnit.Framework.IgnoreAttribute.Reason">
+            <summary>
+            The reason for ignoring a test
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.SetUpAttribute">
+            <summary>
+            Attribute used to mark a class that contains one-time SetUp 
+            and/or TearDown methods that apply to all the tests in a
+            namespace or an assembly.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.SuiteAttribute">
+            <summary>
+            Attribute used to mark a static (shared in VB) property
+            that returns a list of tests.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.TearDownAttribute">
+            <summary>
+            Attribute used to identify a method that is called 
+            immediately after each test is run. The method is 
+            guaranteed to be called, even if an exception is thrown.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.TestAttribute">
+            <summary>
+            Adding this attribute to a method within a <seealso cref="T:NUnit.Framework.TestFixtureAttribute"/> 
+            class makes the method callable from the NUnit test runner. There is a property 
+            called Description which is optional which you can provide a more detailed test
+            description. This class cannot be inherited.
+            </summary>
+            
+            <example>
+            [TestFixture]
+            public class Fixture
+            {
+              [Test]
+              public void MethodToTest()
+              {}
+              
+              [Test(Description = "more detailed description")]
+              publc void TestDescriptionMethod()
+              {}
+            }
+            </example>
+            
+        </member>
+        <member name="P:NUnit.Framework.TestAttribute.Description">
+            <summary>
+            Descriptive text for this test
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.TestFixtureAttribute">
+            <example>
+            [TestFixture]
+            public class ExampleClass 
+            {}
+            </example>
+        </member>
+        <member name="M:NUnit.Framework.TestFixtureAttribute.#ctor">
+            <summary>
+            Default constructor
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.TestFixtureAttribute.#ctor(System.Object[])">
+            <summary>
+            Construct with a object[] representing a set of arguments. 
+            In .NET 2.0, the arguments may later be separated into
+            type arguments and constructor arguments.
+            </summary>
+            <param name="arguments"></param>
+        </member>
+        <member name="P:NUnit.Framework.TestFixtureAttribute.Description">
+            <summary>
+            Descriptive text for this fixture
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.TestFixtureAttribute.Arguments">
+            <summary>
+            The arguments originally provided to the attribute
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.TestFixtureAttribute.Ignore">
+            <summary>
+            Gets or sets a value indicating whether this <see cref="T:NUnit.Framework.TestFixtureAttribute"/> should be ignored.
+            </summary>
+            <value><c>true</c> if ignore; otherwise, <c>false</c>.</value>
+        </member>
+        <member name="P:NUnit.Framework.TestFixtureAttribute.IgnoreReason">
+            <summary>
+            Gets or sets the ignore reason. May set Ignored as a side effect.
+            </summary>
+            <value>The ignore reason.</value>
+        </member>
+        <member name="P:NUnit.Framework.TestFixtureAttribute.TypeArgs">
+            <summary>
+            Get or set the type arguments. If not set
+            explicitly, any leading arguments that are
+            Types are taken as type arguments.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.RequiredAddinAttribute">
+            <summary>
+            RequiredAddinAttribute may be used to indicate the names of any addins
+            that must be present in order to run some or all of the tests in an
+            assembly. If the addin is not loaded, the entire assembly is marked
+            as NotRunnable.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.RequiredAddinAttribute.#ctor(System.String)">
+            <summary>
+            Initializes a new instance of the <see cref="T:RequiredAddinAttribute"/> class.
+            </summary>
+            <param name="requiredAddin">The required addin.</param>
+        </member>
+        <member name="P:NUnit.Framework.RequiredAddinAttribute.RequiredAddin">
+            <summary>
+            Gets the name of required addin.
+            </summary>
+            <value>The required addin name.</value>
+        </member>
+        <member name="T:NUnit.Framework.CombinatorialAttribute">
+            <summary>
+            Marks a test to use a combinatorial join of any argument data 
+            provided. NUnit will create a test case for every combination of 
+            the arguments provided. This can result in a large number of test
+            cases and so should be used judiciously. This is the default join
+            type, so the attribute need not be used except as documentation.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.CombinatorialAttribute.#ctor">
+            <summary>
+            Default constructor
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.PairwiseAttribute">
+            <summary>
+            Marks a test to use pairwise join of any argument data provided. 
+            NUnit will attempt too excercise every pair of argument values at 
+            least once, using as small a number of test cases as it can. With
+            only two arguments, this is the same as a combinatorial join.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.PairwiseAttribute.#ctor">
+            <summary>
+            Default constructor
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.SequentialAttribute">
+            <summary>
+            Marks a test to use a sequential join of any argument data
+            provided. NUnit will use arguements for each parameter in
+            sequence, generating test cases up to the largest number
+            of argument values provided and using null for any arguments
+            for which it runs out of values. Normally, this should be
+            used with the same number of arguments for each parameter.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.SequentialAttribute.#ctor">
+            <summary>
+            Default constructor
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.ParameterDataAttribute">
+            <summary>
+            Abstract base class for attributes that apply to parameters 
+            and supply data for the parameter.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.ParameterDataAttribute.GetData(System.Reflection.ParameterInfo)">
+            <summary>
+            Gets the data to be provided to the specified parameter
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.ValuesAttribute">
+            <summary>
+            ValuesAttribute is used to provide literal arguments for
+            an individual parameter of a test.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.ValuesAttribute.data">
+            <summary>
+            The collection of data to be returned. Must
+            be set by any derived attribute classes.
+            We use an object[] so that the individual
+            elements may have their type changed in GetData
+            if necessary.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.ValuesAttribute.#ctor(System.Object)">
+            <summary>
+            Construct with one argument
+            </summary>
+            <param name="arg1"></param>
+        </member>
+        <member name="M:NUnit.Framework.ValuesAttribute.#ctor(System.Object,System.Object)">
+            <summary>
+            Construct with two arguments
+            </summary>
+            <param name="arg1"></param>
+            <param name="arg2"></param>
+        </member>
+        <member name="M:NUnit.Framework.ValuesAttribute.#ctor(System.Object,System.Object,System.Object)">
+            <summary>
+            Construct with three arguments
+            </summary>
+            <param name="arg1"></param>
+            <param name="arg2"></param>
+            <param name="arg3"></param>
+        </member>
+        <member name="M:NUnit.Framework.ValuesAttribute.#ctor(System.Object[])">
+            <summary>
+            Construct with an array of arguments
+            </summary>
+            <param name="args"></param>
+        </member>
+        <member name="M:NUnit.Framework.ValuesAttribute.GetData(System.Reflection.ParameterInfo)">
+            <summary>
+            Get the collection of values to be used as arguments
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.RandomAttribute">
+            <summary>
+            RandomAttribute is used to supply a set of random values
+            to a single parameter of a parameterized test.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.RandomAttribute.#ctor(System.Int32)">
+            <summary>
+            Construct a set of doubles from 0.0 to 1.0,
+            specifying only the count.
+            </summary>
+            <param name="count"></param>
+        </member>
+        <member name="M:NUnit.Framework.RandomAttribute.#ctor(System.Double,System.Double,System.Int32)">
+            <summary>
+            Construct a set of doubles from min to max
+            </summary>
+            <param name="min"></param>
+            <param name="max"></param>
+            <param name="count"></param>
+        </member>
+        <member name="M:NUnit.Framework.RandomAttribute.#ctor(System.Int32,System.Int32,System.Int32)">
+            <summary>
+            Construct a set of ints from min to max
+            </summary>
+            <param name="min"></param>
+            <param name="max"></param>
+            <param name="count"></param>
+        </member>
+        <member name="M:NUnit.Framework.RandomAttribute.GetData(System.Reflection.ParameterInfo)">
+            <summary>
+            Get the collection of values to be used as arguments
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.RangeAttribute">
+            <summary>
+            RangeAttribute is used to supply a range of values to an
+            individual parameter of a parameterized test.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.RangeAttribute.#ctor(System.Int32,System.Int32)">
+            <summary>
+            Construct a range of ints using default step of 1
+            </summary>
+            <param name="from"></param>
+            <param name="to"></param>
+        </member>
+        <member name="M:NUnit.Framework.RangeAttribute.#ctor(System.Int32,System.Int32,System.Int32)">
+            <summary>
+            Construct a range of ints specifying the step size 
+            </summary>
+            <param name="from"></param>
+            <param name="to"></param>
+            <param name="step"></param>
+        </member>
+        <member name="M:NUnit.Framework.RangeAttribute.#ctor(System.Int64,System.Int64,System.Int64)">
+            <summary>
+            Construct a range of longs
+            </summary>
+            <param name="from"></param>
+            <param name="to"></param>
+            <param name="step"></param>
+        </member>
+        <member name="M:NUnit.Framework.RangeAttribute.#ctor(System.Double,System.Double,System.Double)">
+            <summary>
+            Construct a range of doubles
+            </summary>
+            <param name="from"></param>
+            <param name="to"></param>
+            <param name="step"></param>
+        </member>
+        <member name="M:NUnit.Framework.RangeAttribute.#ctor(System.Single,System.Single,System.Single)">
+            <summary>
+            Construct a range of floats
+            </summary>
+            <param name="from"></param>
+            <param name="to"></param>
+            <param name="step"></param>
+        </member>
+        <member name="T:NUnit.Framework.Has">
+            <summary>
+            Helper class with properties and methods that supply
+            a number of constraints used in Asserts.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Has.Property(System.String)">
+            <summary>
+            Returns a new PropertyConstraintExpression, which will either
+            test for the existence of the named property on the object
+            being tested or apply any following constraint to that property.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Has.Attribute(System.Type)">
+            <summary>
+            Returns a new AttributeConstraint checking for the
+            presence of a particular attribute on an object.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Has.Attribute``1">
+            <summary>
+            Returns a new AttributeConstraint checking for the
+            presence of a particular attribute on an object.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Has.Member(System.Object)">
+            <summary>
+            Returns a new CollectionContainsConstraint checking for the
+            presence of a particular object in the collection.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Has.No">
+            <summary>
+            Returns a ConstraintExpression that negates any
+            following constraint.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Has.All">
+            <summary>
+            Returns a ConstraintExpression, which will apply
+            the following constraint to all members of a collection,
+            succeeding if all of them succeed.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Has.Some">
+            <summary>
+            Returns a ConstraintExpression, which will apply
+            the following constraint to all members of a collection,
+            succeeding if at least one of them succeeds.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Has.None">
+            <summary>
+            Returns a ConstraintExpression, which will apply
+            the following constraint to all members of a collection,
+            succeeding if all of them fail.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Has.Length">
+            <summary>
+            Returns a new ConstraintExpression, which will apply the following
+            constraint to the Length property of the object being tested.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Has.Count">
+            <summary>
+            Returns a new ConstraintExpression, which will apply the following
+            constraint to the Count property of the object being tested.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Has.Message">
+            <summary>
+            Returns a new ConstraintExpression, which will apply the following
+            constraint to the Message property of the object being tested.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Has.InnerException">
+            <summary>
+            Returns a new ConstraintExpression, which will apply the following
+            constraint to the InnerException property of the object being tested.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Is">
+            <summary>
+            Helper class with properties and methods that supply
+            a number of constraints used in Asserts.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Is.EqualTo(System.Object)">
+            <summary>
+            Returns a constraint that tests two items for equality
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Is.SameAs(System.Object)">
+            <summary>
+            Returns a constraint that tests that two references are the same object
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Is.GreaterThan(System.Object)">
+            <summary>
+            Returns a constraint that tests whether the
+            actual value is greater than the suppled argument
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Is.GreaterThanOrEqualTo(System.Object)">
+            <summary>
+            Returns a constraint that tests whether the
+            actual value is greater than or equal to the suppled argument
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Is.AtLeast(System.Object)">
+            <summary>
+            Returns a constraint that tests whether the
+            actual value is greater than or equal to the suppled argument
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Is.LessThan(System.Object)">
+            <summary>
+            Returns a constraint that tests whether the
+            actual value is less than the suppled argument
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Is.LessThanOrEqualTo(System.Object)">
+            <summary>
+            Returns a constraint that tests whether the
+            actual value is less than or equal to the suppled argument
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Is.AtMost(System.Object)">
+            <summary>
+            Returns a constraint that tests whether the
+            actual value is less than or equal to the suppled argument
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Is.TypeOf(System.Type)">
+            <summary>
+            Returns a constraint that tests whether the actual
+            value is of the exact type supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Is.TypeOf``1">
+            <summary>
+            Returns a constraint that tests whether the actual
+            value is of the exact type supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Is.InstanceOf(System.Type)">
+            <summary>
+            Returns a constraint that tests whether the actual value
+            is of the type supplied as an argument or a derived type.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Is.InstanceOf``1">
+            <summary>
+            Returns a constraint that tests whether the actual value
+            is of the type supplied as an argument or a derived type.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Is.InstanceOfType(System.Type)">
+            <summary>
+            Returns a constraint that tests whether the actual value
+            is of the type supplied as an argument or a derived type.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Is.InstanceOfType``1">
+            <summary>
+            Returns a constraint that tests whether the actual value
+            is of the type supplied as an argument or a derived type.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Is.AssignableFrom(System.Type)">
+            <summary>
+            Returns a constraint that tests whether the actual value
+            is assignable from the type supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Is.AssignableFrom``1">
+            <summary>
+            Returns a constraint that tests whether the actual value
+            is assignable from the type supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Is.AssignableTo(System.Type)">
+            <summary>
+            Returns a constraint that tests whether the actual value
+            is assignable from the type supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Is.AssignableTo``1">
+            <summary>
+            Returns a constraint that tests whether the actual value
+            is assignable from the type supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Is.EquivalentTo(System.Collections.IEnumerable)">
+            <summary>
+            Returns a constraint that tests whether the actual value
+            is a collection containing the same elements as the 
+            collection supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Is.SubsetOf(System.Collections.IEnumerable)">
+            <summary>
+            Returns a constraint that tests whether the actual value
+            is a subset of the collection supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Is.StringContaining(System.String)">
+            <summary>
+            Returns a constraint that succeeds if the actual
+            value contains the substring supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Is.StringStarting(System.String)">
+            <summary>
+            Returns a constraint that succeeds if the actual
+            value starts with the substring supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Is.StringEnding(System.String)">
+            <summary>
+            Returns a constraint that succeeds if the actual
+            value ends with the substring supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Is.StringMatching(System.String)">
+            <summary>
+            Returns a constraint that succeeds if the actual
+            value matches the Regex pattern supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Is.SamePath(System.String)">
+            <summary>
+            Returns a constraint that tests whether the path provided 
+            is the same as an expected path after canonicalization.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Is.SamePathOrUnder(System.String)">
+            <summary>
+            Returns a constraint that tests whether the path provided 
+            is the same path or under an expected path after canonicalization.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Is.InRange(System.IComparable,System.IComparable)">
+            <summary>
+            Returns a constraint that tests whether the actual value falls 
+            within a specified range.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Is.Not">
+            <summary>
+            Returns a ConstraintExpression that negates any
+            following constraint.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Is.All">
+            <summary>
+            Returns a ConstraintExpression, which will apply
+            the following constraint to all members of a collection,
+            succeeding if all of them succeed.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Is.Null">
+            <summary>
+            Returns a constraint that tests for null
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Is.True">
+            <summary>
+            Returns a constraint that tests for True
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Is.False">
+            <summary>
+            Returns a constraint that tests for False
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Is.NaN">
+            <summary>
+            Returns a constraint that tests for NaN
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Is.Empty">
+            <summary>
+            Returns a constraint that tests for empty
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Is.Unique">
+            <summary>
+            Returns a constraint that tests whether a collection 
+            contains all unique items.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Is.BinarySerializable">
+            <summary>
+            Returns a constraint that tests whether an object graph is serializable in binary format.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Is.XmlSerializable">
+            <summary>
+            Returns a constraint that tests whether an object graph is serializable in xml format.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Is.Ordered">
+            <summary>
+            Returns a constraint that tests whether a collection is ordered
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.List">
+            <summary>
+            The List class is a helper class with properties and methods
+            that supply a number of constraints used with lists and collections.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.List.Map(System.Collections.ICollection)">
+            <summary>
+            List.Map returns a ListMapper, which can be used to map
+            the original collection to another collection.
+            </summary>
+            <param name="actual"></param>
+            <returns></returns>
+        </member>
+        <member name="T:NUnit.Framework.ListMapper">
+            <summary>
+            ListMapper is used to transform a collection used as an actual argument
+            producing another collection to be used in the assertion.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.ListMapper.#ctor(System.Collections.ICollection)">
+            <summary>
+            Construct a ListMapper based on a collection
+            </summary>
+            <param name="original">The collection to be transformed</param>
+        </member>
+        <member name="M:NUnit.Framework.ListMapper.Property(System.String)">
+            <summary>
+            Produces a collection containing all the values of a property
+            </summary>
+            <param name="name">The collection of property values</param>
+            <returns></returns>
+        </member>
+        <member name="T:NUnit.Framework.Text">
+            <summary>
+            Helper class with static methods used to supply constraints
+            that operate on strings.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Text.Contains(System.String)">
+            <summary>
+            Returns a constraint that succeeds if the actual
+            value contains the substring supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Text.DoesNotContain(System.String)">
+            <summary>
+            Returns a constraint that fails if the actual
+            value contains the substring supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Text.StartsWith(System.String)">
+            <summary>
+            Returns a constraint that succeeds if the actual
+            value starts with the substring supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Text.DoesNotStartWith(System.String)">
+            <summary>
+            Returns a constraint that fails if the actual
+            value starts with the substring supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Text.EndsWith(System.String)">
+            <summary>
+            Returns a constraint that succeeds if the actual
+            value ends with the substring supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Text.DoesNotEndWith(System.String)">
+            <summary>
+            Returns a constraint that fails if the actual
+            value ends with the substring supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Text.Matches(System.String)">
+            <summary>
+            Returns a constraint that succeeds if the actual
+            value matches the Regex pattern supplied as an argument.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Text.DoesNotMatch(System.String)">
+            <summary>
+            Returns a constraint that fails if the actual
+            value matches the pattern supplied as an argument.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Text.All">
+            <summary>
+            Returns a ConstraintExpression, which will apply
+            the following constraint to all members of a collection,
+            succeeding if all of them succeed.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Throws">
+            <summary>
+            Helper class with properties and methods that supply
+            constraints that operate on exceptions.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Throws.TypeOf(System.Type)">
+            <summary>
+            Creates a constraint specifying the exact type of exception expected
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Throws.TypeOf``1">
+            <summary>
+            Creates a constraint specifying the exact type of exception expected
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Throws.InstanceOf(System.Type)">
+            <summary>
+            Creates a constraint specifying the type of exception expected
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Throws.InstanceOf``1">
+            <summary>
+            Creates a constraint specifying the type of exception expected
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Throws.Exception">
+            <summary>
+            Creates a constraint specifying an expected exception
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Throws.InnerException">
+            <summary>
+            Creates a constraint specifying an exception with a given InnerException
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Throws.TargetInvocationException">
+            <summary>
+            Creates a constraint specifying an expected TargetInvocationException
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Throws.ArgumentException">
+            <summary>
+            Creates a constraint specifying an expected TargetInvocationException
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Throws.InvalidOperationException">
+            <summary>
+            Creates a constraint specifying an expected TargetInvocationException
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Throws.Nothing">
+            <summary>
+            Creates a constraint specifying that no exception is thrown
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.TestCaseSourceAttribute">
+            <summary>
+            FactoryAttribute indicates the source to be used to
+            provide test cases for a test method.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.TestCaseSourceAttribute.#ctor(System.String)">
+            <summary>
+            Construct with the name of the factory - for use with languages
+            that don't support params arrays.
+            </summary>
+            <param name="sourceName">An array of the names of the factories that will provide data</param>
+        </member>
+        <member name="M:NUnit.Framework.TestCaseSourceAttribute.#ctor(System.Type,System.String)">
+            <summary>
+            Construct with a Type and name - for use with languages
+            that don't support params arrays.
+            </summary>
+            <param name="sourceType">The Type that will provide data</param>
+            <param name="sourceName">The name of the method, property or field that will provide data</param>
+        </member>
+        <member name="P:NUnit.Framework.TestCaseSourceAttribute.SourceName">
+            <summary>
+            The name of a the method, property or fiend to be used as a source
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.TestCaseSourceAttribute.SourceType">
+            <summary>
+            A Type to be used as a source
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.ValueSourceAttribute">
+            <summary>
+            ValueSourceAttribute indicates the source to be used to
+            provide data for one parameter of a test method.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.ValueSourceAttribute.#ctor(System.String)">
+            <summary>
+            Construct with the name of the factory - for use with languages
+            that don't support params arrays.
+            </summary>
+            <param name="sourceName">The name of the data source to be used</param>
+        </member>
+        <member name="M:NUnit.Framework.ValueSourceAttribute.#ctor(System.Type,System.String)">
+            <summary>
+            Construct with a Type and name - for use with languages
+            that don't support params arrays.
+            </summary>
+            <param name="sourceType">The Type that will provide data</param>
+            <param name="sourceName">The name of the method, property or field that will provide data</param>
+        </member>
+        <member name="P:NUnit.Framework.ValueSourceAttribute.SourceName">
+            <summary>
+            The name of a the method, property or fiend to be used as a source
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.ValueSourceAttribute.SourceType">
+            <summary>
+            A Type to be used as a source
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Iz">
+            <summary>
+            The Iz class is a synonym for Is intended for use in VB,
+            which regards Is as a keyword.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.TimeoutAttribute">
+            <summary>
+            WUsed on a method, marks the test with a timeout value in milliseconds. 
+            The test will be run in a separate thread and is cancelled if the timeout 
+            is exceeded. Used on a method or assembly, sets the default timeout 
+            for all contained test methods.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.TimeoutAttribute.#ctor(System.Int32)">
+            <summary>
+            Construct a TimeoutAttribute given a time in milliseconds
+            </summary>
+            <param name="timeout">The timeout value in milliseconds</param>
+        </member>
+        <member name="T:NUnit.Framework.RequiresSTAAttribute">
+            <summary>
+            Marks a test that must run in the STA, causing it
+            to run in a separate thread if necessary.
+            
+            On methods, you may also use STAThreadAttribute
+            to serve the same purpose.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.RequiresSTAAttribute.#ctor">
+            <summary>
+            Construct a RequiresSTAAttribute
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.RequiresMTAAttribute">
+            <summary>
+            Marks a test that must run in the MTA, causing it
+            to run in a separate thread if necessary.
+            
+            On methods, you may also use MTAThreadAttribute
+            to serve the same purpose.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.RequiresMTAAttribute.#ctor">
+            <summary>
+            Construct a RequiresMTAAttribute
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.RequiresThreadAttribute">
+            <summary>
+            Marks a test that must run on a separate thread.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.RequiresThreadAttribute.#ctor">
+            <summary>
+            Construct a RequiresThreadAttribute
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.RequiresThreadAttribute.#ctor(System.Threading.ApartmentState)">
+            <summary>
+            Construct a RequiresThreadAttribute, specifying the apartment
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.MaxTimeAttribute">
+            <summary>
+            Summary description for MaxTimeAttribute.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.MaxTimeAttribute.#ctor(System.Int32)">
+            <summary>
+            Construct a MaxTimeAttribute, given a time in milliseconds.
+            </summary>
+            <param name="milliseconds">The maximum elapsed time in milliseconds</param>
+        </member>
+        <member name="T:NUnit.Framework.RepeatAttribute">
+            <summary>
+            RepeatAttribute may be applied to test case in order
+            to run it multiple times.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.RepeatAttribute.#ctor(System.Int32)">
+            <summary>
+            Construct a RepeatAttribute
+            </summary>
+            <param name="count">The number of times to run the test</param>
+        </member>
+        <member name="T:NUnit.Framework.Assume">
+            <summary>
+            Provides static methods to express the assumptions
+            that must be met for a test to give a meaningful
+            result. If an assumption is not met, the test
+            should produce an inconclusive result.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Assume.Equals(System.Object,System.Object)">
+            <summary>
+            The Equals method throws an AssertionException. This is done 
+            to make sure there is no mistake by calling this function.
+            </summary>
+            <param name="a"></param>
+            <param name="b"></param>
+        </member>
+        <member name="M:NUnit.Framework.Assume.ReferenceEquals(System.Object,System.Object)">
+            <summary>
+            override the default ReferenceEquals to throw an AssertionException. This 
+            implementation makes sure there is no mistake in calling this function 
+            as part of Assert. 
+            </summary>
+            <param name="a"></param>
+            <param name="b"></param>
+        </member>
+        <member name="M:NUnit.Framework.Assume.That(System.Object,NUnit.Framework.Constraints.IResolveConstraint)">
+            <summary>
+            Apply a constraint to an actual value, succeeding if the constraint
+            is satisfied and throwing an InconclusiveException on failure.
+            </summary>
+            <param name="expression">A Constraint expression to be applied</param>
+            <param name="actual">The actual value to test</param>
+        </member>
+        <member name="M:NUnit.Framework.Assume.That(System.Object,NUnit.Framework.Constraints.IResolveConstraint,System.String)">
+            <summary>
+            Apply a constraint to an actual value, succeeding if the constraint
+            is satisfied and throwing an InconclusiveException on failure.
+            </summary>
+            <param name="expression">A Constraint expression to be applied</param>
+            <param name="actual">The actual value to test</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assume.That(System.Object,NUnit.Framework.Constraints.IResolveConstraint,System.String,System.Object[])">
+            <summary>
+            Apply a constraint to an actual value, succeeding if the constraint
+            is satisfied and throwing an InconclusiveException on failure.
+            </summary>
+            <param name="expression">A Constraint expression to be applied</param>
+            <param name="actual">The actual value to test</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assume.That(NUnit.Framework.Constraints.ActualValueDelegate,NUnit.Framework.Constraints.IResolveConstraint)">
+            <summary>
+            Apply a constraint to an actual value, succeeding if the constraint
+            is satisfied and throwing an InconclusiveException on failure.
+            </summary>
+            <param name="expr">A Constraint expression to be applied</param>
+            <param name="del">An ActualValueDelegate returning the value to be tested</param>
+        </member>
+        <member name="M:NUnit.Framework.Assume.That(NUnit.Framework.Constraints.ActualValueDelegate,NUnit.Framework.Constraints.IResolveConstraint,System.String)">
+            <summary>
+            Apply a constraint to an actual value, succeeding if the constraint
+            is satisfied and throwing an InconclusiveException on failure.
+            </summary>
+            <param name="expr">A Constraint expression to be applied</param>
+            <param name="del">An ActualValueDelegate returning the value to be tested</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assume.That(NUnit.Framework.Constraints.ActualValueDelegate,NUnit.Framework.Constraints.IResolveConstraint,System.String,System.Object[])">
+            <summary>
+            Apply a constraint to an actual value, succeeding if the constraint
+            is satisfied and throwing an InconclusiveException on failure.
+            </summary>
+            <param name="del">An ActualValueDelegate returning the value to be tested</param>
+            <param name="expr">A Constraint expression to be applied</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assume.That``1(``0@,NUnit.Framework.Constraints.IResolveConstraint)">
+            <summary>
+            Apply a constraint to a referenced value, succeeding if the constraint
+            is satisfied and throwing an InconclusiveException on failure.
+            </summary>
+            <param name="expression">A Constraint expression to be applied</param>
+            <param name="actual">The actual value to test</param>
+        </member>
+        <member name="M:NUnit.Framework.Assume.That``1(``0@,NUnit.Framework.Constraints.IResolveConstraint,System.String)">
+            <summary>
+            Apply a constraint to a referenced value, succeeding if the constraint
+            is satisfied and throwing an InconclusiveException on failure.
+            </summary>
+            <param name="expression">A Constraint expression to be applied</param>
+            <param name="actual">The actual value to test</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assume.That``1(``0@,NUnit.Framework.Constraints.IResolveConstraint,System.String,System.Object[])">
+            <summary>
+            Apply a constraint to a referenced value, succeeding if the constraint
+            is satisfied and throwing an InconclusiveException on failure.
+            </summary>
+            <param name="expression">A Constraint expression to be applied</param>
+            <param name="actual">The actual value to test</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assume.That(System.Boolean,System.String,System.Object[])">
+            <summary>
+            Asserts that a condition is true. If the condition is false the method throws
+            an <see cref="T:NUnit.Framework.InconclusiveException"/>.
+            </summary> 
+            <param name="condition">The evaluated condition</param>
+            <param name="message">The message to display if the condition is false</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assume.That(System.Boolean,System.String)">
+            <summary>
+            Asserts that a condition is true. If the condition is false the method throws
+            an <see cref="T:NUnit.Framework.InconclusiveException"/>.
+            </summary>
+            <param name="condition">The evaluated condition</param>
+            <param name="message">The message to display if the condition is false</param>
+        </member>
+        <member name="M:NUnit.Framework.Assume.That(System.Boolean)">
+            <summary>
+            Asserts that a condition is true. If the condition is false the 
+            method throws an <see cref="T:NUnit.Framework.InconclusiveException"/>.
+            </summary>
+            <param name="condition">The evaluated condition</param>
+        </member>
+        <member name="M:NUnit.Framework.Assume.That(NUnit.Framework.TestDelegate,NUnit.Framework.Constraints.IResolveConstraint)">
+            <summary>
+            Asserts that the code represented by a delegate throws an exception
+            that satisfies the constraint provided.
+            </summary>
+            <param name="code">A TestDelegate to be executed</param>
+            <param name="constraint">A ThrowsConstraint used in the test</param>
+        </member>
+        <member name="T:NUnit.Framework.Randomizer">
+            <summary>
+            Randomizer returns a set of random values in a repeatable
+            way, to allow re-running of tests if necessary.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Randomizer.GetRandomizer(System.Reflection.MemberInfo)">
+            <summary>
+            Get a randomizer for a particular member, returning
+            one that has already been created if it exists.
+            This ensures that the same values are generated
+            each time the tests are reloaded.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Randomizer.GetRandomizer(System.Reflection.ParameterInfo)">
+            <summary>
+            Get a randomizer for a particular parameter, returning
+            one that has already been created if it exists.
+            This ensures that the same values are generated
+            each time the tests are reloaded.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Randomizer.#ctor">
+            <summary>
+            Construct a randomizer using a random seed
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Randomizer.#ctor(System.Int32)">
+            <summary>
+            Construct a randomizer using a specified seed
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Randomizer.GetDoubles(System.Int32)">
+            <summary>
+            Return an array of random doubles between 0.0 and 1.0.
+            </summary>
+            <param name="count"></param>
+            <returns></returns>
+        </member>
+        <member name="M:NUnit.Framework.Randomizer.GetDoubles(System.Double,System.Double,System.Int32)">
+            <summary>
+            Return an array of random doubles with values in a specified range.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Randomizer.GetInts(System.Int32,System.Int32,System.Int32)">
+            <summary>
+            Return an array of random ints with values in a specified range.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.Randomizer.RandomSeed">
+            <summary>
+            Get a random seed for use in creating a randomizer.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.TheoryAttribute">
+            <summary>
+            Adding this attribute to a method within a <seealso cref="T:NUnit.Framework.TestFixtureAttribute"/> 
+            class makes the method callable from the NUnit test runner. There is a property 
+            called Description which is optional which you can provide a more detailed test
+            description. This class cannot be inherited.
+            </summary>
+            
+            <example>
+            [TestFixture]
+            public class Fixture
+            {
+              [Test]
+              public void MethodToTest()
+              {}
+              
+              [Test(Description = "more detailed description")]
+              publc void TestDescriptionMethod()
+              {}
+            }
+            </example>
+            
+        </member>
+        <member name="T:NUnit.Framework.DatapointAttribute">
+            <summary>
+            Used to mark a field for use as a datapoint when executing a theory
+            within the same fixture that requires an argument of the field's Type.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.DatapointsAttribute">
+            <summary>
+            Used to mark an array as containing a set of datapoints to be used
+            executing a theory within the same fixture that requires an argument 
+            of the Type of the array elements.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.SpecialValue">
+            <summary>
+            The SpecialValue enum is used to represent TestCase arguments
+            that cannot be used as arguments to an Attribute.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.SpecialValue.Null">
+            <summary>
+            Null represents a null value, which cannot be used as an 
+            argument to an attriute under .NET 1.x
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.SetUICultureAttribute">
+            <summary>
+            Summary description for SetUICultureAttribute.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.SetUICultureAttribute.#ctor(System.String)">
+            <summary>
+            Construct given the name of a culture
+            </summary>
+            <param name="culture"></param>
+        </member>
+        <member name="T:NUnit.Framework.TestDelegate">
+            <summary>
+            Delegate used by tests that execute code and
+            capture any thrown exception.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Assert">
+            <summary>
+            The Assert class contains a collection of static methods that
+            implement the most common assertions used in NUnit.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Assert.#ctor">
+            <summary>
+            We don't actually want any instances of this object, but some people
+            like to inherit from it to add other static methods. Hence, the
+            protected constructor disallows any instances of this object. 
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Equals(System.Object,System.Object)">
+            <summary>
+            The Equals method throws an AssertionException. This is done 
+            to make sure there is no mistake by calling this function.
+            </summary>
+            <param name="a"></param>
+            <param name="b"></param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.ReferenceEquals(System.Object,System.Object)">
+            <summary>
+            override the default ReferenceEquals to throw an AssertionException. This 
+            implementation makes sure there is no mistake in calling this function 
+            as part of Assert. 
+            </summary>
+            <param name="a"></param>
+            <param name="b"></param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AssertDoublesAreEqual(System.Double,System.Double,System.Double,System.String,System.Object[])">
+            <summary>
+            Helper for Assert.AreEqual(double expected, double actual, ...)
+            allowing code generation to work consistently.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="delta">The maximum acceptable difference between the
+            the expected and the actual</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Pass(System.String,System.Object[])">
+            <summary>
+            Throws a <see cref="T:NUnit.Framework.SuccessException"/> with the message and arguments 
+            that are passed in. This allows a test to be cut short, with a result
+            of success returned to NUnit.
+            </summary>
+            <param name="message">The message to initialize the <see cref="T:NUnit.Framework.AssertionException"/> with.</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Pass(System.String)">
+            <summary>
+            Throws a <see cref="T:NUnit.Framework.SuccessException"/> with the message and arguments 
+            that are passed in. This allows a test to be cut short, with a result
+            of success returned to NUnit.
+            </summary>
+            <param name="message">The message to initialize the <see cref="T:NUnit.Framework.AssertionException"/> with.</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Pass">
+            <summary>
+            Throws a <see cref="T:NUnit.Framework.SuccessException"/> with the message and arguments 
+            that are passed in. This allows a test to be cut short, with a result
+            of success returned to NUnit.
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Fail(System.String,System.Object[])">
+            <summary>
+            Throws an <see cref="T:NUnit.Framework.AssertionException"/> with the message and arguments 
+            that are passed in. This is used by the other Assert functions. 
+            </summary>
+            <param name="message">The message to initialize the <see cref="T:NUnit.Framework.AssertionException"/> with.</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Fail(System.String)">
+            <summary>
+            Throws an <see cref="T:NUnit.Framework.AssertionException"/> with the message that is 
+            passed in. This is used by the other Assert functions. 
+            </summary>
+            <param name="message">The message to initialize the <see cref="T:NUnit.Framework.AssertionException"/> with.</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Fail">
+            <summary>
+            Throws an <see cref="T:NUnit.Framework.AssertionException"/>. 
+            This is used by the other Assert functions. 
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Ignore(System.String,System.Object[])">
+            <summary>
+            Throws an <see cref="T:NUnit.Framework.IgnoreException"/> with the message and arguments 
+            that are passed in.  This causes the test to be reported as ignored.
+            </summary>
+            <param name="message">The message to initialize the <see cref="T:NUnit.Framework.AssertionException"/> with.</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Ignore(System.String)">
+            <summary>
+            Throws an <see cref="T:NUnit.Framework.IgnoreException"/> with the message that is 
+            passed in. This causes the test to be reported as ignored. 
+            </summary>
+            <param name="message">The message to initialize the <see cref="T:NUnit.Framework.AssertionException"/> with.</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Ignore">
+            <summary>
+            Throws an <see cref="T:NUnit.Framework.IgnoreException"/>. 
+            This causes the test to be reported as ignored. 
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Inconclusive(System.String,System.Object[])">
+            <summary>
+            Throws an <see cref="T:NUnit.Framework.InconclusiveException"/> with the message and arguments 
+            that are passed in.  This causes the test to be reported as inconclusive.
+            </summary>
+            <param name="message">The message to initialize the <see cref="T:NUnit.Framework.InconclusiveException"/> with.</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Inconclusive(System.String)">
+            <summary>
+            Throws an <see cref="T:NUnit.Framework.InconclusiveException"/> with the message that is 
+            passed in. This causes the test to be reported as inconclusive. 
+            </summary>
+            <param name="message">The message to initialize the <see cref="T:NUnit.Framework.InconclusiveException"/> with.</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Inconclusive">
+            <summary>
+            Throws an <see cref="T:NUnit.Framework.InconclusiveException"/>. 
+            This causes the test to be reported as Inconclusive. 
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Assert.That(System.Object,NUnit.Framework.Constraints.IResolveConstraint)">
+            <summary>
+            Apply a constraint to an actual value, succeeding if the constraint
+            is satisfied and throwing an assertion exception on failure.
+            </summary>
+            <param name="expression">A Constraint to be applied</param>
+            <param name="actual">The actual value to test</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.That(System.Object,NUnit.Framework.Constraints.IResolveConstraint,System.String)">
+            <summary>
+            Apply a constraint to an actual value, succeeding if the constraint
+            is satisfied and throwing an assertion exception on failure.
+            </summary>
+            <param name="expression">A Constraint to be applied</param>
+            <param name="actual">The actual value to test</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.That(System.Object,NUnit.Framework.Constraints.IResolveConstraint,System.String,System.Object[])">
+            <summary>
+            Apply a constraint to an actual value, succeeding if the constraint
+            is satisfied and throwing an assertion exception on failure.
+            </summary>
+            <param name="expression">A Constraint expression to be applied</param>
+            <param name="actual">The actual value to test</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.That(NUnit.Framework.Constraints.ActualValueDelegate,NUnit.Framework.Constraints.IResolveConstraint)">
+            <summary>
+            Apply a constraint to an actual value, succeeding if the constraint
+            is satisfied and throwing an assertion exception on failure.
+            </summary>
+            <param name="expr">A Constraint expression to be applied</param>
+            <param name="del">An ActualValueDelegate returning the value to be tested</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.That(NUnit.Framework.Constraints.ActualValueDelegate,NUnit.Framework.Constraints.IResolveConstraint,System.String)">
+            <summary>
+            Apply a constraint to an actual value, succeeding if the constraint
+            is satisfied and throwing an assertion exception on failure.
+            </summary>
+            <param name="expr">A Constraint expression to be applied</param>
+            <param name="del">An ActualValueDelegate returning the value to be tested</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.That(NUnit.Framework.Constraints.ActualValueDelegate,NUnit.Framework.Constraints.IResolveConstraint,System.String,System.Object[])">
+            <summary>
+            Apply a constraint to an actual value, succeeding if the constraint
+            is satisfied and throwing an assertion exception on failure.
+            </summary>
+            <param name="del">An ActualValueDelegate returning the value to be tested</param>
+            <param name="expr">A Constraint expression to be applied</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.That``1(``0@,NUnit.Framework.Constraints.IResolveConstraint)">
+            <summary>
+            Apply a constraint to a referenced value, succeeding if the constraint
+            is satisfied and throwing an assertion exception on failure.
+            </summary>
+            <param name="expression">A Constraint to be applied</param>
+            <param name="actual">The actual value to test</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.That``1(``0@,NUnit.Framework.Constraints.IResolveConstraint,System.String)">
+            <summary>
+            Apply a constraint to a referenced value, succeeding if the constraint
+            is satisfied and throwing an assertion exception on failure.
+            </summary>
+            <param name="expression">A Constraint to be applied</param>
+            <param name="actual">The actual value to test</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.That``1(``0@,NUnit.Framework.Constraints.IResolveConstraint,System.String,System.Object[])">
+            <summary>
+            Apply a constraint to a referenced value, succeeding if the constraint
+            is satisfied and throwing an assertion exception on failure.
+            </summary>
+            <param name="expression">A Constraint to be applied</param>
+            <param name="actual">The actual value to test</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.That(System.Boolean,System.String,System.Object[])">
+            <summary>
+            Asserts that a condition is true. If the condition is false the method throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>.
+            </summary> 
+            <param name="condition">The evaluated condition</param>
+            <param name="message">The message to display if the condition is false</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.That(System.Boolean,System.String)">
+            <summary>
+            Asserts that a condition is true. If the condition is false the method throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>.
+            </summary>
+            <param name="condition">The evaluated condition</param>
+            <param name="message">The message to display if the condition is false</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.That(System.Boolean)">
+            <summary>
+            Asserts that a condition is true. If the condition is false the method throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>.
+            </summary>
+            <param name="condition">The evaluated condition</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.That(NUnit.Framework.TestDelegate,NUnit.Framework.Constraints.IResolveConstraint)">
+            <summary>
+            Asserts that the code represented by a delegate throws an exception
+            that satisfies the constraint provided.
+            </summary>
+            <param name="code">A TestDelegate to be executed</param>
+            <param name="constraint">A ThrowsConstraint used in the test</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Throws(NUnit.Framework.Constraints.IResolveConstraint,NUnit.Framework.TestDelegate,System.String,System.Object[])">
+            <summary>
+            Verifies that a delegate throws a particular exception when called.
+            </summary>
+            <param name="expression">A constraint to be satisfied by the exception</param>
+            <param name="code">A TestSnippet delegate</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Throws(NUnit.Framework.Constraints.IResolveConstraint,NUnit.Framework.TestDelegate,System.String)">
+            <summary>
+            Verifies that a delegate throws a particular exception when called.
+            </summary>
+            <param name="expression">A constraint to be satisfied by the exception</param>
+            <param name="code">A TestSnippet delegate</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Throws(NUnit.Framework.Constraints.IResolveConstraint,NUnit.Framework.TestDelegate)">
+            <summary>
+            Verifies that a delegate throws a particular exception when called.
+            </summary>
+            <param name="expression">A constraint to be satisfied by the exception</param>
+            <param name="code">A TestSnippet delegate</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Throws(System.Type,NUnit.Framework.TestDelegate,System.String,System.Object[])">
+            <summary>
+            Verifies that a delegate throws a particular exception when called.
+            </summary>
+            <param name="expectedExceptionType">The exception Type expected</param>
+            <param name="code">A TestSnippet delegate</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Throws(System.Type,NUnit.Framework.TestDelegate,System.String)">
+            <summary>
+            Verifies that a delegate throws a particular exception when called.
+            </summary>
+            <param name="expectedExceptionType">The exception Type expected</param>
+            <param name="code">A TestSnippet delegate</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Throws(System.Type,NUnit.Framework.TestDelegate)">
+            <summary>
+            Verifies that a delegate throws a particular exception when called.
+            </summary>
+            <param name="expectedExceptionType">The exception Type expected</param>
+            <param name="code">A TestSnippet delegate</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Throws``1(NUnit.Framework.TestDelegate,System.String,System.Object[])">
+            <summary>
+            Verifies that a delegate throws a particular exception when called.
+            </summary>
+            <typeparam name="T">Type of the expected exception</typeparam>
+            <param name="code">A TestSnippet delegate</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Throws``1(NUnit.Framework.TestDelegate,System.String)">
+            <summary>
+            Verifies that a delegate throws a particular exception when called.
+            </summary>
+            <typeparam name="T">Type of the expected exception</typeparam>
+            <param name="code">A TestSnippet delegate</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Throws``1(NUnit.Framework.TestDelegate)">
+            <summary>
+            Verifies that a delegate throws a particular exception when called.
+            </summary>
+            <typeparam name="T">Type of the expected exception</typeparam>
+            <param name="code">A TestSnippet delegate</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Catch(NUnit.Framework.TestDelegate,System.String,System.Object[])">
+            <summary>
+            Verifies that a delegate throws an exception when called
+            and returns it.
+            </summary>
+            <param name="code">A TestDelegate</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Catch(NUnit.Framework.TestDelegate,System.String)">
+            <summary>
+            Verifies that a delegate throws an exception when called
+            and returns it.
+            </summary>
+            <param name="code">A TestDelegate</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Catch(NUnit.Framework.TestDelegate)">
+            <summary>
+            Verifies that a delegate throws an exception when called
+            and returns it.
+            </summary>
+            <param name="code">A TestDelegate</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Catch(System.Type,NUnit.Framework.TestDelegate,System.String,System.Object[])">
+            <summary>
+            Verifies that a delegate throws an exception of a certain Type
+            or one derived from it when called and returns it.
+            </summary>
+            <param name="expectedExceptionType">The expected Exception Type</param>
+            <param name="code">A TestDelegate</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Catch(System.Type,NUnit.Framework.TestDelegate,System.String)">
+            <summary>
+            Verifies that a delegate throws an exception of a certain Type
+            or one derived from it when called and returns it.
+            </summary>
+            <param name="expectedExceptionType">The expected Exception Type</param>
+            <param name="code">A TestDelegate</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Catch(System.Type,NUnit.Framework.TestDelegate)">
+            <summary>
+            Verifies that a delegate throws an exception of a certain Type
+            or one derived from it when called and returns it.
+            </summary>
+            <param name="expectedExceptionType">The expected Exception Type</param>
+            <param name="code">A TestDelegate</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Catch``1(NUnit.Framework.TestDelegate,System.String,System.Object[])">
+            <summary>
+            Verifies that a delegate throws an exception of a certain Type
+            or one derived from it when called and returns it.
+            </summary>
+            <typeparam name="T">The expected Exception Type</typeparam>
+            <param name="code">A TestDelegate</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Catch``1(NUnit.Framework.TestDelegate,System.String)">
+            <summary>
+            Verifies that a delegate throws an exception of a certain Type
+            or one derived from it when called and returns it.
+            </summary>
+            <typeparam name="T">The expected Exception Type</typeparam>
+            <param name="code">A TestDelegate</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Catch``1(NUnit.Framework.TestDelegate)">
+            <summary>
+            Verifies that a delegate throws an exception of a certain Type
+            or one derived from it when called and returns it.
+            </summary>
+            <typeparam name="T">The expected Exception Type</typeparam>
+            <param name="code">A TestDelegate</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.DoesNotThrow(NUnit.Framework.TestDelegate,System.String,System.Object[])">
+            <summary>
+            Verifies that a delegate does not throw an exception
+            </summary>
+            <param name="code">A TestSnippet delegate</param>
+            <param name="message">The message that will be displayed on failure</param>
+            <param name="args">Arguments to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.DoesNotThrow(NUnit.Framework.TestDelegate,System.String)">
+            <summary>
+            Verifies that a delegate does not throw an exception.
+            </summary>
+            <param name="code">A TestSnippet delegate</param>
+            <param name="message">The message that will be displayed on failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.DoesNotThrow(NUnit.Framework.TestDelegate)">
+            <summary>
+            Verifies that a delegate does not throw an exception.
+            </summary>
+            <param name="code">A TestSnippet delegate</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.True(System.Boolean,System.String,System.Object[])">
+            <summary>
+            Asserts that a condition is true. If the condition is false the method throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>.
+            </summary>
+            <param name="condition">The evaluated condition</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.True(System.Boolean,System.String)">
+            <summary>
+            Asserts that a condition is true. If the condition is false the method throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>.
+            </summary>
+            <param name="condition">The evaluated condition</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.True(System.Boolean)">
+            <summary>
+            Asserts that a condition is true. If the condition is false the method throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>.
+            </summary>
+            <param name="condition">The evaluated condition</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsTrue(System.Boolean,System.String,System.Object[])">
+            <summary>
+            Asserts that a condition is true. If the condition is false the method throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>.
+            </summary>
+            <param name="condition">The evaluated condition</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsTrue(System.Boolean,System.String)">
+            <summary>
+            Asserts that a condition is true. If the condition is false the method throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>.
+            </summary>
+            <param name="condition">The evaluated condition</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsTrue(System.Boolean)">
+            <summary>
+            Asserts that a condition is true. If the condition is false the method throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>.
+            </summary>
+            <param name="condition">The evaluated condition</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.False(System.Boolean,System.String,System.Object[])">
+            <summary>
+            Asserts that a condition is false. If the condition is true the method throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>.
+            </summary> 
+            <param name="condition">The evaluated condition</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.False(System.Boolean,System.String)">
+            <summary>
+            Asserts that a condition is false. If the condition is true the method throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>.
+            </summary> 
+            <param name="condition">The evaluated condition</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.False(System.Boolean)">
+            <summary>
+            Asserts that a condition is false. If the condition is true the method throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>.
+            </summary> 
+            <param name="condition">The evaluated condition</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsFalse(System.Boolean,System.String,System.Object[])">
+            <summary>
+            Asserts that a condition is false. If the condition is true the method throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>.
+            </summary> 
+            <param name="condition">The evaluated condition</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsFalse(System.Boolean,System.String)">
+            <summary>
+            Asserts that a condition is false. If the condition is true the method throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>.
+            </summary> 
+            <param name="condition">The evaluated condition</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsFalse(System.Boolean)">
+            <summary>
+            Asserts that a condition is false. If the condition is true the method throws
+            an <see cref="T:NUnit.Framework.AssertionException"/>.
+            </summary> 
+            <param name="condition">The evaluated condition</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.NotNull(System.Object,System.String,System.Object[])">
+            <summary>
+            Verifies that the object that is passed in is not equal to <code>null</code>
+            If the object is <code>null</code> then an <see cref="T:NUnit.Framework.AssertionException"/>
+            is thrown.
+            </summary>
+            <param name="anObject">The object that is to be tested</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.NotNull(System.Object,System.String)">
+            <summary>
+            Verifies that the object that is passed in is not equal to <code>null</code>
+            If the object is <code>null</code> then an <see cref="T:NUnit.Framework.AssertionException"/>
+            is thrown.
+            </summary>
+            <param name="anObject">The object that is to be tested</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.NotNull(System.Object)">
+            <summary>
+            Verifies that the object that is passed in is not equal to <code>null</code>
+            If the object is <code>null</code> then an <see cref="T:NUnit.Framework.AssertionException"/>
+            is thrown.
+            </summary>
+            <param name="anObject">The object that is to be tested</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotNull(System.Object,System.String,System.Object[])">
+            <summary>
+            Verifies that the object that is passed in is not equal to <code>null</code>
+            If the object is <code>null</code> then an <see cref="T:NUnit.Framework.AssertionException"/>
+            is thrown.
+            </summary>
+            <param name="anObject">The object that is to be tested</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotNull(System.Object,System.String)">
+            <summary>
+            Verifies that the object that is passed in is not equal to <code>null</code>
+            If the object is <code>null</code> then an <see cref="T:NUnit.Framework.AssertionException"/>
+            is thrown.
+            </summary>
+            <param name="anObject">The object that is to be tested</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotNull(System.Object)">
+            <summary>
+            Verifies that the object that is passed in is not equal to <code>null</code>
+            If the object is <code>null</code> then an <see cref="T:NUnit.Framework.AssertionException"/>
+            is thrown.
+            </summary>
+            <param name="anObject">The object that is to be tested</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Null(System.Object,System.String,System.Object[])">
+            <summary>
+            Verifies that the object that is passed in is equal to <code>null</code>
+            If the object is not <code>null</code> then an <see cref="T:NUnit.Framework.AssertionException"/>
+            is thrown.
+            </summary>
+            <param name="anObject">The object that is to be tested</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Null(System.Object,System.String)">
+            <summary>
+            Verifies that the object that is passed in is equal to <code>null</code>
+            If the object is not <code>null</code> then an <see cref="T:NUnit.Framework.AssertionException"/>
+            is thrown.
+            </summary>
+            <param name="anObject">The object that is to be tested</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Null(System.Object)">
+            <summary>
+            Verifies that the object that is passed in is equal to <code>null</code>
+            If the object is not <code>null</code> then an <see cref="T:NUnit.Framework.AssertionException"/>
+            is thrown.
+            </summary>
+            <param name="anObject">The object that is to be tested</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNull(System.Object,System.String,System.Object[])">
+            <summary>
+            Verifies that the object that is passed in is equal to <code>null</code>
+            If the object is not <code>null</code> then an <see cref="T:NUnit.Framework.AssertionException"/>
+            is thrown.
+            </summary>
+            <param name="anObject">The object that is to be tested</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNull(System.Object,System.String)">
+            <summary>
+            Verifies that the object that is passed in is equal to <code>null</code>
+            If the object is not <code>null</code> then an <see cref="T:NUnit.Framework.AssertionException"/>
+            is thrown.
+            </summary>
+            <param name="anObject">The object that is to be tested</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNull(System.Object)">
+            <summary>
+            Verifies that the object that is passed in is equal to <code>null</code>
+            If the object is not <code>null</code> then an <see cref="T:NUnit.Framework.AssertionException"/>
+            is thrown.
+            </summary>
+            <param name="anObject">The object that is to be tested</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNaN(System.Double,System.String,System.Object[])">
+            <summary>
+            Verifies that the double that is passed in is an <code>NaN</code> value.
+            If the object is not <code>NaN</code> then an <see cref="T:NUnit.Framework.AssertionException"/>
+            is thrown.
+            </summary>
+            <param name="aDouble">The value that is to be tested</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNaN(System.Double,System.String)">
+            <summary>
+            Verifies that the double that is passed in is an <code>NaN</code> value.
+            If the object is not <code>NaN</code> then an <see cref="T:NUnit.Framework.AssertionException"/>
+            is thrown.
+            </summary>
+            <param name="aDouble">The value that is to be tested</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNaN(System.Double)">
+            <summary>
+            Verifies that the double that is passed in is an <code>NaN</code> value.
+            If the object is not <code>NaN</code> then an <see cref="T:NUnit.Framework.AssertionException"/>
+            is thrown.
+            </summary>
+            <param name="aDouble">The value that is to be tested</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNaN(System.Nullable{System.Double},System.String,System.Object[])">
+            <summary>
+            Verifies that the double that is passed in is an <code>NaN</code> value.
+            If the object is not <code>NaN</code> then an <see cref="T:NUnit.Framework.AssertionException"/>
+            is thrown.
+            </summary>
+            <param name="aDouble">The value that is to be tested</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNaN(System.Nullable{System.Double},System.String)">
+            <summary>
+            Verifies that the double that is passed in is an <code>NaN</code> value.
+            If the object is not <code>NaN</code> then an <see cref="T:NUnit.Framework.AssertionException"/>
+            is thrown.
+            </summary>
+            <param name="aDouble">The value that is to be tested</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNaN(System.Nullable{System.Double})">
+            <summary>
+            Verifies that the double that is passed in is an <code>NaN</code> value.
+            If the object is not <code>NaN</code> then an <see cref="T:NUnit.Framework.AssertionException"/>
+            is thrown.
+            </summary>
+            <param name="aDouble">The value that is to be tested</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsEmpty(System.String,System.String,System.Object[])">
+            <summary>
+            Assert that a string is empty - that is equal to string.Empty
+            </summary>
+            <param name="aString">The string to be tested</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsEmpty(System.String,System.String)">
+            <summary>
+            Assert that a string is empty - that is equal to string.Empty
+            </summary>
+            <param name="aString">The string to be tested</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsEmpty(System.String)">
+            <summary>
+            Assert that a string is empty - that is equal to string.Empty
+            </summary>
+            <param name="aString">The string to be tested</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsEmpty(System.Collections.ICollection,System.String,System.Object[])">
+            <summary>
+            Assert that an array, list or other collection is empty
+            </summary>
+            <param name="collection">An array, list or other collection implementing ICollection</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsEmpty(System.Collections.ICollection,System.String)">
+            <summary>
+            Assert that an array, list or other collection is empty
+            </summary>
+            <param name="collection">An array, list or other collection implementing ICollection</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsEmpty(System.Collections.ICollection)">
+            <summary>
+            Assert that an array, list or other collection is empty
+            </summary>
+            <param name="collection">An array, list or other collection implementing ICollection</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotEmpty(System.String,System.String,System.Object[])">
+            <summary>
+            Assert that a string is not empty - that is not equal to string.Empty
+            </summary>
+            <param name="aString">The string to be tested</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotEmpty(System.String,System.String)">
+            <summary>
+            Assert that a string is not empty - that is not equal to string.Empty
+            </summary>
+            <param name="aString">The string to be tested</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotEmpty(System.String)">
+            <summary>
+            Assert that a string is not empty - that is not equal to string.Empty
+            </summary>
+            <param name="aString">The string to be tested</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotEmpty(System.Collections.ICollection,System.String,System.Object[])">
+            <summary>
+            Assert that an array, list or other collection is not empty
+            </summary>
+            <param name="collection">An array, list or other collection implementing ICollection</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotEmpty(System.Collections.ICollection,System.String)">
+            <summary>
+            Assert that an array, list or other collection is not empty
+            </summary>
+            <param name="collection">An array, list or other collection implementing ICollection</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotEmpty(System.Collections.ICollection)">
+            <summary>
+            Assert that an array, list or other collection is not empty
+            </summary>
+            <param name="collection">An array, list or other collection implementing ICollection</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNullOrEmpty(System.String,System.String,System.Object[])">
+            <summary>
+            Assert that a string is either null or equal to string.Empty
+            </summary>
+            <param name="aString">The string to be tested</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNullOrEmpty(System.String,System.String)">
+            <summary>
+            Assert that a string is either null or equal to string.Empty
+            </summary>
+            <param name="aString">The string to be tested</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNullOrEmpty(System.String)">
+            <summary>
+            Assert that a string is either null or equal to string.Empty
+            </summary>
+            <param name="aString">The string to be tested</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotNullOrEmpty(System.String,System.String,System.Object[])">
+            <summary>
+            Assert that a string is not null or empty
+            </summary>
+            <param name="aString">The string to be tested</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotNullOrEmpty(System.String,System.String)">
+            <summary>
+            Assert that a string is not null or empty
+            </summary>
+            <param name="aString">The string to be tested</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotNullOrEmpty(System.String)">
+            <summary>
+            Assert that a string is not null or empty
+            </summary>
+            <param name="aString">The string to be tested</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsAssignableFrom(System.Type,System.Object,System.String,System.Object[])">
+            <summary>
+            Asserts that an object may be assigned a  value of a given Type.
+            </summary>
+            <param name="expected">The expected Type.</param>
+            <param name="actual">The object under examination</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsAssignableFrom(System.Type,System.Object,System.String)">
+            <summary>
+            Asserts that an object may be assigned a  value of a given Type.
+            </summary>
+            <param name="expected">The expected Type.</param>
+            <param name="actual">The object under examination</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsAssignableFrom(System.Type,System.Object)">
+            <summary>
+            Asserts that an object may be assigned a  value of a given Type.
+            </summary>
+            <param name="expected">The expected Type.</param>
+            <param name="actual">The object under examination</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsAssignableFrom``1(System.Object,System.String,System.Object[])">
+            <summary>
+            Asserts that an object may be assigned a  value of a given Type.
+            </summary>
+            <typeparam name="T">The expected Type.</typeparam>
+            <param name="actual">The object under examination</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsAssignableFrom``1(System.Object,System.String)">
+            <summary>
+            Asserts that an object may be assigned a  value of a given Type.
+            </summary>
+            <typeparam name="T">The expected Type.</typeparam>
+            <param name="actual">The object under examination</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsAssignableFrom``1(System.Object)">
+            <summary>
+            Asserts that an object may be assigned a  value of a given Type.
+            </summary>
+            <typeparam name="T">The expected Type.</typeparam>
+            <param name="actual">The object under examination</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotAssignableFrom(System.Type,System.Object,System.String,System.Object[])">
+            <summary>
+            Asserts that an object may not be assigned a  value of a given Type.
+            </summary>
+            <param name="expected">The expected Type.</param>
+            <param name="actual">The object under examination</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotAssignableFrom(System.Type,System.Object,System.String)">
+            <summary>
+            Asserts that an object may not be assigned a  value of a given Type.
+            </summary>
+            <param name="expected">The expected Type.</param>
+            <param name="actual">The object under examination</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotAssignableFrom(System.Type,System.Object)">
+            <summary>
+            Asserts that an object may not be assigned a  value of a given Type.
+            </summary>
+            <param name="expected">The expected Type.</param>
+            <param name="actual">The object under examination</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotAssignableFrom``1(System.Object,System.String,System.Object[])">
+            <summary>
+            Asserts that an object may not be assigned a  value of a given Type.
+            </summary>
+            <typeparam name="T">The expected Type.</typeparam>
+            <param name="actual">The object under examination</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotAssignableFrom``1(System.Object,System.String)">
+            <summary>
+            Asserts that an object may not be assigned a  value of a given Type.
+            </summary>
+            <typeparam name="T">The expected Type.</typeparam>
+            <param name="actual">The object under examination</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotAssignableFrom``1(System.Object)">
+            <summary>
+            Asserts that an object may not be assigned a  value of a given Type.
+            </summary>
+            <typeparam name="T">The expected Type.</typeparam>
+            <param name="actual">The object under examination</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsInstanceOf(System.Type,System.Object,System.String,System.Object[])">
+            <summary>
+            Asserts that an object is an instance of a given type.
+            </summary>
+            <param name="expected">The expected Type</param>
+            <param name="actual">The object being examined</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsInstanceOf(System.Type,System.Object,System.String)">
+            <summary>
+            Asserts that an object is an instance of a given type.
+            </summary>
+            <param name="expected">The expected Type</param>
+            <param name="actual">The object being examined</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsInstanceOf(System.Type,System.Object)">
+            <summary>
+            Asserts that an object is an instance of a given type.
+            </summary>
+            <param name="expected">The expected Type</param>
+            <param name="actual">The object being examined</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsInstanceOfType(System.Type,System.Object,System.String,System.Object[])">
+            <summary>
+            Asserts that an object is an instance of a given type.
+            </summary>
+            <param name="expected">The expected Type</param>
+            <param name="actual">The object being examined</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsInstanceOfType(System.Type,System.Object,System.String)">
+            <summary>
+            Asserts that an object is an instance of a given type.
+            </summary>
+            <param name="expected">The expected Type</param>
+            <param name="actual">The object being examined</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsInstanceOfType(System.Type,System.Object)">
+            <summary>
+            Asserts that an object is an instance of a given type.
+            </summary>
+            <param name="expected">The expected Type</param>
+            <param name="actual">The object being examined</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsInstanceOf``1(System.Object,System.String,System.Object[])">
+            <summary>
+            Asserts that an object is an instance of a given type.
+            </summary>
+            <typeparam name="T">The expected Type</typeparam>
+            <param name="actual">The object being examined</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsInstanceOf``1(System.Object,System.String)">
+            <summary>
+            Asserts that an object is an instance of a given type.
+            </summary>
+            <typeparam name="T">The expected Type</typeparam>
+            <param name="actual">The object being examined</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsInstanceOf``1(System.Object)">
+            <summary>
+            Asserts that an object is an instance of a given type.
+            </summary>
+            <typeparam name="T">The expected Type</typeparam>
+            <param name="actual">The object being examined</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotInstanceOf(System.Type,System.Object,System.String,System.Object[])">
+            <summary>
+            Asserts that an object is not an instance of a given type.
+            </summary>
+            <param name="expected">The expected Type</param>
+            <param name="actual">The object being examined</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotInstanceOf(System.Type,System.Object,System.String)">
+            <summary>
+            Asserts that an object is not an instance of a given type.
+            </summary>
+            <param name="expected">The expected Type</param>
+            <param name="actual">The object being examined</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotInstanceOf(System.Type,System.Object)">
+            <summary>
+            Asserts that an object is not an instance of a given type.
+            </summary>
+            <param name="expected">The expected Type</param>
+            <param name="actual">The object being examined</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotInstanceOfType(System.Type,System.Object,System.String,System.Object[])">
+            <summary>
+            Asserts that an object is not an instance of a given type.
+            </summary>
+            <param name="expected">The expected Type</param>
+            <param name="actual">The object being examined</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotInstanceOfType(System.Type,System.Object,System.String)">
+            <summary>
+            Asserts that an object is not an instance of a given type.
+            </summary>
+            <param name="expected">The expected Type</param>
+            <param name="actual">The object being examined</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotInstanceOfType(System.Type,System.Object)">
+            <summary>
+            Asserts that an object is not an instance of a given type.
+            </summary>
+            <param name="expected">The expected Type</param>
+            <param name="actual">The object being examined</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotInstanceOf``1(System.Object,System.String,System.Object[])">
+            <summary>
+            Asserts that an object is not an instance of a given type.
+            </summary>
+            <typeparam name="T">The expected Type</typeparam>
+            <param name="actual">The object being examined</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotInstanceOf``1(System.Object,System.String)">
+            <summary>
+            Asserts that an object is not an instance of a given type.
+            </summary>
+            <typeparam name="T">The expected Type</typeparam>
+            <param name="actual">The object being examined</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.IsNotInstanceOf``1(System.Object)">
+            <summary>
+            Asserts that an object is not an instance of a given type.
+            </summary>
+            <typeparam name="T">The expected Type</typeparam>
+            <param name="actual">The object being examined</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Int32,System.Int32,System.String,System.Object[])">
+            <summary>
+            Verifies that two values are equal. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Int32,System.Int32,System.String)">
+            <summary>
+            Verifies that two values are equal. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Int32,System.Int32)">
+            <summary>
+            Verifies that two values are equal. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Int64,System.Int64,System.String,System.Object[])">
+            <summary>
+            Verifies that two values are equal. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Int64,System.Int64,System.String)">
+            <summary>
+            Verifies that two values are equal. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Int64,System.Int64)">
+            <summary>
+            Verifies that two values are equal. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.UInt32,System.UInt32,System.String,System.Object[])">
+            <summary>
+            Verifies that two values are equal. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.UInt32,System.UInt32,System.String)">
+            <summary>
+            Verifies that two values are equal. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.UInt32,System.UInt32)">
+            <summary>
+            Verifies that two values are equal. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.UInt64,System.UInt64,System.String,System.Object[])">
+            <summary>
+            Verifies that two values are equal. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.UInt64,System.UInt64,System.String)">
+            <summary>
+            Verifies that two values are equal. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.UInt64,System.UInt64)">
+            <summary>
+            Verifies that two values are equal. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Decimal,System.Decimal,System.String,System.Object[])">
+            <summary>
+            Verifies that two values are equal. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Decimal,System.Decimal,System.String)">
+            <summary>
+            Verifies that two values are equal. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Decimal,System.Decimal)">
+            <summary>
+            Verifies that two values are equal. If they are not, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Double,System.Double,System.Double,System.String,System.Object[])">
+            <summary>
+            Verifies that two doubles are equal considering a delta. If the
+            expected value is infinity then the delta value is ignored. If 
+            they are not equal then an <see cref="T:NUnit.Framework.AssertionException"/> is
+            thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="delta">The maximum acceptable difference between the
+            the expected and the actual</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Double,System.Double,System.Double,System.String)">
+            <summary>
+            Verifies that two doubles are equal considering a delta. If the
+            expected value is infinity then the delta value is ignored. If 
+            they are not equal then an <see cref="T:NUnit.Framework.AssertionException"/> is
+            thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="delta">The maximum acceptable difference between the
+            the expected and the actual</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Double,System.Double,System.Double)">
+            <summary>
+            Verifies that two doubles are equal considering a delta. If the
+            expected value is infinity then the delta value is ignored. If 
+            they are not equal then an <see cref="T:NUnit.Framework.AssertionException"/> is
+            thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="delta">The maximum acceptable difference between the
+            the expected and the actual</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Double,System.Nullable{System.Double},System.Double,System.String,System.Object[])">
+            <summary>
+            Verifies that two doubles are equal considering a delta. If the
+            expected value is infinity then the delta value is ignored. If 
+            they are not equal then an <see cref="T:NUnit.Framework.AssertionException"/> is
+            thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="delta">The maximum acceptable difference between the
+            the expected and the actual</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Double,System.Nullable{System.Double},System.Double,System.String)">
+            <summary>
+            Verifies that two doubles are equal considering a delta. If the
+            expected value is infinity then the delta value is ignored. If 
+            they are not equal then an <see cref="T:NUnit.Framework.AssertionException"/> is
+            thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="delta">The maximum acceptable difference between the
+            the expected and the actual</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Double,System.Nullable{System.Double},System.Double)">
+            <summary>
+            Verifies that two doubles are equal considering a delta. If the
+            expected value is infinity then the delta value is ignored. If 
+            they are not equal then an <see cref="T:NUnit.Framework.AssertionException"/> is
+            thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="delta">The maximum acceptable difference between the
+            the expected and the actual</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Object,System.Object,System.String,System.Object[])">
+            <summary>
+            Verifies that two objects are equal.  Two objects are considered
+            equal if both are null, or if both have the same value. NUnit
+            has special semantics for some object types.
+            If they are not equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The value that is expected</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Object,System.Object,System.String)">
+            <summary>
+            Verifies that two objects are equal.  Two objects are considered
+            equal if both are null, or if both have the same value. NUnit
+            has special semantics for some object types.
+            If they are not equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The value that is expected</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreEqual(System.Object,System.Object)">
+            <summary>
+            Verifies that two objects are equal.  Two objects are considered
+            equal if both are null, or if both have the same value. NUnit
+            has special semantics for some object types.
+            If they are not equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The value that is expected</param>
+            <param name="actual">The actual value</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Int32,System.Int32,System.String,System.Object[])">
+            <summary>
+            Verifies that two values are not equal. If they are equal, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Int32,System.Int32,System.String)">
+            <summary>
+            Verifies that two values are not equal. If they are equal, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Int32,System.Int32)">
+            <summary>
+            Verifies that two values are not equal. If they are equal, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Int64,System.Int64,System.String,System.Object[])">
+            <summary>
+            Verifies that two values are not equal. If they are equal, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Int64,System.Int64,System.String)">
+            <summary>
+            Verifies that two values are not equal. If they are equal, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Int64,System.Int64)">
+            <summary>
+            Verifies that two values are not equal. If they are equal, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.UInt32,System.UInt32,System.String,System.Object[])">
+            <summary>
+            Verifies that two values are not equal. If they are equal, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.UInt32,System.UInt32,System.String)">
+            <summary>
+            Verifies that two values are not equal. If they are equal, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.UInt32,System.UInt32)">
+            <summary>
+            Verifies that two values are not equal. If they are equal, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.UInt64,System.UInt64,System.String,System.Object[])">
+            <summary>
+            Verifies that two values are not equal. If they are equal, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.UInt64,System.UInt64,System.String)">
+            <summary>
+            Verifies that two values are not equal. If they are equal, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.UInt64,System.UInt64)">
+            <summary>
+            Verifies that two values are not equal. If they are equal, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Decimal,System.Decimal,System.String,System.Object[])">
+            <summary>
+            Verifies that two values are not equal. If they are equal, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Decimal,System.Decimal,System.String)">
+            <summary>
+            Verifies that two values are not equal. If they are equal, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Decimal,System.Decimal)">
+            <summary>
+            Verifies that two values are not equal. If they are equal, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Single,System.Single,System.String,System.Object[])">
+            <summary>
+            Verifies that two values are not equal. If they are equal, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Single,System.Single,System.String)">
+            <summary>
+            Verifies that two values are not equal. If they are equal, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Single,System.Single)">
+            <summary>
+            Verifies that two values are not equal. If they are equal, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Double,System.Double,System.String,System.Object[])">
+            <summary>
+            Verifies that two values are not equal. If they are equal, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Double,System.Double,System.String)">
+            <summary>
+            Verifies that two values are not equal. If they are equal, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Double,System.Double)">
+            <summary>
+            Verifies that two values are not equal. If they are equal, then an 
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected value</param>
+            <param name="actual">The actual value</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Object,System.Object,System.String,System.Object[])">
+            <summary>
+            Verifies that two objects are not equal.  Two objects are considered
+            equal if both are null, or if both have the same value. NUnit
+            has special semantics for some object types.
+            If they are equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The value that is expected</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Object,System.Object,System.String)">
+            <summary>
+            Verifies that two objects are not equal.  Two objects are considered
+            equal if both are null, or if both have the same value. NUnit
+            has special semantics for some object types.
+            If they are equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The value that is expected</param>
+            <param name="actual">The actual value</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotEqual(System.Object,System.Object)">
+            <summary>
+            Verifies that two objects are not equal.  Two objects are considered
+            equal if both are null, or if both have the same value. NUnit
+            has special semantics for some object types.
+            If they are equal an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The value that is expected</param>
+            <param name="actual">The actual value</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreSame(System.Object,System.Object,System.String,System.Object[])">
+            <summary>
+            Asserts that two objects refer to the same object. If they
+            are not the same an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreSame(System.Object,System.Object,System.String)">
+            <summary>
+            Asserts that two objects refer to the same object. If they
+            are not the same an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreSame(System.Object,System.Object)">
+            <summary>
+            Asserts that two objects refer to the same object. If they
+            are not the same an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotSame(System.Object,System.Object,System.String,System.Object[])">
+            <summary>
+            Asserts that two objects do not refer to the same object. If they
+            are the same an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotSame(System.Object,System.Object,System.String)">
+            <summary>
+            Asserts that two objects do not refer to the same object. If they
+            are the same an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.AreNotSame(System.Object,System.Object)">
+            <summary>
+            Asserts that two objects do not refer to the same object. If they
+            are the same an <see cref="T:NUnit.Framework.AssertionException"/> is thrown.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The actual object</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.Int32,System.Int32,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.Int32,System.Int32,System.String)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.Int32,System.Int32)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.UInt32,System.UInt32,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.UInt32,System.UInt32,System.String)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.UInt32,System.UInt32)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.Int64,System.Int64,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.Int64,System.Int64,System.String)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.Int64,System.Int64)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.UInt64,System.UInt64,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.UInt64,System.UInt64,System.String)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.UInt64,System.UInt64)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.Decimal,System.Decimal,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.Decimal,System.Decimal,System.String)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.Decimal,System.Decimal)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.Double,System.Double,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.Double,System.Double,System.String)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.Double,System.Double)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.Single,System.Single,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.Single,System.Single,System.String)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.Single,System.Single)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.IComparable,System.IComparable,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.IComparable,System.IComparable,System.String)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Greater(System.IComparable,System.IComparable)">
+            <summary>
+            Verifies that the first value is greater than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.Int32,System.Int32,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.Int32,System.Int32,System.String)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.Int32,System.Int32)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.UInt32,System.UInt32,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.UInt32,System.UInt32,System.String)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.UInt32,System.UInt32)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.Int64,System.Int64,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.Int64,System.Int64,System.String)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.Int64,System.Int64)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.UInt64,System.UInt64,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.UInt64,System.UInt64,System.String)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.UInt64,System.UInt64)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.Decimal,System.Decimal,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.Decimal,System.Decimal,System.String)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.Decimal,System.Decimal)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.Double,System.Double,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.Double,System.Double,System.String)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.Double,System.Double)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.Single,System.Single,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.Single,System.Single,System.String)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.Single,System.Single)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.IComparable,System.IComparable,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.IComparable,System.IComparable,System.String)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Less(System.IComparable,System.IComparable)">
+            <summary>
+            Verifies that the first value is less than the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.Int32,System.Int32,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than or equal tothe second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.Int32,System.Int32,System.String)">
+            <summary>
+            Verifies that the first value is greater than or equal tothe second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.Int32,System.Int32)">
+            <summary>
+            Verifies that the first value is greater than or equal tothe second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.UInt32,System.UInt32,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than or equal tothe second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.UInt32,System.UInt32,System.String)">
+            <summary>
+            Verifies that the first value is greater than or equal tothe second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.UInt32,System.UInt32)">
+            <summary>
+            Verifies that the first value is greater than or equal tothe second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.Int64,System.Int64,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than or equal tothe second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.Int64,System.Int64,System.String)">
+            <summary>
+            Verifies that the first value is greater than or equal tothe second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.Int64,System.Int64)">
+            <summary>
+            Verifies that the first value is greater than or equal tothe second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.UInt64,System.UInt64,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than or equal tothe second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.UInt64,System.UInt64,System.String)">
+            <summary>
+            Verifies that the first value is greater than or equal tothe second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.UInt64,System.UInt64)">
+            <summary>
+            Verifies that the first value is greater than or equal tothe second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.Decimal,System.Decimal,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than or equal tothe second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.Decimal,System.Decimal,System.String)">
+            <summary>
+            Verifies that the first value is greater than or equal tothe second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.Decimal,System.Decimal)">
+            <summary>
+            Verifies that the first value is greater than or equal tothe second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.Double,System.Double,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than or equal tothe second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.Double,System.Double,System.String)">
+            <summary>
+            Verifies that the first value is greater than or equal tothe second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.Double,System.Double)">
+            <summary>
+            Verifies that the first value is greater than or equal tothe second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.Single,System.Single,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than or equal tothe second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.Single,System.Single,System.String)">
+            <summary>
+            Verifies that the first value is greater than or equal tothe second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.Single,System.Single)">
+            <summary>
+            Verifies that the first value is greater than or equal tothe second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.IComparable,System.IComparable,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is greater than or equal tothe second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.IComparable,System.IComparable,System.String)">
+            <summary>
+            Verifies that the first value is greater than or equal tothe second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.GreaterOrEqual(System.IComparable,System.IComparable)">
+            <summary>
+            Verifies that the first value is greater than or equal tothe second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be greater</param>
+            <param name="arg2">The second value, expected to be less</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.Int32,System.Int32,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.Int32,System.Int32,System.String)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.Int32,System.Int32)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.UInt32,System.UInt32,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.UInt32,System.UInt32,System.String)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.UInt32,System.UInt32)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.Int64,System.Int64,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.Int64,System.Int64,System.String)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.Int64,System.Int64)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.UInt64,System.UInt64,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.UInt64,System.UInt64,System.String)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.UInt64,System.UInt64)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.Decimal,System.Decimal,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.Decimal,System.Decimal,System.String)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.Decimal,System.Decimal)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.Double,System.Double,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.Double,System.Double,System.String)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.Double,System.Double)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.Single,System.Single,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.Single,System.Single,System.String)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.Single,System.Single)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.IComparable,System.IComparable,System.String,System.Object[])">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.IComparable,System.IComparable,System.String)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.LessOrEqual(System.IComparable,System.IComparable)">
+            <summary>
+            Verifies that the first value is less than or equal to the second
+            value. If it is not, then an
+            <see cref="T:NUnit.Framework.AssertionException"/> is thrown. 
+            </summary>
+            <param name="arg1">The first value, expected to be less</param>
+            <param name="arg2">The second value, expected to be greater</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Contains(System.Object,System.Collections.ICollection,System.String,System.Object[])">
+            <summary>
+            Asserts that an object is contained in a list.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The list to be examined</param>
+            <param name="message">The message to display in case of failure</param>
+            <param name="args">Array of objects to be used in formatting the message</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Contains(System.Object,System.Collections.ICollection,System.String)">
+            <summary>
+            Asserts that an object is contained in a list.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The list to be examined</param>
+            <param name="message">The message to display in case of failure</param>
+        </member>
+        <member name="M:NUnit.Framework.Assert.Contains(System.Object,System.Collections.ICollection)">
+            <summary>
+            Asserts that an object is contained in a list.
+            </summary>
+            <param name="expected">The expected object</param>
+            <param name="actual">The list to be examined</param>
+        </member>
+        <member name="P:NUnit.Framework.Assert.Counter">
+            <summary>
+            Gets the number of assertions executed so far and 
+            resets the counter to zero.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.Contains">
+            <summary>
+            Static helper class used in the constraint-based syntax
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.Contains.Substring(System.String)">
+            <summary>
+            Creates a new SubstringConstraint
+            </summary>
+            <param name="substring">The value of the substring</param>
+            <returns>A SubstringConstraint</returns>
+        </member>
+        <member name="M:NUnit.Framework.Contains.Item(System.Object)">
+            <summary>
+            Creates a new CollectionContainsConstraint.
+            </summary>
+            <param name="item">The item that should be found.</param>
+            <returns>A new CollectionContainsConstraint</returns>
+        </member>
+        <member name="T:NUnit.Framework.CategoryAttribute">
+            <summary>
+            Attribute used to apply a category to a test
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.CategoryAttribute.categoryName">
+            <summary>
+            The name of the category
+            </summary>
+        </member>
+        <member name="M:NUnit.Framework.CategoryAttribute.#ctor(System.String)">
+            <summary>
+            Construct attribute for a given category based on
+            a name. The name may not contain the characters ',',
+            '+', '-' or '!'. However, this is not checked in the
+            constructor since it would cause an error to arise at
+            as the test was loaded without giving a clear indication
+            of where the problem is located. The error is handled
+            in NUnitFramework.cs by marking the test as not
+            runnable.
+            </summary>
+            <param name="name">The name of the category</param>
+        </member>
+        <member name="M:NUnit.Framework.CategoryAttribute.#ctor">
+            <summary>
+            Protected constructor uses the Type name as the name
+            of the category.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.CategoryAttribute.Name">
+            <summary>
+            The name of the category
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.TestStatus">
+            <summary>
+            The TestStatus enum indicates the result of running a test
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.TestStatus.Inconclusive">
+            <summary>
+            The test was inconclusive
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.TestStatus.Skipped">
+            <summary>
+            The test has skipped 
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.TestStatus.Passed">
+            <summary>
+            The test succeeded
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.TestStatus.Failed">
+            <summary>
+            The test failed
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.TestContext">
+            <summary>
+            Provide the context information of the current test
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.TestContext.State">
+            <summary>
+            The TestState of current test. This maps to the ResultState
+            used in nunit.core and is subject to change in the future.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.TestContext.Status">
+            <summary>
+            The TestStatus of current test. This enum will be used
+            in future versions of NUnit and so is to be preferred
+            to the TestState value.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.TestContext.TestName">
+            <summary>
+            The name of the currently executing test. If no
+            test is running, the name of the last test run.
+            </summary>
+        </member>
+        <member name="P:NUnit.Framework.TestContext.Properties">
+            <summary>
+            The properties of the currently executing test
+            or, if no test is running, of the last test run.
+            </summary>
+        </member>
+        <member name="T:NUnit.Framework.TestState">
+            <summary>
+            The ResultState enum indicates the result of running a test
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.TestState.Inconclusive">
+            <summary>
+            The result is inconclusive
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.TestState.NotRunnable">
+            <summary>
+            The test was not runnable.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.TestState.Skipped">
+            <summary>
+            The test has been skipped. 
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.TestState.Ignored">
+            <summary>
+            The test has been ignored.
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.TestState.Success">
+            <summary>
+            The test succeeded
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.TestState.Failure">
+            <summary>
+            The test failed
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.TestState.Error">
+            <summary>
+            The test encountered an unexpected exception
+            </summary>
+        </member>
+        <member name="F:NUnit.Framework.TestState.Cancelled">
+            <summary>
+            The test was cancelled by the user
+            </summary>
+        </member>
+    </members>
+</doc>
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/framework/nunit.mocks.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/framework/nunit.mocks.dll
new file mode 100644 (file)
index 0000000..43aafff
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/framework/nunit.mocks.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/framework/pnunit.framework.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/framework/pnunit.framework.dll
new file mode 100644 (file)
index 0000000..3783a4a
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/framework/pnunit.framework.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/launcher.log.conf b/trunk/Libraries/Json40r2/Source/Tools/NUnit/launcher.log.conf
new file mode 100644 (file)
index 0000000..4bd90ca
--- /dev/null
@@ -0,0 +1,18 @@
+<log4net>
+       <!-- A1 is set to be a ConsoleAppender -->
+       <appender name="A1" type="log4net.Appender.ConsoleAppender">
+
+               <!-- A1 uses PatternLayout -->
+               <layout type="log4net.Layout.PatternLayout">
+                       <!-- Print the date in ISO 8601 format -->
+                       <conversionPattern value="%-5level %logger - %message%newline" />
+               </layout>
+       </appender>
+       
+       <!-- Set root logger level to DEBUG and its only appender to A1 -->
+       <root>
+               <level value="DEBUG" />
+               <appender-ref ref="A1" />
+       </root>
+
+</log4net>
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/Failure.png b/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/Failure.png
new file mode 100644 (file)
index 0000000..2e400b2
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/Failure.png differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/Ignored.png b/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/Ignored.png
new file mode 100644 (file)
index 0000000..478efbf
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/Ignored.png differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/Inconclusive.png b/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/Inconclusive.png
new file mode 100644 (file)
index 0000000..4807b7c
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/Inconclusive.png differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/Skipped.png b/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/Skipped.png
new file mode 100644 (file)
index 0000000..7c9fc64
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/Skipped.png differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/Success.png b/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/Success.png
new file mode 100644 (file)
index 0000000..2a30150
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/Success.png differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/fit.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/fit.dll
new file mode 100644 (file)
index 0000000..40bbef0
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/fit.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/log4net.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/log4net.dll
new file mode 100644 (file)
index 0000000..20a2e1c
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/log4net.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit-console-runner.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit-console-runner.dll
new file mode 100644 (file)
index 0000000..3d1152c
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit-console-runner.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit-gui-runner.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit-gui-runner.dll
new file mode 100644 (file)
index 0000000..4398f8f
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit-gui-runner.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit.core.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit.core.dll
new file mode 100644 (file)
index 0000000..dd3b2e0
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit.core.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit.core.interfaces.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit.core.interfaces.dll
new file mode 100644 (file)
index 0000000..39a1127
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit.core.interfaces.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit.fixtures.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit.fixtures.dll
new file mode 100644 (file)
index 0000000..b48a1d4
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit.fixtures.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit.uiexception.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit.uiexception.dll
new file mode 100644 (file)
index 0000000..9e970f5
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit.uiexception.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit.uikit.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit.uikit.dll
new file mode 100644 (file)
index 0000000..bd0ff5b
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit.uikit.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit.util.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit.util.dll
new file mode 100644 (file)
index 0000000..2d002a8
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/lib/nunit.util.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/nunit-agent-x86.exe.config b/trunk/Libraries/Json40r2/Source/Tools/NUnit/nunit-agent-x86.exe.config
new file mode 100644 (file)
index 0000000..e2d3b78
--- /dev/null
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+  <!-- Set the level for tracing NUnit itself -->
+  <!-- 0=Off 1=Error 2=Warning 3=Info 4=Debug -->
+  <system.diagnostics>
+         <switches>
+      <add name="NTrace" value="0" />
+         </switches>
+  </system.diagnostics>
+  
+  <runtime>
+    <!-- We need this so test exceptions don't crash NUnit -->
+    <legacyUnhandledExceptionPolicy enabled="1" />
+
+    <!-- Look for addins in the addins directory for now -->
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+      <probing privatePath="lib;addins"/>
+   </assemblyBinding>
+
+    <!--
+    The following <assemblyBinding> section allows running nunit under 
+    .NET 1.0 by redirecting assemblies. The appliesTo attribute
+    causes the section to be ignored except under .NET 1.0
+    on a machine with only the .NET version 1.0 runtime installed.
+    If application and its tests were built for .NET 1.1 you will
+    also need to redirect system assemblies in the test config file,
+    which controls loading of the tests.
+   -->
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"
+                       appliesTo="v1.0.3705">
+
+      <dependentAssembly> 
+        <assemblyIdentity name="System" 
+                          publicKeyToken="b77a5c561934e089" 
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0" 
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly> 
+        <assemblyIdentity name="System.Data" 
+                          publicKeyToken="b77a5c561934e089" 
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0" 
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly> 
+        <assemblyIdentity name="System.Drawing" 
+                          publicKeyToken="b03f5f7f11d50a3a" 
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0" 
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly> 
+        <assemblyIdentity name="System.Windows.Forms" 
+                          publicKeyToken="b77a5c561934e089" 
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0" 
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly> 
+        <assemblyIdentity name="System.Xml" 
+                          publicKeyToken="b77a5c561934e089" 
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0" 
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+    </assemblyBinding>
+  
+  </runtime>
+  
+</configuration>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/nunit-agent.exe.config b/trunk/Libraries/Json40r2/Source/Tools/NUnit/nunit-agent.exe.config
new file mode 100644 (file)
index 0000000..e2d3b78
--- /dev/null
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+  <!-- Set the level for tracing NUnit itself -->
+  <!-- 0=Off 1=Error 2=Warning 3=Info 4=Debug -->
+  <system.diagnostics>
+         <switches>
+      <add name="NTrace" value="0" />
+         </switches>
+  </system.diagnostics>
+  
+  <runtime>
+    <!-- We need this so test exceptions don't crash NUnit -->
+    <legacyUnhandledExceptionPolicy enabled="1" />
+
+    <!-- Look for addins in the addins directory for now -->
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+      <probing privatePath="lib;addins"/>
+   </assemblyBinding>
+
+    <!--
+    The following <assemblyBinding> section allows running nunit under 
+    .NET 1.0 by redirecting assemblies. The appliesTo attribute
+    causes the section to be ignored except under .NET 1.0
+    on a machine with only the .NET version 1.0 runtime installed.
+    If application and its tests were built for .NET 1.1 you will
+    also need to redirect system assemblies in the test config file,
+    which controls loading of the tests.
+   -->
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"
+                       appliesTo="v1.0.3705">
+
+      <dependentAssembly> 
+        <assemblyIdentity name="System" 
+                          publicKeyToken="b77a5c561934e089" 
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0" 
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly> 
+        <assemblyIdentity name="System.Data" 
+                          publicKeyToken="b77a5c561934e089" 
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0" 
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly> 
+        <assemblyIdentity name="System.Drawing" 
+                          publicKeyToken="b03f5f7f11d50a3a" 
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0" 
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly> 
+        <assemblyIdentity name="System.Windows.Forms" 
+                          publicKeyToken="b77a5c561934e089" 
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0" 
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly> 
+        <assemblyIdentity name="System.Xml" 
+                          publicKeyToken="b77a5c561934e089" 
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0" 
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+    </assemblyBinding>
+  
+  </runtime>
+  
+</configuration>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/nunit-console-x86.exe.config b/trunk/Libraries/Json40r2/Source/Tools/NUnit/nunit-console-x86.exe.config
new file mode 100644 (file)
index 0000000..f32f92b
--- /dev/null
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+  <!-- Set the level for tracing NUnit itself -->
+  <!-- 0=Off 1=Error 2=Warning 3=Info 4=Debug -->
+  <system.diagnostics>
+         <switches>
+      <add name="NTrace" value="0" />
+         </switches>
+       </system.diagnostics>
+
+  <runtime>
+    <!-- We need this so test exceptions don't crash NUnit -->
+    <legacyUnhandledExceptionPolicy enabled="1" />
+
+    <!-- Look for addins in the addins directory for now -->
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+      <probing privatePath="lib;addins"/>
+   </assemblyBinding>
+
+   <!--
+    The following <assemblyBinding> section allows running nunit under 
+    .NET 1.0 by redirecting assemblies. The appliesTo attribute
+    causes the section to be ignored except under .NET 1.0
+    on a machine with only the .NET version 1.0 runtime installed.
+    If application and its tests were built for .NET 1.1 you will
+    also need to redirect system assemblies in the test config file,
+    which controls loading of the tests.
+   -->
+   <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"
+                       appliesTo="v1.0.3705">
+
+      <dependentAssembly> 
+        <assemblyIdentity name="System" 
+                          publicKeyToken="b77a5c561934e089" 
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0" 
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly> 
+        <assemblyIdentity name="System.Data" 
+                          publicKeyToken="b77a5c561934e089" 
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0" 
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly> 
+        <assemblyIdentity name="System.Drawing" 
+                          publicKeyToken="b03f5f7f11d50a3a" 
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0" 
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly> 
+        <assemblyIdentity name="System.Windows.Forms" 
+                          publicKeyToken="b77a5c561934e089" 
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0" 
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly> 
+        <assemblyIdentity name="System.Xml" 
+                          publicKeyToken="b77a5c561934e089" 
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0" 
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+    </assemblyBinding>
+
+  </runtime>
+  
+</configuration>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/nunit-console.exe.config b/trunk/Libraries/Json40r2/Source/Tools/NUnit/nunit-console.exe.config
new file mode 100644 (file)
index 0000000..f32f92b
--- /dev/null
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+  <!-- Set the level for tracing NUnit itself -->
+  <!-- 0=Off 1=Error 2=Warning 3=Info 4=Debug -->
+  <system.diagnostics>
+         <switches>
+      <add name="NTrace" value="0" />
+         </switches>
+       </system.diagnostics>
+
+  <runtime>
+    <!-- We need this so test exceptions don't crash NUnit -->
+    <legacyUnhandledExceptionPolicy enabled="1" />
+
+    <!-- Look for addins in the addins directory for now -->
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+      <probing privatePath="lib;addins"/>
+   </assemblyBinding>
+
+   <!--
+    The following <assemblyBinding> section allows running nunit under 
+    .NET 1.0 by redirecting assemblies. The appliesTo attribute
+    causes the section to be ignored except under .NET 1.0
+    on a machine with only the .NET version 1.0 runtime installed.
+    If application and its tests were built for .NET 1.1 you will
+    also need to redirect system assemblies in the test config file,
+    which controls loading of the tests.
+   -->
+   <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"
+                       appliesTo="v1.0.3705">
+
+      <dependentAssembly> 
+        <assemblyIdentity name="System" 
+                          publicKeyToken="b77a5c561934e089" 
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0" 
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly> 
+        <assemblyIdentity name="System.Data" 
+                          publicKeyToken="b77a5c561934e089" 
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0" 
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly> 
+        <assemblyIdentity name="System.Drawing" 
+                          publicKeyToken="b03f5f7f11d50a3a" 
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0" 
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly> 
+        <assemblyIdentity name="System.Windows.Forms" 
+                          publicKeyToken="b77a5c561934e089" 
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0" 
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly> 
+        <assemblyIdentity name="System.Xml" 
+                          publicKeyToken="b77a5c561934e089" 
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0" 
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+    </assemblyBinding>
+
+  </runtime>
+  
+</configuration>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/nunit-x86.exe.config b/trunk/Libraries/Json40r2/Source/Tools/NUnit/nunit-x86.exe.config
new file mode 100644 (file)
index 0000000..878d91b
--- /dev/null
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+  <!--
+     Application settings for NUnit-gui.exe. Do NOT put settings
+        for use by your tests here.
+       -->
+  <appSettings>
+    <!--
+     Uncomment to specify the url to be used for help. If not used, the
+     default value is something like
+               file://localhost/C:/Program Files/NUnit 2.2/doc/index.html
+        This setting is provided in case your default browser doesn't
+        support this format.
+       -->
+    <!-- <add key="helpUrl" value="http://www.nunit.org" /> -->
+  </appSettings>
+
+  <!-- Set the level for tracing NUnit itself -->
+  <!-- 0=Off 1=Error 2=Warning 3=Info 4=Debug -->
+  <system.diagnostics>
+         <switches>
+      <add name="NTrace" value="0" />
+         </switches>
+       </system.diagnostics>
+
+  <runtime>
+    <!-- We need this so test exceptions don't crash NUnit -->
+    <legacyUnhandledExceptionPolicy enabled="1" />
+
+    <!-- Look for addins in the addins directory for now -->
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+      <probing privatePath="lib;addins" />
+    </assemblyBinding>
+
+    <!--
+    The following <assemblyBinding> section allows running nunit under 
+    .NET 1.0 by redirecting assemblies. The appliesTo attribute
+    causes the section to be ignored except under .NET 1.0
+    on a machine with only the .NET version 1.0 runtime installed.
+    If application and its tests were built for .NET 1.1 you will
+    also need to redirect system assemblies in the test config file,
+    which controls loading of the tests.
+   -->
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"
+       appliesTo="v1.0.3705">
+
+      <dependentAssembly>
+        <assemblyIdentity name="System"
+                          publicKeyToken="b77a5c561934e089"
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0"
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly>
+        <assemblyIdentity name="System.Data"
+                          publicKeyToken="b77a5c561934e089"
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0"
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly>
+        <assemblyIdentity name="System.Drawing"
+                          publicKeyToken="b03f5f7f11d50a3a"
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0"
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly>
+        <assemblyIdentity name="System.Windows.Forms"
+                          publicKeyToken="b77a5c561934e089"
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0"
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly>
+        <assemblyIdentity name="System.Xml"
+                          publicKeyToken="b77a5c561934e089"
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0"
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+    </assemblyBinding>
+
+  </runtime>
+
+</configuration>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/nunit.exe.config b/trunk/Libraries/Json40r2/Source/Tools/NUnit/nunit.exe.config
new file mode 100644 (file)
index 0000000..878d91b
--- /dev/null
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+  <!--
+     Application settings for NUnit-gui.exe. Do NOT put settings
+        for use by your tests here.
+       -->
+  <appSettings>
+    <!--
+     Uncomment to specify the url to be used for help. If not used, the
+     default value is something like
+               file://localhost/C:/Program Files/NUnit 2.2/doc/index.html
+        This setting is provided in case your default browser doesn't
+        support this format.
+       -->
+    <!-- <add key="helpUrl" value="http://www.nunit.org" /> -->
+  </appSettings>
+
+  <!-- Set the level for tracing NUnit itself -->
+  <!-- 0=Off 1=Error 2=Warning 3=Info 4=Debug -->
+  <system.diagnostics>
+         <switches>
+      <add name="NTrace" value="0" />
+         </switches>
+       </system.diagnostics>
+
+  <runtime>
+    <!-- We need this so test exceptions don't crash NUnit -->
+    <legacyUnhandledExceptionPolicy enabled="1" />
+
+    <!-- Look for addins in the addins directory for now -->
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+      <probing privatePath="lib;addins" />
+    </assemblyBinding>
+
+    <!--
+    The following <assemblyBinding> section allows running nunit under 
+    .NET 1.0 by redirecting assemblies. The appliesTo attribute
+    causes the section to be ignored except under .NET 1.0
+    on a machine with only the .NET version 1.0 runtime installed.
+    If application and its tests were built for .NET 1.1 you will
+    also need to redirect system assemblies in the test config file,
+    which controls loading of the tests.
+   -->
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"
+       appliesTo="v1.0.3705">
+
+      <dependentAssembly>
+        <assemblyIdentity name="System"
+                          publicKeyToken="b77a5c561934e089"
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0"
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly>
+        <assemblyIdentity name="System.Data"
+                          publicKeyToken="b77a5c561934e089"
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0"
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly>
+        <assemblyIdentity name="System.Drawing"
+                          publicKeyToken="b03f5f7f11d50a3a"
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0"
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly>
+        <assemblyIdentity name="System.Windows.Forms"
+                          publicKeyToken="b77a5c561934e089"
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0"
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly>
+        <assemblyIdentity name="System.Xml"
+                          publicKeyToken="b77a5c561934e089"
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0"
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+    </assemblyBinding>
+
+  </runtime>
+
+</configuration>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/nunit.framework.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/nunit.framework.dll
new file mode 100644 (file)
index 0000000..639dbb0
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/nunit.framework.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/pnunit-agent.exe.config b/trunk/Libraries/Json40r2/Source/Tools/NUnit/pnunit-agent.exe.config
new file mode 100644 (file)
index 0000000..0bf29b3
--- /dev/null
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<configuration>
+
+  <!-- Set the level for tracing NUnit itself -->
+  <!-- 0=Off 1=Error 2=Warning 3=Info 4=Debug -->
+  <system.diagnostics>
+         <switches>
+      <add name="NTrace" value="0" />
+         </switches>
+  </system.diagnostics>
+  
+  <runtime>
+    <!-- We need this so test exceptions don't crash NUnit -->
+    <legacyUnhandledExceptionPolicy enabled="1" />
+
+    <!-- Look for addins in the addins directory for now -->
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+      <probing privatePath="framework;lib;addins"/>
+   </assemblyBinding>
+
+    <!--
+    The following <assemblyBinding> section allows running nunit under 
+    .NET 1.0 by redirecting assemblies. The appliesTo attribute
+    causes the section to be ignored except under .NET 1.0
+    on a machine with only the .NET version 1.0 runtime installed.
+    If application and its tests were built for .NET 1.1 you will
+    also need to redirect system assemblies in the test config file,
+    which controls loading of the tests.
+   -->
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"
+                       appliesTo="v1.0.3705">
+
+      <dependentAssembly> 
+        <assemblyIdentity name="System" 
+                          publicKeyToken="b77a5c561934e089" 
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0" 
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly> 
+        <assemblyIdentity name="System.Data" 
+                          publicKeyToken="b77a5c561934e089" 
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0" 
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly> 
+        <assemblyIdentity name="System.Drawing" 
+                          publicKeyToken="b03f5f7f11d50a3a" 
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0" 
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly> 
+        <assemblyIdentity name="System.Windows.Forms" 
+                          publicKeyToken="b77a5c561934e089" 
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0" 
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly> 
+        <assemblyIdentity name="System.Xml" 
+                          publicKeyToken="b77a5c561934e089" 
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0" 
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+    </assemblyBinding>
+  
+  </runtime>
+  
+</configuration>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/pnunit-launcher.exe.config b/trunk/Libraries/Json40r2/Source/Tools/NUnit/pnunit-launcher.exe.config
new file mode 100644 (file)
index 0000000..0bf29b3
--- /dev/null
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<configuration>
+
+  <!-- Set the level for tracing NUnit itself -->
+  <!-- 0=Off 1=Error 2=Warning 3=Info 4=Debug -->
+  <system.diagnostics>
+         <switches>
+      <add name="NTrace" value="0" />
+         </switches>
+  </system.diagnostics>
+  
+  <runtime>
+    <!-- We need this so test exceptions don't crash NUnit -->
+    <legacyUnhandledExceptionPolicy enabled="1" />
+
+    <!-- Look for addins in the addins directory for now -->
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+      <probing privatePath="framework;lib;addins"/>
+   </assemblyBinding>
+
+    <!--
+    The following <assemblyBinding> section allows running nunit under 
+    .NET 1.0 by redirecting assemblies. The appliesTo attribute
+    causes the section to be ignored except under .NET 1.0
+    on a machine with only the .NET version 1.0 runtime installed.
+    If application and its tests were built for .NET 1.1 you will
+    also need to redirect system assemblies in the test config file,
+    which controls loading of the tests.
+   -->
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"
+                       appliesTo="v1.0.3705">
+
+      <dependentAssembly> 
+        <assemblyIdentity name="System" 
+                          publicKeyToken="b77a5c561934e089" 
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0" 
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly> 
+        <assemblyIdentity name="System.Data" 
+                          publicKeyToken="b77a5c561934e089" 
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0" 
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly> 
+        <assemblyIdentity name="System.Drawing" 
+                          publicKeyToken="b03f5f7f11d50a3a" 
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0" 
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly> 
+        <assemblyIdentity name="System.Windows.Forms" 
+                          publicKeyToken="b77a5c561934e089" 
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0" 
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+      <dependentAssembly> 
+        <assemblyIdentity name="System.Xml" 
+                          publicKeyToken="b77a5c561934e089" 
+                          culture="neutral"/>
+        <bindingRedirect  oldVersion="1.0.5000.0" 
+                          newVersion="1.0.3300.0"/>
+      </dependentAssembly>
+
+    </assemblyBinding>
+  
+  </runtime>
+  
+</configuration>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/pnunit.framework.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/pnunit.framework.dll
new file mode 100644 (file)
index 0000000..3783a4a
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/pnunit.framework.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/pnunit.tests.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/pnunit.tests.dll
new file mode 100644 (file)
index 0000000..77c4a22
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/pnunit.tests.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/runFile.exe.config b/trunk/Libraries/Json40r2/Source/Tools/NUnit/runFile.exe.config
new file mode 100644 (file)
index 0000000..f58f099
--- /dev/null
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+  <startup>
+         <supportedRuntime version="v2.0.50727" />
+         <supportedRuntime version="v2.0.50215" />
+         <supportedRuntime version="v2.0.40607" />
+         <supportedRuntime version="v1.1.4322" />
+         <supportedRuntime version="v1.0.3705" />
+       
+         <requiredRuntime version="v1.0.3705" />
+  </startup>
+
+<!--
+     The following <runtime> section allows running nunit tests under 
+     .NET 1.0 by redirecting assemblies. The appliesTo attribute
+     causes the section to be ignored except under .NET 1.0.
+       -->
+       <runtime>
+               <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"
+                               appliesTo="v1.0.3705">
+                       <dependentAssembly>
+                               <assemblyIdentity name="System" publicKeyToken="b77a5c561934e089" culture="" />
+                               <bindingRedirect oldVersion="1.0.5000.0" newVersion="1.0.3300.0" />
+                       </dependentAssembly>
+                       <dependentAssembly>
+                               <assemblyIdentity name="System.Data" publicKeyToken="b77a5c561934e089" culture="" />
+                               <bindingRedirect oldVersion="1.0.5000.0" newVersion="1.0.3300.0" />
+                       </dependentAssembly>
+                       <dependentAssembly>
+                               <assemblyIdentity name="System.Drawing" publicKeyToken="b03f5f7f11d50a3a" culture="" />
+                               <bindingRedirect oldVersion="1.0.5000.0" newVersion="1.0.3300.0" />
+                       </dependentAssembly>
+                       <dependentAssembly>
+                               <assemblyIdentity name="System.Windows.Forms" publicKeyToken="b77a5c561934e089" culture="" />
+                               <bindingRedirect oldVersion="1.0.5000.0" newVersion="1.0.3300.0" />
+                       </dependentAssembly>
+                       <dependentAssembly>
+                               <assemblyIdentity name="System.Xml" publicKeyToken="b77a5c561934e089" culture="" />
+                               <bindingRedirect oldVersion="1.0.5000.0" newVersion="1.0.3300.0" />
+                       </dependentAssembly>
+               </assemblyBinding>
+       </runtime>
+</configuration>
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/runpnunit.bat b/trunk/Libraries/Json40r2/Source/Tools/NUnit/runpnunit.bat
new file mode 100644 (file)
index 0000000..a05cbb7
--- /dev/null
@@ -0,0 +1,2 @@
+start pnunit-agent agent.conf
+pnunit-launcher test.conf
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/test.conf b/trunk/Libraries/Json40r2/Source/Tools/NUnit/test.conf
new file mode 100644 (file)
index 0000000..14cd113
--- /dev/null
@@ -0,0 +1,24 @@
+<TestGroup>
+    <ParallelTests>
+
+        <ParallelTest>
+            <Name>Testing</Name>
+            <Tests>
+                <TestConf>
+                    <Name>Testing</Name>
+                    <Assembly>pnunit.tests.dll</Assembly>
+                    <TestToRun>TestLibraries.Testing.EqualTo19</TestToRun>
+                    <Machine>localhost:8080</Machine>
+                    <TestParams>
+                        <string>..\server</string> <!-- server dir -->
+                       <string></string> <!-- database server -->
+                       <string></string><!-- conn string -->
+                    </TestParams>                                                                                
+                </TestConf>
+
+            </Tests>
+        </ParallelTest>
+
+
+    </ParallelTests>
+</TestGroup>
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/loadtest-assembly.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/loadtest-assembly.dll
new file mode 100644 (file)
index 0000000..ffcb0e6
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/loadtest-assembly.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/mock-assembly.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/mock-assembly.dll
new file mode 100644 (file)
index 0000000..1083ced
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/mock-assembly.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nonamespace-assembly.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nonamespace-assembly.dll
new file mode 100644 (file)
index 0000000..22506fb
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nonamespace-assembly.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit-console.tests.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit-console.tests.dll
new file mode 100644 (file)
index 0000000..b626c19
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit-console.tests.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit-gui.tests.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit-gui.tests.dll
new file mode 100644 (file)
index 0000000..0845863
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit-gui.tests.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.core.tests.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.core.tests.dll
new file mode 100644 (file)
index 0000000..ee09df9
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.core.tests.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.fixtures.tests.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.fixtures.tests.dll
new file mode 100644 (file)
index 0000000..9ab1d96
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.fixtures.tests.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.framework.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.framework.dll
new file mode 100644 (file)
index 0000000..639dbb0
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.framework.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.framework.tests.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.framework.tests.dll
new file mode 100644 (file)
index 0000000..2da0676
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.framework.tests.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.mocks.tests.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.mocks.tests.dll
new file mode 100644 (file)
index 0000000..289ac49
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.mocks.tests.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.uiexception.tests.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.uiexception.tests.dll
new file mode 100644 (file)
index 0000000..8c47743
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.uiexception.tests.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.uikit.tests.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.uikit.tests.dll
new file mode 100644 (file)
index 0000000..f6e4b4c
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.uikit.tests.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.util.tests.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.util.tests.dll
new file mode 100644 (file)
index 0000000..21c093d
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/nunit.util.tests.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/test-assembly.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/test-assembly.dll
new file mode 100644 (file)
index 0000000..2f1d71d
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/test-assembly.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/test-utilities.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/test-utilities.dll
new file mode 100644 (file)
index 0000000..87a0b2a
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/test-utilities.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/timing-tests.dll b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/timing-tests.dll
new file mode 100644 (file)
index 0000000..6be4cfc
Binary files /dev/null and b/trunk/Libraries/Json40r2/Source/Tools/NUnit/tests/timing-tests.dll differ
diff --git a/trunk/Libraries/Json40r2/Source/Tools/PSake/psake.psm1 b/trunk/Libraries/Json40r2/Source/Tools/PSake/psake.psm1
new file mode 100644 (file)
index 0000000..4641028
--- /dev/null
@@ -0,0 +1,1208 @@
+# psake
+# Copyright (c) 2010 James Kovacs
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+#Requires -Version 2.0
+
+#-- Private Module Variables (Listed here for quick reference)
+[system.collections.stack]$script:context
+
+#-- Public Module Variables -- The psake hashtable variable is initialized in the invoke-psake function
+$script:psake = @{}
+$script:psake.use_exit_on_error = $false    # determines if psake uses the "exit()" function when an exception occurs
+$script:psake.log_error = $false            # determines if the exception details are written to a file
+$script:psake.build_success = $false        # indicates that the current build was successful
+$script:psake.version = "4.00"              # contains the current version of psake
+$script:psake.build_script_file = $null     # contains a System.IO.FileInfo for the current build file
+$script:psake.framework_version = ""        # contains the framework version # for the current build
+$script:psake.default_build_file_name = 'default.ps1'
+
+Export-ModuleMember -Variable "psake"
+
+#-- Private Module Functions
+function ExecuteTask
+{
+  param([string]$taskName)
+
+  Assert (![string]::IsNullOrEmpty($taskName)) "Task name should not be null or empty string"
+
+  $taskKey = $taskName.ToLower()
+
+    Assert ($script:context.Peek().tasks.Contains($taskKey)) "task [$taskName] does not exist"
+
+    if ($script:context.Peek().executedTasks.Contains($taskKey))
+  {
+    return
+  }
+
+  Assert (!$script:context.Peek().callStack.Contains($taskKey)) "Error: Circular reference found for task, $taskName"
+
+  $script:context.Peek().callStack.Push($taskKey)
+
+  $task = $script:context.Peek().tasks.$taskKey
+
+  $taskName = $task.Name
+
+  $precondition_is_valid = if ($task.Precondition -ne $null) {& $task.Precondition} else {$true}
+
+  if (!$precondition_is_valid)
+  {
+    "Precondition was false not executing $name"
+  }
+  else
+  {
+    if ($taskKey -ne 'default')
+    {
+      $stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
+
+      if ( ($task.PreAction -ne $null) -or ($task.PostAction -ne $null) )
+      {
+        Assert ($task.Action -ne $null) "Error: Action parameter must be specified when using PreAction or PostAction parameters"
+      }
+
+      if ($task.Action -ne $null)
+      {
+        try
+        {
+          foreach($childTask in $task.DependsOn)
+          {
+            ExecuteTask $childTask
+          }
+
+          $script:context.Peek().currentTaskName = $taskName
+
+          if ($script:context.Peek().taskSetupScriptBlock -ne $null)
+          {
+            & $script:context.Peek().taskSetupScriptBlock
+          }
+
+          if ($task.PreAction -ne $null)
+          {
+            & $task.PreAction
+          }
+
+          $script:context.Peek().formatTaskNameString -f $taskName
+          & $task.Action
+
+          if ($task.PostAction -ne $null)
+          {
+            & $task.PostAction
+          }
+
+          if ($script:context.Peek().taskTearDownScriptBlock -ne $null)
+          {
+            & $script:context.Peek().taskTearDownScriptBlock
+          }
+        }
+        catch
+        {
+          if ($task.ContinueOnError)
+          {
+            "-"*70
+            "Error in Task [$taskName] $_"
+            "-"*70
+          }
+          else
+          {
+            throw $_
+          }
+        }
+      } # if ($task.Action -ne $null)
+      else
+      {
+        #no Action was specified but we still execute all the dependencies
+        foreach($childTask in $task.DependsOn)
+        {
+          ExecuteTask $childTask
+        }
+      }
+      $stopwatch.stop()
+      $task.Duration = $stopwatch.Elapsed
+    } # if ($name.ToLower() -ne 'default')
+    else
+    {
+      foreach($childTask in $task.DependsOn)
+      {
+        ExecuteTask $childTask
+      }
+    }
+
+    if ($task.Postcondition -ne $null)
+    {
+      Assert (& $task.Postcondition) "Error: Postcondition failed for $taskName"
+    }
+  }
+
+  $poppedTaskKey = $script:context.Peek().callStack.Pop()
+
+  Assert ($poppedTaskKey -eq $taskKey) "Error: CallStack was corrupt. Expected $taskKey, but got $poppedTaskKey."
+
+  $script:context.Peek().executedTasks.Push($taskKey)
+}
+
+function Configure-BuildEnvironment
+{
+  if ($framework.Length -ne 3 -and $framework.Length -ne 6) {
+    throw "Error: Invalid .NET Framework version, $framework, specified"
+  }
+  $versionPart = $framework.Substring(0,3)
+  $bitnessPart = $framework.Substring(3)
+  $versions = $null
+  switch ($versionPart)
+  {
+    '1.0' { $versions = @('v1.0.3705')  }
+    '1.1' { $versions = @('v1.1.4322')  }
+    '2.0' { $versions = @('v2.0.50727') }
+    '3.0' { $versions = @('v2.0.50727') }
+    '3.5' { $versions = @('v3.5','v2.0.50727') }
+    '4.0' { $versions = @('v4.0.30319') }
+    default { throw "Error: Unknown .NET Framework version, $versionPart, specified in $framework" }
+  }
+
+  $bitness = 'Framework'
+  if($versionPart -ne '1.0' -and $versionPart -ne '1.1') {
+    switch ($bitnessPart)
+    {
+      'x86' { $bitness = 'Framework' }
+      'x64' { $bitness = 'Framework64' }
+      $null {
+        $ptrSize = [System.IntPtr]::Size
+        switch ($ptrSize)
+        {
+          4 { $bitness = 'Framework' }
+          8 { $bitness = 'Framework64' }
+          default { throw "Error: Unknown pointer size ($ptrSize) returned from System.IntPtr." }
+        }
+      }
+      default { throw "Error: Unknown .NET Framework bitness, $bitnessPart, specified in $framework" }
+    }
+  }
+  $frameworkDirs = $versions | foreach { "$env:windir\Microsoft.NET\$bitness\$_\" }
+
+  $frameworkDirs | foreach { Assert (test-path $_) "Error: No .NET Framework installation directory found at $_" }
+
+  $env:path = [string]::Join(';', $frameworkDirs) + ";$env:path"
+  #if any error occurs in a PS function then "stop" processing immediately
+  # this does not effect any external programs that return a non-zero exit code
+  $global:ErrorActionPreference = "Stop"
+}
+
+function Cleanup-Environment
+{
+  $env:path = $script:context.Peek().originalEnvPath
+  Set-Location $script:context.Peek().originalDirectory
+  $global:ErrorActionPreference = $script:context.Peek().originalErrorActionPreference
+}
+
+#borrowed from Jeffrey Snover http://blogs.msdn.com/powershell/archive/2006/12/07/resolve-error.aspx
+function Resolve-Error($ErrorRecord=$Error[0])
+{
+  "ErrorRecord"
+  $ErrorRecord | Format-List * -Force | Out-String -Stream | ? {$_}
+  ""
+  "ErrorRecord.InvocationInfo"
+  $ErrorRecord.InvocationInfo | Format-List * | Out-String -Stream | ? {$_}
+  ""
+  "Exception"
+  $Exception = $ErrorRecord.Exception
+  for ($i = 0; $Exception; $i++, ($Exception = $Exception.InnerException))
+  {
+    "$i" * 70
+    $Exception | Format-List * -Force | Out-String -Stream | ? {$_}
+    ""
+  }
+}
+
+function Write-Documentation
+{
+  $list = New-Object System.Collections.ArrayList
+  foreach($key in $script:context.Peek().tasks.Keys)
+  {
+    if($key -eq "default")
+    {
+      continue
+    }
+    $task = $script:context.Peek().tasks.$key
+    $content = "" | Select-Object Name, Description
+    $content.Name = $task.Name
+    $content.Description = $task.Description
+    $index = $list.Add($content)
+  }
+
+  $list | Sort 'Name' | Format-Table -Auto
+}
+
+function Write-TaskTimeSummary
+{
+  "-"*70
+  "Build Time Report"
+  "-"*70
+  $list = @()
+  while ($script:context.Peek().executedTasks.Count -gt 0)
+  {
+    $taskKey = $script:context.Peek().executedTasks.Pop()
+    $task = $script:context.Peek().tasks.$taskKey
+    if($taskKey -eq "default")
+    {
+      continue
+    }
+    $list += "" | Select-Object @{Name="Name";Expression={$task.Name}}, @{Name="Duration";Expression={$task.Duration}}
+  }
+  [Array]::Reverse($list)
+  $list += "" | Select-Object @{Name="Name";Expression={"Total:"}}, @{Name="Duration";Expression={$stopwatch.Elapsed}}
+  $list | Format-Table -Auto | Out-String -Stream | ? {$_}  # using "Out-String -Stream" to filter out the blank line that Format-Table prepends
+}
+
+#-- Public Module Functions
+function Exec
+{
+<#
+.SYNOPSIS
+Helper function for executing command-line programs.
+
+.DESCRIPTION
+This is a helper function that runs a scriptblock and checks the PS variable $lastexitcode to see if an error occcured.
+If an error is detected then an exception is thrown.  This function allows you to run command-line programs without
+having to explicitly check fthe $lastexitcode variable.
+
+.PARAMETER cmd
+The scriptblock to execute.  This scriptblock will typically contain the command-line invocation.
+Required
+
+.PARAMETER errorMessage
+The error message used for the exception that is thrown.
+Optional
+
+.EXAMPLE
+exec { svn info $repository_trunk } "Error executing SVN. Please verify SVN command-line client is installed"
+
+This example calls the svn command-line client.
+
+.LINK
+Assert
+Invoke-psake
+Task
+Properties
+Include
+FormatTaskName
+TaskSetup
+TaskTearDown
+#>
+[CmdletBinding(
+    SupportsShouldProcess=$False,
+    SupportsTransactions=$False,
+    ConfirmImpact="None",
+    DefaultParameterSetName="")]
+
+  param(
+      [Parameter(Position=0,Mandatory=1)][scriptblock]$cmd,
+    [Parameter(Position=1,Mandatory=0)][string]$errorMessage = "Error executing command: " + $cmd
+  )
+     & $cmd
+     if ($lastexitcode -ne 0)
+     {
+          throw $errorMessage
+     }
+}
+
+function Assert
+{
+<#
+.SYNOPSIS
+Helper function for "Design by Contract" assertion checking.
+
+.DESCRIPTION
+This is a helper function that makes the code less noisy by eliminating many of the "if" statements
+that are normally required to verify assumptions in the code.
+
+.PARAMETER conditionToCheck
+The boolean condition to evaluate
+Required
+
+.PARAMETER failureMessage
+The error message used for the exception if the conditionToCheck parameter is false
+Required
+
+.EXAMPLE
+Assert $false "This always throws an exception"
+
+This example always throws an exception
+
+.EXAMPLE
+Assert ( ($i % 2) -eq 0 ) "%i is not an even number"
+
+This exmaple may throw an exception if $i is not an even number
+
+.LINK
+Invoke-psake
+Task
+Properties
+Include
+FormatTaskName
+TaskSetup
+TaskTearDown
+
+.NOTES
+It might be necessary to wrap the condition with paranthesis to force PS to evaluate the condition
+so that a boolean value is calculated and passed into the 'conditionToCheck' parameter.
+
+Example:
+    Assert 1 -eq 2 "1 doesn't equal 2"
+
+PS will pass 1 into the condtionToCheck variable and PS will look for a parameter called "eq" and
+throw an exception with the following message "A parameter cannot be found that matches parameter name 'eq'"
+
+The solution is to wrap the condition in () so that PS will evaluate it first.
+
+    Assert (1 -eq 2) "1 doesn't equal 2"
+#>
+[CmdletBinding(
+    SupportsShouldProcess=$False,
+    SupportsTransactions=$False,
+    ConfirmImpact="None",
+    DefaultParameterSetName="")]
+
+  param(
+    [Parameter(Position=0,Mandatory=1)]$conditionToCheck,
+    [Parameter(Position=1,Mandatory=1)]$failureMessage
+  )
+  if (!$conditionToCheck) { throw $failureMessage }
+}
+
+function Task
+{
+<#
+.SYNOPSIS
+Defines a build task to be executed by psake
+
+.DESCRIPTION
+This function creates a 'task' object that will be used by the psake engine to execute a build task.
+Note: There must be at least one task called 'default' in the build script
+
+.PARAMETER Name
+The name of the task
+Required
+
+.PARAMETER Action
+A scriptblock containing the statements to execute
+Optional
+
+.PARAMETER PreAction
+A scriptblock to be executed before the 'Action' scriptblock.
+Note: This parameter is ignored if the 'Action' scriptblock is not defined.
+Optional
+
+.PARAMETER PostAction
+A scriptblock to be executed after the 'Action' scriptblock.
+Note: This parameter is ignored if the 'Action' scriptblock is not defined.
+Optional
+
+.PARAMETER Precondition
+A scriptblock that is executed to determine if the task is executed or skipped.
+This scriptblock should return $true or $false
+Optional
+
+.PARAMETER Postcondition
+A scriptblock that is executed to determine if the task completed its job correctly.
+An exception is thrown if the scriptblock returns $false.
+Optional
+
+.PARAMETER ContinueOnError
+If this switch parameter is set then the task will not cause the build to fail when an exception is thrown
+
+.PARAMETER Depends
+An array of tasks that this task depends on.  They will be executed before the current task is executed.
+
+.PARAMETER Description
+A description of the task.
+
+.EXAMPLE
+A sample build script is shown below:
+
+task default -depends Test
+
+task Test -depends Compile, Clean {
+  "This is a test"
+}
+
+task Compile -depends Clean {
+  "Compile"
+}
+
+task Clean {
+  "Clean"
+}
+
+The 'default' task is required and should not contain an 'Action' parameter.
+It uses the 'depends' parameter to specify that 'Test' is a dependency
+
+The 'Test' task uses the 'depends' parameter to specify that 'Compile' and 'Clean' are dependencies
+The 'Compile' task depends on the 'Clean' task.
+
+Note:
+The 'Action' parameter is defaulted to the script block following the 'Clean' task.
+
+The equivalent 'Test' task is shown below:
+
+task Test -depends Compile, Clean -Action {
+  $testMessage
+}
+
+The output for the above sample build script is shown below:
+Executing task, Clean...
+Clean
+Executing task, Compile...
+Compile
+Executing task, Test...
+This is a test
+
+Build Succeeded!
+
+----------------------------------------------------------------------
+Build Time Report
+----------------------------------------------------------------------
+Name    Duration
+----    --------
+Clean   00:00:00.0065614
+Compile 00:00:00.0133268
+Test    00:00:00.0225964
+Total:  00:00:00.0782496
+
+.LINK
+Invoke-psake
+Properties
+Include
+FormatTaskName
+TaskSetup
+TaskTearDown
+Assert
+#>
+[CmdletBinding(
+    SupportsShouldProcess=$False,
+    SupportsTransactions=$False,
+    ConfirmImpact="None",
+    DefaultParameterSetName="")]
+  param(
+    [Parameter(Position=0,Mandatory=1)]
+    [string]$name = $null,
+    [Parameter(Position=1,Mandatory=0)]
+    [scriptblock]$action = $null,
+    [Parameter(Position=2,Mandatory=0)]
+    [scriptblock]$preaction = $null,
+    [Parameter(Position=3,Mandatory=0)]
+    [scriptblock]$postaction = $null,
+    [Parameter(Position=4,Mandatory=0)]
+    [scriptblock]$precondition = $null,
+    [Parameter(Position=5,Mandatory=0)]
+    [scriptblock]$postcondition = $null,
+    [Parameter(Position=6,Mandatory=0)]
+    [switch]$continueOnError = $false,
+    [Parameter(Position=7,Mandatory=0)]
+    [string[]]$depends = @(),
+    [Parameter(Position=8,Mandatory=0)]
+    [string]$description = $null
+    )
+
+  if ($name.ToLower() -eq 'default')
+  {
+    Assert ($action -eq $null) "Error: 'default' task cannot specify an action"
+  }
+
+  $newTask = @{
+    Name = $name
+    DependsOn = $depends
+    PreAction = $preaction
+    Action = $action
+    PostAction = $postaction
+    Precondition = $precondition
+    Postcondition = $postcondition
+    ContinueOnError = $continueOnError
+    Description = $description
+    Duration = 0
+  }
+
+  $taskKey = $name.ToLower()
+
+  Assert (!$script:context.Peek().tasks.ContainsKey($taskKey)) "Error: Task, $name, has already been defined."
+
+  $script:context.Peek().tasks.$taskKey = $newTask
+}
+
+function Properties
+{
+<#
+.SYNOPSIS
+Define a scriptblock that contains assignments to variables that will be available to all tasks in the build script
+
+.DESCRIPTION
+A build script may declare a "Properies" function which allows you to define
+variables that will be available to all the "Task" functions in the build script.
+
+.PARAMETER properties
+The script block containing all the variable assignment statements
+Required
+
+.EXAMPLE
+A sample build script is shown below:
+
+Properties {
+  $build_dir = "c:\build"
+  $connection_string = "datasource=localhost;initial catalog=northwind;integrated security=sspi"
+}
+
+Task default -depends Test
+
+Task Test -depends Compile, Clean {
+}
+
+Task Compile -depends Clean {
+}
+
+Task Clean {
+}
+
+.LINK
+Invoke-psake
+Task
+Include
+FormatTaskName
+TaskSetup
+TaskTearDown
+Assert
+
+.NOTES
+You can have more than 1 "Properties" function defined in the script
+#>
+[CmdletBinding(
+    SupportsShouldProcess=$False,
+    SupportsTransactions=$False,
+    ConfirmImpact="None",
+    DefaultParameterSetName="")]
+  param(
+  [Parameter(Position=0,Mandatory=1)]
+  [scriptblock]$properties
+  )
+  $script:context.Peek().properties += $properties
+}
+
+function Include
+{
+<#
+.SYNOPSIS
+Include the functions or code of another powershell script file into the current build script's scope
+
+.DESCRIPTION
+A build script may declare an "includes" function which allows you to define
+a file containing powershell code to be included and added to the scope of
+the currently running build script.
+
+.PARAMETER fileNamePathToInclude
+A string containing the path and name of the powershell file to include
+Required
+
+.EXAMPLE
+A sample build script is shown below:
+
+Include ".\build_utils.ps1"
+
+Task default -depends Test
+
+Task Test -depends Compile, Clean {
+}
+
+Task Compile -depends Clean {
+}
+
+Task Clean {
+}
+
+
+.LINK
+Invoke-psake
+Task
+Properties
+FormatTaskName
+TaskSetup
+TaskTearDown
+Assert
+
+.NOTES
+You can have more than 1 "Include" function defined in the script
+#>
+[CmdletBinding(
+    SupportsShouldProcess=$False,
+    SupportsTransactions=$False,
+    ConfirmImpact="None",
+    DefaultParameterSetName="")]
+  param(
+  [Parameter(Position=0,Mandatory=1)]
+  [string]$fileNamePathToInclude
+  )
+  Assert (test-path $fileNamePathToInclude) "Error: Unable to include $fileNamePathToInclude. File not found."
+  $script:context.Peek().includes.Enqueue((Resolve-Path $fileNamePathToInclude));
+}
+
+function FormatTaskName
+{
+<#
+.SYNOPSIS
+Allows you to define a format mask that will be used when psake displays
+the task name
+
+.DESCRIPTION
+Allows you to define a format mask that will be used when psake displays
+the task name.  The default is "Executing task, {0}..."
+
+.PARAMETER format
+A string containing the format mask to use, it should contain a placeholder ({0})
+that will be used to substitute the task name.
+Required
+
+.EXAMPLE
+A sample build script is shown below:
+
+FormatTaskName "[Task: {0}]"
+
+Task default -depends Test
+
+Task Test -depends Compile, Clean {
+}
+
+Task Compile -depends Clean {
+}
+
+Task Clean {
+}
+
+You should get the following output:
+------------------------------------
+
+[Task: Clean]
+[Task: Compile]
+[Task: Test]
+
+Build Succeeded
+
+----------------------------------------------------------------------
+Build Time Report
+----------------------------------------------------------------------
+Name    Duration
+----    --------
+Clean   00:00:00.0043477
+Compile 00:00:00.0102130
+Test    00:00:00.0182858
+Total:  00:00:00.0698071
+
+.LINK
+Invoke-psake
+Include
+Task
+Properties
+TaskSetup
+TaskTearDown
+Assert
+#>
+[CmdletBinding(
+    SupportsShouldProcess=$False,
+    SupportsTransactions=$False,
+    ConfirmImpact="None",
+    DefaultParameterSetName="")]
+  param(
+  [Parameter(Position=0,Mandatory=1)]
+  [string]$format
+  )
+  $script:context.Peek().formatTaskNameString = $format
+}
+
+function TaskSetup
+{
+<#
+.SYNOPSIS
+Adds a scriptblock that will be executed before each task
+
+.DESCRIPTION
+This function will accept a scriptblock that will be executed before each
+task in the build script.
+
+.PARAMETER include
+A scriptblock to execute
+Required
+
+.EXAMPLE
+A sample build script is shown below:
+
+Task default -depends Test
+
+Task Test -depends Compile, Clean {
+}
+
+Task Compile -depends Clean {
+}
+
+Task Clean {
+}
+
+TaskSetup {
+  "Running 'TaskSetup' for task $script:context.Peek().currentTaskName"
+}
+
+You should get the following output:
+------------------------------------
+
+Running 'TaskSetup' for task Clean
+Executing task, Clean...
+Running 'TaskSetup' for task Compile
+Executing task, Compile...
+Running 'TaskSetup' for task Test
+Executing task, Test...
+
+Build Succeeded
+
+----------------------------------------------------------------------
+Build Time Report
+----------------------------------------------------------------------
+Name    Duration
+----    --------
+Clean   00:00:00.0054018
+Compile 00:00:00.0123085
+Test    00:00:00.0236915
+Total:  00:00:00.0739437
+
+.LINK
+Invoke-psake
+Include
+Task
+Properties
+FormatTaskName
+TaskTearDown
+Assert
+#>
+[CmdletBinding(
+    SupportsShouldProcess=$False,
+    SupportsTransactions=$False,
+    ConfirmImpact="None",
+    DefaultParameterSetName="")]
+  param(
+  [Parameter(Position=0,Mandatory=1)]
+  [scriptblock]$setup
+  )
+  $script:context.Peek().taskSetupScriptBlock = $setup
+}
+
+function TaskTearDown
+{
+<#
+.SYNOPSIS
+Adds a scriptblock that will be executed after each task
+
+.DESCRIPTION
+This function will accept a scriptblock that will be executed after each
+task in the build script.
+
+.PARAMETER include
+A scriptblock to execute
+Required
+
+.EXAMPLE
+A sample build script is shown below:
+
+Task default -depends Test
+
+Task Test -depends Compile, Clean {
+}
+
+Task Compile -depends Clean {
+}
+
+Task Clean {
+}
+
+TaskTearDown {
+  "Running 'TaskTearDown' for task $script:context.Peek().currentTaskName"
+}
+
+You should get the following output:
+------------------------------------
+
+Executing task, Clean...
+Running 'TaskTearDown' for task Clean
+Executing task, Compile...
+Running 'TaskTearDown' for task Compile
+Executing task, Test...
+Running 'TaskTearDown' for task Test
+
+Build Succeeded
+
+----------------------------------------------------------------------
+Build Time Report
+----------------------------------------------------------------------
+Name    Duration
+----    --------
+Clean   00:00:00.0064555
+Compile 00:00:00.0218902
+Test    00:00:00.0309151
+Total:  00:00:00.0858301
+
+.LINK
+Invoke-psake
+Include
+Task
+Properties
+FormatTaskName
+TaskSetup
+Assert
+#>
+[CmdletBinding(
+    SupportsShouldProcess=$False,
+    SupportsTransactions=$False,
+    ConfirmImpact="None",
+    DefaultParameterSetName="")]
+  param(
+  [Parameter(Position=0,Mandatory=1)]
+  [scriptblock]$teardown)
+  $script:context.Peek().taskTearDownScriptBlock = $teardown
+}
+
+function Invoke-psake
+{
+<#
+.SYNOPSIS
+Runs a psake build script.
+
+.DESCRIPTION
+This function runs a psake build script
+
+.PARAMETER BuildFile
+The psake build script to execute (default: default.ps1).
+
+.PARAMETER TaskList
+A comma-separated list of task names to execute
+
+.PARAMETER Framework
+The version of the .NET framework you want to build. You can append x86 or x64 to force a specific framework. If not specified, x86 or x64 will be detected based on the bitness of the PowerShell process.
+Possible values: '1.0', '1.1', '2.0', '2.0x86', '2.0x64', '3.0', '3.0x86', '3.0x64', '3.5', '3.5x86', '3.5x64', '4.0', '4.0x86', '4.0x64'
+Default = '3.5'
+
+.PARAMETER Docs
+Prints a list of tasks and their descriptions
+
+.PARAMETER Parameters
+A hashtable containing parameters to be passed into the current build script.  These parameters will be processed before the 'Properties' function of the script is processed.  This means you can access parameters from within the 'Properties' function!
+
+.PARAMETER Properties
+A hashtable containing properties to be passed into the current build script.  These properties will override matching properties that are found in the 'Properties' function of the script.
+
+.EXAMPLE
+Invoke-psake
+
+Runs the 'default' task in the 'default.ps1' build script in the current directory
+
+.EXAMPLE
+Invoke-psake '.\build.ps1'
+
+Runs the 'default' task in the '.build.ps1' build script
+
+.EXAMPLE
+Invoke-psake '.\build.ps1' Tests,Package
+
+Runs the 'Tests' and 'Package' tasks in the '.build.ps1' build script
+
+.EXAMPLE
+Invoke-psake Tests
+
+If you have your Tasks in the .\default.ps1. This example will run the 'Tests' tasks in the 'default.ps1' build script.
+
+.EXAMPLE
+Invoke-psake 'Tests, Package'
+
+If you have your Tasks in the .\default.ps1. This example will run the 'Tests' and 'Package' tasks in the 'default.ps1' build script.
+NOTE: the quotes around the list of tasks to execute.
+
+.EXAMPLE
+Invoke-psake '.\build.ps1' -docs
+
+Prints a report of all the tasks and their descriptions and exits
+
+.EXAMPLE
+Invoke-psake .\parameters.ps1 -parameters @{"p1"="v1";"p2"="v2"}
+
+Runs the build script called 'parameters.ps1' and passes in parameters 'p1' and 'p2' with values 'v1' and 'v2'
+
+.EXAMPLE
+Invoke-psake .\properties.ps1 -properties @{"x"="1";"y"="2"}
+
+Runs the build script called 'properties.ps1' and passes in parameters 'x' and 'y' with values '1' and '2'
+
+.OUTPUTS
+    If there is an exception and '$psake.use_exit_on_error' -eq $true
+  then runs exit(1) to set the DOS lastexitcode variable
+  otherwise set the '$psake.build_success variable' to $true or $false depending
+  on whether an exception was thrown
+
+.NOTES
+When the psake module is loaded a variabled called $psake is created it is a hashtable
+containing some variables that can be used to configure psake:
+
+$psake.use_exit_on_error = $false   # determines if psake uses the "exit()" function when an exception occurs
+$psake.log_error = $false           # determines if the exception details are written to a file
+$psake.build_success = $false       # indicates that the current build was successful
+$psake.version = "4.00"             # contains the current version of psake
+$psake.build_script_file = $null    # contains a System.IO.FileInfo for the current build file
+$psake.framework_version = ""       # contains the framework version # for the current build
+
+$psake.use_exit_on_error and $psake.log_error are boolean variables that can be set before you call Invoke-Psake.
+
+You should see the following when you display the contents of the $psake variable right after importing psake
+
+PS projects:\psake> Import-Module .\psake.psm1
+PS projects:\psake> $psake
+
+Name                           Value
+----                           -----
+version                        4.00
+build_script_file
+use_exit_on_error              False
+build_success                  False
+log_error                      False
+framework_version
+
+After a build is executed the following $psake values are updated (build_script_file, build_success, and framework_version)
+
+PS projects:\psake> Invoke-psake .\examples\default.ps1
+Executing task: Clean
+Executed Clean!
+Executing task: Compile
+Executed Compile!
+Executing task: Test
+Executed Test!
+
+Build Succeeded!
+
+----------------------------------------------------------------------
+Build Time Report
+----------------------------------------------------------------------
+Name    Duration
+----    --------
+Clean   00:00:00.0798486
+Compile 00:00:00.0869948
+Test    00:00:00.0958225
+Total:  00:00:00.2712414
+
+PS projects:\psake> $psake
+
+Name                           Value
+----                           -----
+version                        4.00
+build_script_file              C:\Users\Jorge\Documents\Projects\psake\examples\default.ps1
+use_exit_on_error              False
+build_success                  True
+log_error                      False
+framework_version              3.5
+
+.LINK
+Task
+Include
+Properties
+FormatTaskName
+TaskSetup
+TaskTearDown
+Assert
+#>
+[CmdletBinding(
+    SupportsShouldProcess=$False,
+    SupportsTransactions=$False,
+    ConfirmImpact="None",
+    DefaultParameterSetName="")]
+
+  param(
+    [Parameter(Position=0,Mandatory=0)]
+    [string]$buildFile = $script:psake.default_build_file_name,
+    [Parameter(Position=1,Mandatory=0)]
+    [string[]]$taskList = @(),
+    [Parameter(Position=2,Mandatory=0)]
+    [string]$framework = '3.5',
+    [Parameter(Position=3,Mandatory=0)]
+    [switch]$docs = $false,
+    [Parameter(Position=4,Mandatory=0)]
+    [System.Collections.Hashtable]$parameters = @{},
+    [Parameter(Position=5, Mandatory=0)]
+    [System.Collections.Hashtable]$properties = @{}
+  )
+
+  Begin
+  {
+    $script:psake.build_success = $false
+    $script:psake.framework_version = $framework
+
+    if ($script:context -eq $null)
+    {
+      $script:context = New-Object System.Collections.Stack
+    }
+
+    $script:context.push(@{
+                           "formatTaskNameString" = "Executing task: {0}";
+                           "taskSetupScriptBlock" = $null;
+                           "taskTearDownScriptBlock" = $null;
+                           "executedTasks" = New-Object System.Collections.Stack;
+                           "callStack" = New-Object System.Collections.Stack;
+                           "originalEnvPath" = $env:path;
+                           "originalDirectory" = Get-Location;
+                           "originalErrorActionPreference" = $global:ErrorActionPreference;
+                           "tasks" = @{};
+                           "properties" = @();
+                           "includes" = New-Object System.Collections.Queue;
+    })
+  }
+
+  Process
+  {
+    try
+    {
+    $stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
+
+    <#
+      If the default.ps1 file exists and the given "buildfile" isn't found assume that the given 
+      $buildFile is actually the target Tasks to execute in the default.ps1 script.
+    #>
+    if((Test-Path $script:psake.default_build_file_name ) -and !(test-path $buildFile)) {
+      $list = New-Object System.Collections.ArrayList
+      foreach($t in $buildFile.Split(',')) {
+        $t1 = $t.Trim()
+        if($t1 -ne $null -or $t1 -ne "") {
+          $list.Add($t1)
+        }
+      }
+      $taskList = $list.ToArray()
+      $buildFile = $script:psake.default_build_file_name
+    }
+
+    # Execute the build file to set up the tasks and defaults
+    Assert (test-path $buildFile) "Error: Could not find the build file, $buildFile."
+
+    $script:psake.build_script_file = dir $buildFile
+    set-location $script:psake.build_script_file.Directory
+    . $script:psake.build_script_file.FullName
+
+    if ($docs)
+    {
+    Write-Documentation
+    Cleanup-Environment
+    return
+    }
+
+    Configure-BuildEnvironment
+
+    # N.B. The initial dot (.) indicates that variables initialized/modified
+    #      in the propertyBlock are available in the parent scope.
+    while ($script:context.Peek().includes.Count -gt 0)
+    {
+      $includeBlock = $script:context.Peek().includes.Dequeue()
+      . $includeBlock
+    }
+
+    foreach($key in $parameters.keys)
+    {
+      if (test-path "variable:\$key")
+      {
+        set-item -path "variable:\$key" -value $parameters.$key | out-null
+      }
+      else
+      {
+        new-item -path "variable:\$key" -value $parameters.$key | out-null
+      }
+    }
+
+    foreach($propertyBlock in $script:context.Peek().properties)
+    {
+      . $propertyBlock
+    }
+
+    foreach($key in $properties.keys)
+    {
+      if (test-path "variable:\$key")
+      {
+        set-item -path "variable:\$key" -value $properties.$key | out-null
+      }
+    }
+
+    # Execute the list of tasks or the default task
+    if($taskList.Length -ne 0)
+    {
+      foreach($task in $taskList)
+      {
+        ExecuteTask $task
+      }
+    }
+    elseif ($script:context.Peek().tasks.default -ne $null)
+    {
+      ExecuteTask default
+    }
+    else
+    {
+      throw 'Error: default task required'
+    }
+
+    $stopwatch.Stop()
+
+    "`nBuild Succeeded!`n"
+
+    Write-TaskTimeSummary
+
+    $script:psake.build_success = $true
+    }
+    catch
+    {
+    #Append detailed exception and script variables to error log file
+    if ($script:psake.log_error)
+    {
+      $errorLogFile = "psake-error-log-{0}.log" -f ([DateTime]::Now.ToString("yyyyMMdd"))
+      "-" * 70 >> $errorLogFile
+      "{0}: An Error Occurred. See Error Details Below: " -f [DateTime]::Now >>$errorLogFile
+      "-" * 70 >> $errorLogFile
+      Resolve-Error $_ >> $errorLogFile
+      "-" * 70 >> $errorLogFile
+      "Script Variables" >> $errorLogFile
+      "-" * 70 >> $errorLogFile
+      Get-Variable -scope script >> $errorLogFile
+    }
+
+    $buildFileName = Split-Path $buildFile -leaf
+    if (test-path $buildFile) { $buildFileName = $script:psake.build_script_file.Name }
+    Write-Host -foregroundcolor Red ($buildFileName + ":" + $_)
+
+    if ($script:psake.use_exit_on_error)
+    {
+      exit(1)
+    }
+    else
+    {
+      $script:psake.build_success = $false
+    }
+    }
+  } #Process
+
+  End
+  {
+  # Clear out any global variables
+  Cleanup-Environment
+  [void]$script:context.Pop()
+  }
+}
+
+Export-ModuleMember -Function "Invoke-psake","Task","Properties","Include","FormatTaskName","TaskSetup","TaskTearDown","Assert","Exec"
\ No newline at end of file
diff --git a/trunk/Libraries/Json40r2/readme.txt b/trunk/Libraries/Json40r2/readme.txt
new file mode 100644 (file)
index 0000000..ca85148
--- /dev/null
@@ -0,0 +1,59 @@
+Json.NET
+
+http://james.newtonking.com/projects/json-net.aspx
+http://www.codeplex.com/json/
+
+
+Description:
+
+Json.NET makes working with JSON formatted data in .NET simple. Quickly read and write JSON using LINQ to JSON or serialize your .NET objects with a single method call using the JsonSerializer.
+
+-Flexible JSON serializer to convert .NET objects to JSON and back again 
+-LINQ to JSON for reading and writing JSON 
+-Writes indented, easy to read JSON 
+-Convert JSON to and from XML 
+-Supports Silverlight and Windows Phone
+
+
+
+Versions:
+
+Json.NET comes in different versions for the various .NET frameworks.
+
+-DotNet:
+  .NET latest (4.0)
+
+-DotNet35:
+  .NET 3.5 SP1, Mono
+
+-DotNet20:
+  .NET 2.0
+
+-Silverlight:
+  Silverlight 4.0
+
+-WindowsPhone:
+  Windows Phone 7
+
+Microsoft stopped support for the Compact Framework in Visual Studio 2010.
+For a Compact Framework 3.5 build download Json.NET 3.5.
+
+For a Silverlight 3.0 build down download Json.NET 3.5.
+
+
+Instructions:
+
+ 1. Extract Newtonsoft.Json.dll and Newtonsoft.Json.xml from the archive's /bin directory into your own applications.
+ 2. Add a reference to Newtonsoft.Json.dll within Visual Studio.NET to your project.
+
+
+
+License:
+
+Copyright (c) 2007 James Newton-King
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/AbstractStreamBase.cs b/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/AbstractStreamBase.cs
new file mode 100644 (file)
index 0000000..88d8cd6
--- /dev/null
@@ -0,0 +1,85 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: AbstractStreamBase.cs
+//
+//--------------------------------------------------------------------------
+
+namespace System.IO
+{
+    /// <summary>Base stream class that implements all of Stream's abstract members.</summary>
+    public abstract class AbstractStreamBase : Stream
+    {
+        /// <summary>Determines whether data can be read from the stream.</summary>
+        public override bool CanRead { get { return false; } }
+        /// <summary>Determines whether data can be written to the stream.</summary>
+        public override bool CanWrite { get { return false; } }
+        /// <summary>Determines whether the stream can be seeked.</summary>
+        public override bool CanSeek { get { return false; } }
+        /// <summary>Flushes the contents of the stream to the underlying storage.</summary>
+        public override void Flush() { }
+
+        /// <summary>Gets the length of the stream.</summary>
+        public override long Length { get { throw new NotSupportedException(); } }
+
+        /// <summary>Gets or sets the current position of the stream.</summary>
+        public override long Position
+        {
+            get { throw new NotSupportedException(); }
+            set { throw new NotSupportedException(); }
+        }
+
+        /// <summary>
+        /// Reads a sequence of bytes from the current
+        /// stream and advances the position within the stream by the number of bytes read.
+        /// </summary>
+        /// <param name="buffer">
+        /// An array of bytes. When Read returns, the buffer contains the specified
+        /// byte array with the values between offset and (offset + count - 1) replaced
+        /// by the bytes read from the current source.
+        /// </param>
+        /// <param name="offset">
+        /// The zero-based byte offset in buffer at which to begin storing the data read
+        /// from the current stream.
+        /// </param>
+        /// <param name="count">The maximum number of bytes to be read from the current stream.</param>
+        /// <returns>
+        /// The total number of bytes read into the buffer. This can be less than the
+        /// number of bytes requested if that many bytes are not currently available,
+        /// or zero (0) if the end of the stream has been reached.
+        /// </returns>
+        public override int Read(byte[] buffer, int offset, int count)
+        {
+            throw new NotSupportedException();
+        }
+
+        /// <summary>Sets the position within the current stream.</summary>
+        /// <param name="offset">A byte offset relative to the origin parameter.</param>
+        /// <param name="origin">
+        /// A value of type System.IO.SeekOrigin indicating the reference point used
+        /// to obtain the new position.
+        /// </param>
+        /// <returns>The new position within the current stream.</returns>
+        public override long Seek(long offset, SeekOrigin origin)
+        {
+            throw new NotSupportedException();
+        }
+
+        /// <summary>Sets the length of the current stream.</summary>
+        /// <param name="value">The desired length of the current stream in bytes.</param>
+        public override void SetLength(long value)
+        {
+            throw new NotSupportedException();
+        }
+
+        /// <summary>Writes a sequence of bytes to the stream.</summary>
+        /// <param name="buffer">An array of bytes. Write copies count bytes from buffer to the stream.</param>
+        /// <param name="offset">The zero-based byte offset in buffer at which to begin copying bytes to the stream.</param>
+        /// <param name="count">The number of bytes to be written to the current stream.</param>
+        public override void Write(byte[] buffer, int offset, int count)
+        {
+            throw new NotSupportedException();
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/ActionCountdownEvent.cs b/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/ActionCountdownEvent.cs
new file mode 100644 (file)
index 0000000..ef05e83
--- /dev/null
@@ -0,0 +1,75 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: ActionCountdownEvent.cs
+//
+//--------------------------------------------------------------------------
+
+namespace System.Threading
+{
+    /// <summary>Runs an action when the CountdownEvent reaches zero.</summary>
+    public class ActionCountdownEvent : IDisposable
+    {
+        private readonly CountdownEvent _event;
+        private readonly Action _action;
+        private readonly ExecutionContext _context;
+
+        /// <summary>Initializes the ActionCountdownEvent.</summary>
+        /// <param name="initialCount">The number of signals required to set the CountdownEvent.</param>
+        /// <param name="action">The delegate to be invoked when the count reaches zero.</param>
+        public ActionCountdownEvent(int initialCount, Action action)
+        {
+            // Validate arguments
+            if (initialCount < 0) throw new ArgumentOutOfRangeException("initialCount");
+            if (action == null) throw new ArgumentNullException("action");
+
+            // Store the action and create the event from the initial count. If the initial count forces the
+            // event to be set, run the action immediately. Otherwise, capture the current execution context
+            // so we can run the action in the right context later on.
+            _action = action;
+            _event = new CountdownEvent(initialCount);
+            if (initialCount == 0) action();
+            else _context = ExecutionContext.Capture();
+        }
+
+        /// <summary>Increments the current count by one.</summary>
+        public void AddCount() 
+        {
+            // Just delegate to the underlying event
+            _event.AddCount(); 
+        }
+
+        /// <summary>Registers a signal with the event, decrementing its count.</summary>
+        public void Signal()
+        {
+            // If signaling the event causes it to become set
+            if (_event.Signal())
+            {
+                // Execute the action.  If we were able to capture a context
+                // at instantiation time, use that context to execute the action.
+                // Otherwise, just run the action.
+                if (_context != null)
+                {
+                    ExecutionContext.Run(_context, _ => _action(), null);
+                }
+                else _action();
+            }
+        }
+
+        /// <summary>Releases all resources used by the current instance.</summary>
+        public void Dispose()
+        {
+            Dispose(true);
+        }
+
+        /// <summary>Releases all resources used by the current instance.</summary>
+        /// <param name="disposing">
+        /// true if called because the object is being disposed; otherwise, false.
+        /// </param>
+        protected void Dispose(bool disposing)
+        {
+            if (disposing) _event.Dispose();
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/AsyncCoordination/AsyncBarrier.cs b/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/AsyncCoordination/AsyncBarrier.cs
new file mode 100644 (file)
index 0000000..8b05a1a
--- /dev/null
@@ -0,0 +1,57 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: AsyncBarrier.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Diagnostics;
+using System.Threading.Tasks;
+
+namespace System.Threading.Async
+{
+    /// <summary>Provides an asynchronous barrier.</summary>
+    [DebuggerDisplay("ParticipantCount={ParticipantCount}, RemainingCount={RemainingCount}")]
+    public sealed class AsyncBarrier
+    {
+        /// <summary>The number of participants in the barrier.</summary>
+        private readonly int _participantCount;
+        /// <summary>The task used to signal completion of the current round.</summary>
+        private TaskCompletionSource<object> _currentSignalTask;
+        /// <summary>The number of participants remaining to arrive for this round.</summary>
+        private int _remainingParticipants;
+
+        /// <summary>Initializes the BarrierAsync with the specified number of participants.</summary>
+        /// <param name="participantCount">The number of participants in the barrier.</param>
+        public AsyncBarrier(int participantCount)
+        {
+            if (participantCount <= 0) throw new ArgumentOutOfRangeException("participantCount");
+            _participantCount = participantCount;
+
+            _remainingParticipants = participantCount;
+            _currentSignalTask = new TaskCompletionSource<object>();
+        }
+
+        /// <summary>Gets the participant count.</summary>
+        public int ParticipantCount { get { return _participantCount; } }
+        /// <summary>Gets the number of participants still not yet arrived in this round.</summary>
+        public int RemainingCount { get { return _remainingParticipants; } }
+
+        /// <summary>Signals that a participant has arrived.</summary>
+        /// <returns>A Task that will be signaled when the current round completes.</returns>
+        public Task SignalAndWait()
+        {
+            var curCts = _currentSignalTask;
+        #pragma warning disable 420
+            if (Interlocked.Decrement(ref _remainingParticipants) == 0)
+        #pragma warning restore 420
+            {
+                _remainingParticipants = _participantCount;
+                _currentSignalTask = new TaskCompletionSource<object>();
+                curCts.SetResult(null);
+            }
+            return curCts.Task;
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/AsyncCoordination/AsyncCache.cs b/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/AsyncCoordination/AsyncCache.cs
new file mode 100644 (file)
index 0000000..b506154
--- /dev/null
@@ -0,0 +1,162 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: AsyncCache.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Net;
+using System.Threading.Tasks;
+
+namespace System.Threading
+{
+    /// <summary>Debugger type proxy for AsyncCache.</summary>
+    /// <typeparam name="TKey">Specifies the type of the cache's keys.</typeparam>
+    /// <typeparam name="TValue">Specifies the type of the cache's values.</typeparam>
+    internal class AsyncCache_DebugView<TKey, TValue>
+    {
+        private readonly AsyncCache<TKey, TValue> _asyncCache;
+
+        internal AsyncCache_DebugView(AsyncCache<TKey,TValue> asyncCache)
+        {
+            _asyncCache = asyncCache;
+        }
+
+        [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
+        internal KeyValuePair<TKey, Task<TValue>>[] Values
+        {
+            get { return _asyncCache.ToArray(); }
+        }
+    }
+
+    /// <summary>Caches asynchronously retrieved data.</summary>
+    /// <typeparam name="TKey">Specifies the type of the cache's keys.</typeparam>
+    /// <typeparam name="TValue">Specifies the type of the cache's values.</typeparam>
+    [DebuggerTypeProxy(typeof(AsyncCache_DebugView<,>))]
+    [DebuggerDisplay("Count={Count}")]
+    public class AsyncCache<TKey, TValue> : ICollection<KeyValuePair<TKey,Task<TValue>>>
+    {
+        /// <summary>The factory to use to create tasks.</summary>
+        private readonly Func<TKey, Task<TValue>> _valueFactory;
+        /// <summary>The dictionary to store all of the tasks.</summary>
+        private readonly ConcurrentDictionary<TKey, Lazy<Task<TValue>>> _map;
+
+        /// <summary>Initializes the cache.</summary>
+        /// <param name="valueFactory">A factory for producing the cache's values.</param>
+        public AsyncCache(Func<TKey, Task<TValue>> valueFactory)
+        {
+            if (valueFactory == null) throw new ArgumentNullException("loader");
+            _valueFactory = valueFactory;
+            _map = new ConcurrentDictionary<TKey, Lazy<Task<TValue>>>();
+        }
+
+        /// <summary>Gets a Task to retrieve the value for the specified key.</summary>
+        /// <param name="key">The key whose value should be retrieved.</param>
+        /// <returns>A Task for the value of the specified key.</returns>
+        public Task<TValue> GetValue(TKey key)
+        {
+            if (key == null) throw new ArgumentNullException("key");
+            var value = new Lazy<Task<TValue>>(() => _valueFactory(key));
+            return _map.GetOrAdd(key, value).Value;
+        }
+
+        /// <summary>Sets the value for the specified key.</summary>
+        /// <param name="key">The key whose value should be set.</param>
+        /// <param name="value">The value to which the key should be set.</param>
+        public void SetValue(TKey key, TValue value)
+        {
+            SetValue(key, Task.Factory.FromResult(value));
+        }
+
+        /// <summary>Sets the value for the specified key.</summary>
+        /// <param name="key">The key whose value should be set.</param>
+        /// <param name="value">The value to which the key should be set.</param>
+        public void SetValue(TKey key, Task<TValue> value)
+        {
+            if (key == null) throw new ArgumentNullException("key");
+            _map[key] = LazyExtensions.Create(value);
+        }
+
+        /// <summary>Gets a Task to retrieve the value for the specified key.</summary>
+        /// <param name="key">The key whose value should be retrieved.</param>
+        /// <returns>A Task for the value of the specified key.</returns>
+        public Task<TValue> this[TKey key]
+        {
+            get { return GetValue(key); }
+            set { SetValue(key, value); }
+        }
+
+        /// <summary>Empties the cache.</summary>
+        public void Clear() { _map.Clear(); }
+
+        /// <summary>Gets the number of items in the cache.</summary>
+        public int Count { get { return _map.Count; } }
+
+        /// <summary>Gets an enumerator for the contents of the cache.</summary>
+        /// <returns>An enumerator for the contents of the cache.</returns>
+        public IEnumerator<KeyValuePair<TKey, Task<TValue>>> GetEnumerator()
+        {
+            return _map.Select(p => new KeyValuePair<TKey, Task<TValue>>(p.Key, p.Value.Value)).GetEnumerator();
+        }
+
+        /// <summary>Gets an enumerator for the contents of the cache.</summary>
+        /// <returns>An enumerator for the contents of the cache.</returns>
+        IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
+
+        /// <summary>Adds or overwrites the specified entry in the cache.</summary>
+        /// <param name="item">The item to be added.</param>
+        void ICollection<KeyValuePair<TKey, Task<TValue>>>.Add(KeyValuePair<TKey, Task<TValue>> item)
+        {
+            this[item.Key] = item.Value;
+        }
+
+        /// <summary>Determines whether the cache contains the specified key.</summary>
+        /// <param name="item">The item contained the key to be searched for.</param>
+        /// <returns>True if the cache contains the key; otherwise, false.</returns>
+        bool ICollection<KeyValuePair<TKey, Task<TValue>>>.Contains(KeyValuePair<TKey, Task<TValue>> item)
+        {
+            return _map.ContainsKey(item.Key);
+        }
+
+        /// <summary>
+        /// Copies the elements of the System.Collections.Generic.ICollection<T> to an
+        /// System.Array, starting at a particular System.Array index.
+        /// </summary>
+        /// <param name="array">
+        /// The one-dimensional System.Array that is the destination of the elements
+        /// copied from System.Collections.Generic.ICollection<T>. The System.Array must
+        /// have zero-based indexing.
+        /// </param>
+        /// <param name="arrayIndex">The zero-based index in array at which copying begins.</param>
+        void ICollection<KeyValuePair<TKey, Task<TValue>>>.CopyTo(KeyValuePair<TKey, Task<TValue>>[] array, int arrayIndex)
+        {
+            ((ICollection<KeyValuePair<TKey, Task<TValue>>>)_map).CopyTo(array, arrayIndex);
+        }
+
+        /// <summary>Gets whether the cache is read-only.</summary>
+        bool ICollection<KeyValuePair<TKey, Task<TValue>>>.IsReadOnly { get { return false; } }
+
+        /// <summary>Removes the specified key from the cache.</summary>
+        /// <param name="item">The item containing the key to be removed.</param>
+        /// <returns>True if the item could be removed; otherwise, false.</returns>
+        bool ICollection<KeyValuePair<TKey, Task<TValue>>>.Remove(KeyValuePair<TKey, Task<TValue>> item)
+        {
+            Lazy<Task<TValue>> value;
+            return _map.TryRemove(item.Key, out value);
+        }
+    }
+
+    /// <summary>An asynchronous cache for downloaded HTML.</summary>
+    public sealed class HtmlAsyncCache : AsyncCache<Uri, string>
+    {
+        /// <summary>Initializes the HtmlCache.</summary>
+        public HtmlAsyncCache() :
+            base(uri => new WebClient().DownloadStringTask(uri)) { }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/AsyncCoordination/AsyncCall.cs b/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/AsyncCoordination/AsyncCall.cs
new file mode 100644 (file)
index 0000000..58f3196
--- /dev/null
@@ -0,0 +1,256 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: AsyncCall.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+namespace System.Threading.Tasks
+{
+    /// <summary>Asynchronously invokes a handler for every posted item.</summary>
+    /// <typeparam name="T">Specifies the type of data processed by the instance.</typeparam>
+    public sealed class AsyncCall<T> : MarshalByRefObject
+    {
+        /// <summary>
+        /// A queue that stores the posted data.  Also serves as the syncObj for protected instance state.
+        /// A ConcurrentQueue is used to enable lock-free dequeues while running with a single consumer task.
+        /// </summary>
+        private readonly ConcurrentQueue<T> _queue;
+        /// <summary>The delegate to invoke for every element.</summary>
+        private readonly Delegate _handler;
+        /// <summary>The maximum number of items that should be processed by an individual task.</summary>
+        private readonly int _maxItemsPerTask;
+        /// <summary>The TaskFactory to use to launch new tasks.</summary>
+        private readonly TaskFactory _tf;
+        /// <summary>The options to use for parallel processing of data.</summary>
+        private readonly ParallelOptions _parallelOptions;
+        /// <summary>Whether a processing task has been scheduled.</summary>
+        private int _processingCount;
+
+        /// <summary>Initializes the AsyncCall with an action to execute for each element.</summary>
+        /// <param name="actionHandler">The action to run for every posted item.</param>
+        /// <param name="maxDegreeOfParallelism">The maximum degree of parallelism to use.  If not specified, 1 is used for serial execution.</param>
+        /// <param name="scheduler">The scheduler to use.  If null, the default scheduler is used.</param>
+        /// <param name="maxItemsPerTask">The maximum number of items to be processed per task.  If not specified, Int32.MaxValue is used.</param>
+        public AsyncCall(Action<T> actionHandler, int maxDegreeOfParallelism = 1, int maxItemsPerTask = Int32.MaxValue, TaskScheduler scheduler = null) :
+            this(maxDegreeOfParallelism, maxItemsPerTask, scheduler)
+        {
+            if (actionHandler == null) throw new ArgumentNullException("handler");
+            _handler = actionHandler;
+        }
+
+        /// <summary>
+        /// Initializes the AsyncCall with a function to execute for each element.  The function returns an Task 
+        /// that represents the asynchronous completion of that element's processing.
+        /// </summary>
+        /// <param name="functionHandler">The function to run for every posted item.</param>
+        /// <param name="maxDegreeOfParallelism">The maximum degree of parallelism to use.  If not specified, 1 is used for serial execution.</param>
+        /// <param name="scheduler">The scheduler to use.  If null, the default scheduler is used.</param>
+        public AsyncCall(Func<T,Task> functionHandler, int maxDegreeOfParallelism = 1, TaskScheduler scheduler = null) :
+            this(maxDegreeOfParallelism, 1, scheduler)
+        {
+            if (functionHandler == null) throw new ArgumentNullException("handler");
+            _handler = functionHandler;
+        }
+
+        /// <summary>General initialization of the AsyncCall.  Another constructor must initialize the delegate.</summary>
+        /// <param name="maxDegreeOfParallelism">The maximum degree of parallelism to use.  If not specified, 1 is used for serial execution.</param>
+        /// <param name="maxItemsPerTask">The maximum number of items to be processed per task.  If not specified, Int32.MaxValue is used.</param>
+        /// <param name="scheduler">The scheduler to use.  If null, the default scheduler is used.</param>
+        private AsyncCall(int maxDegreeOfParallelism = 1, int maxItemsPerTask = Int32.MaxValue, TaskScheduler scheduler = null)
+        {
+            // Validate arguments
+            if (maxDegreeOfParallelism < 1) throw new ArgumentOutOfRangeException("maxDegreeOfParallelism");
+            if (maxItemsPerTask < 1) throw new ArgumentOutOfRangeException("maxItemsPerTask");
+            if (scheduler == null) scheduler = TaskScheduler.Default;
+
+            // Configure the instance
+            _queue = new ConcurrentQueue<T>();
+            _maxItemsPerTask = maxItemsPerTask;
+            _tf = new TaskFactory(scheduler);
+            if (maxDegreeOfParallelism != 1)
+            {
+                _parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = maxDegreeOfParallelism, TaskScheduler = scheduler };
+            }
+        }
+
+        /// <summary>Post an item for processing.</summary>
+        /// <param name="item">The item to be processed.</param>
+        public void Post(T item)
+        {
+            lock (_queue)
+            {
+                // Add the item to the internal queue
+                _queue.Enqueue(item);
+
+                // Check to see whether the right number of tasks have been scheduled.
+                // If they haven't, schedule one for this new piece of data.
+                if (_handler is Action<T>)
+                {
+                    if (_processingCount == 0)
+                    {
+                        _processingCount = 1;
+                        _tf.StartNew(ProcessItemsActionTaskBody);
+                    }
+                }
+                else if (_handler is Func<T, Task>)
+                {
+                    if (_processingCount == 0 ||  // is anyone at all currently processing?
+                        (_parallelOptions != null && _processingCount < _parallelOptions.MaxDegreeOfParallelism && // are enough workers currently processing?
+                        !_queue.IsEmpty)) // and, as an optimization, double check to make sure the item hasn't already been picked up by another worker
+                    {
+                        _processingCount++;
+                        _tf.StartNew(ProcessItemFunctionTaskBody, null);
+                    }
+                }
+                else Debug.Fail("_handler is an invalid delegate type");
+            }
+        }
+
+        /// <summary>Gets an enumerable that yields the items to be processed at this time.</summary>
+        /// <returns>An enumerable of items.</returns>
+        private IEnumerable<T> GetItemsToProcess()
+        {
+            // Yield the next elements to be processed until either there are no more elements
+            // or we've reached the maximum number of elements that an individual task should process.
+            int processedCount = 0;
+            T nextItem;
+            while (processedCount < _maxItemsPerTask && _queue.TryDequeue(out nextItem))
+            {
+                yield return nextItem;
+                processedCount++;
+            }
+        }
+
+        /// <summary>Used as the body of an action task to process items in the queue.</summary>
+        private void ProcessItemsActionTaskBody()
+        {
+            try
+            {
+                // Get the handler
+                Action<T> handler = (Action<T>)_handler;
+
+                // Process up to _maxItemsPerTask items, either serially or in parallel
+                // based on the provided maxDegreeOfParallelism (which determines
+                // whether a ParallelOptions is instantiated).
+                if (_parallelOptions == null)
+                    foreach (var item in GetItemsToProcess()) handler(item);
+                else
+                    Parallel.ForEach(GetItemsToProcess(), _parallelOptions, handler);
+            }
+            finally
+            {
+                lock (_queue)
+                {
+                    // If there are still items in the queue, schedule another task to continue processing.
+                    // Otherwise, note that we're no longer processing.
+                    if (!_queue.IsEmpty) _tf.StartNew(ProcessItemsActionTaskBody, TaskCreationOptions.PreferFairness);
+                    else _processingCount = 0;
+                }
+            }
+        }
+
+        /// <summary>Used as the body of a function task to process items in the queue.</summary>
+        private void ProcessItemFunctionTaskBody(object ignored)
+        {
+            bool anotherTaskQueued = false;
+            try
+            {
+                // Get the handler
+                Func<T, Task> handler = (Func<T, Task>)_handler;
+
+                // Get the next item from the queue to process
+                T nextItem;
+                if (_queue.TryDequeue(out nextItem))
+                {
+                    // Run the handler and get the follow-on task.
+                    // If we got a follow-on task, run this process again when the task completes.
+                    // If we didn't, just start another task to keep going now.
+                    var task = handler(nextItem);
+                    if (task != null) task.ContinueWith(ProcessItemFunctionTaskBody, _tf.Scheduler);
+                    else _tf.StartNew(ProcessItemFunctionTaskBody, null);
+
+                    // We've queued a task to continue processing, which means that logically
+                    // we're still maintaining the same level of parallelism.
+                    anotherTaskQueued = true;
+                }
+            }
+            finally
+            {
+                // If we didn't queue up another task to continue processing (either
+                // because an exception occurred, or we failed to grab an item from the queue)
+                if (!anotherTaskQueued)
+                {
+                    lock (_queue)
+                    {
+                        // Verify that there's still nothing in the queue, now under the same
+                        // lock that the queuer needs to take in order to increment the processing count
+                        // and launch a new processor.
+                        if (!_queue.IsEmpty) _tf.StartNew(ProcessItemFunctionTaskBody, null);
+                        else _processingCount--;
+                    }
+                }
+            }
+        }
+    }
+
+    /// <summary>Provides static factory methods for creating AsyncCall(Of T) instances.</summary>
+    public static class AsyncCall
+    {
+        /// <summary>Initializes the AsyncCall with an action to execute for each element.</summary>
+        /// <param name="actionHandler">The action to run for every posted item.</param>
+        /// <param name="maxDegreeOfParallelism">The maximum degree of parallelism to use.  If not specified, 1 is used for serial execution.</param>
+        /// <param name="scheduler">The scheduler to use.  If null, the default scheduler is used.</param>
+        /// <param name="maxItemsPerTask">The maximum number of items to be processed per task.  If not specified, Int32.MaxValue is used.</param>
+        public static AsyncCall<T> Create<T>(Action<T> actionHandler, int maxDegreeOfParallelism = 1, int maxItemsPerTask = Int32.MaxValue, TaskScheduler scheduler = null)
+        {
+            return new AsyncCall<T>(actionHandler, maxDegreeOfParallelism, maxItemsPerTask, scheduler);
+        }
+
+        /// <summary>
+        /// Initializes the AsyncCall with a function to execute for each element.  The function returns an Task 
+        /// that represents the asynchronous completion of that element's processing.
+        /// </summary>
+        /// <param name="functionHandler">The function to run for every posted item.</param>
+        /// <param name="maxDegreeOfParallelism">The maximum degree of parallelism to use.  If not specified, 1 is used for serial execution.</param>
+        /// <param name="maxItemsPerTask">The maximum number of items to be processed per task.  If not specified, Int32.MaxValue is used.</param>
+        /// <param name="scheduler">The scheduler to use.  If null, the default scheduler is used.</param>
+        public static AsyncCall<T> Create<T>(Func<T, Task> functionHandler, int maxDegreeOfParallelism = 1, TaskScheduler scheduler = null)
+        {
+            return new AsyncCall<T>(functionHandler, maxDegreeOfParallelism, scheduler);
+        }
+
+        /// <summary>Initializes the AsyncCall in the specified AppDomain with an action to execute for each element.</summary>
+        /// <param name="actionHandler">The action to run for every posted item.</param>
+        /// <param name="maxDegreeOfParallelism">The maximum degree of parallelism to use.  If not specified, 1 is used for serial execution.</param>
+        /// <param name="maxItemsPerTask">The maximum number of items to be processed per task.  If not specified, Int32.MaxValue is used.</param>
+        public static AsyncCall<T> CreateInTargetAppDomain<T>(AppDomain targetDomain, Action<T> actionHandler, int maxDegreeOfParallelism = 1, int maxItemsPerTask = Int32.MaxValue)
+        {
+            return (AsyncCall<T>)targetDomain.CreateInstanceAndUnwrap(
+                typeof(AsyncCall<T>).Assembly.FullName, typeof(AsyncCall<T>).FullName,
+                false, Reflection.BindingFlags.CreateInstance, null,
+                new object[] { actionHandler, maxDegreeOfParallelism, maxItemsPerTask, null },
+                null, null);
+        }
+
+        /// <summary>
+        /// Initializes the AsyncCall in the specified AppDomain with a function to execute for each element.  
+        /// The function returns an Task that represents the asynchronous completion of that element's processing.
+        /// </summary>
+        /// <param name="functionHandler">The action to run for every posted item.</param>
+        /// <param name="maxDegreeOfParallelism">The maximum degree of parallelism to use.  If not specified, 1 is used for serial execution.</param>
+        public static AsyncCall<T> CreateInTargetAppDomain<T>(AppDomain targetDomain, Func<T, Task> functionHandler, int maxDegreeOfParallelism = 1)
+        {
+            return (AsyncCall<T>)targetDomain.CreateInstanceAndUnwrap(
+                typeof(AsyncCall<T>).Assembly.FullName, typeof(AsyncCall<T>).FullName,
+                false, Reflection.BindingFlags.CreateInstance, null,
+                new object[] { functionHandler, maxDegreeOfParallelism, null },
+                null, null);
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/AsyncCoordination/AsyncProducerConsumerCollection.cs b/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/AsyncCoordination/AsyncProducerConsumerCollection.cs
new file mode 100644 (file)
index 0000000..cb0148b
--- /dev/null
@@ -0,0 +1,68 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: AsyncProducerConsumerCollection.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Concurrent;
+using System.Diagnostics;
+using System.Threading.Tasks;
+
+namespace System.Threading.Async
+{
+    /// <summary>Provides an asynchronous producer/consumer collection.</summary>
+    [DebuggerDisplay("Count={CurrentCount}")]
+    public sealed class AsyncProducerConsumerCollection<T> : IDisposable
+    {
+        /// <summary>Asynchronous semaphore used to keep track of asynchronous work.</summary>
+        private AsyncSemaphore _semaphore = new AsyncSemaphore();
+        /// <summary>The data stored in the collection.</summary>
+        private IProducerConsumerCollection<T> _collection;
+
+        /// <summary>Initializes the asynchronous producer/consumer collection to store data in a first-in-first-out (FIFO) order.</summary>
+        public AsyncProducerConsumerCollection() : this(new ConcurrentQueue<T>()) { }
+
+        /// <summary>Initializes the asynchronous producer/consumer collection.</summary>
+        /// <param name="collection">The underlying collection to use to store data.</param>
+        public AsyncProducerConsumerCollection(IProducerConsumerCollection<T> collection)
+        {
+            if (collection == null) throw new ArgumentNullException("collection");
+            _collection = collection;
+        }
+
+        /// <summary>Adds an element to the collection.</summary>
+        /// <param name="item">The item to be added.</param>
+        public void Add(T item)
+        {
+            if (_collection.TryAdd(item)) _semaphore.Release();
+            else throw new InvalidOperationException("Invalid collection");
+        }
+
+        /// <summary>Takes an element from the collection asynchronously.</summary>
+        /// <returns>A Task that represents the element removed from the collection.</returns>
+        public Task<T> Take()
+        {
+            return _semaphore.Wait().ContinueWith(_ =>
+            {
+                T result;
+                if (!_collection.TryTake(out result)) throw new InvalidOperationException("Invalid collection");
+                return result;
+            }, TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.OnlyOnRanToCompletion);
+        }
+
+        /// <summary>Gets the number of elements in the collection.</summary>
+        public int Count { get { return _collection.Count; } }
+
+        /// <summary>Disposes of the collection.</summary>
+        public void Dispose()
+        {
+            if (_semaphore != null)
+            {
+                _semaphore.Dispose();
+                _semaphore = null;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/AsyncCoordination/AsyncReaderWriter.cs b/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/AsyncCoordination/AsyncReaderWriter.cs
new file mode 100644 (file)
index 0000000..f893591
--- /dev/null
@@ -0,0 +1,226 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: AsyncReaderWriter.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using System.Diagnostics;
+
+namespace System.Threading.Async
+{
+    /// <summary>Provides for asynchronous exclusive and concurrent execution support.</summary>
+    [DebuggerDisplay("WaitingConcurrent={WaitingConcurrent}, WaitingExclusive={WaitingExclusive}, CurrentReaders={CurrentConcurrent}, Exclusive={CurrentlyExclusive}")]
+    public sealed class AsyncReaderWriter
+    {
+        /// <summary>The lock that protects all shared state in this instance.</summary>
+        private readonly object _lock = new object();
+        /// <summary>The queue of concurrent readers waiting to execute.</summary>
+        private readonly Queue<Task> _waitingConcurrent = new Queue<Task>();
+        /// <summary>The queue of exclusive writers waiting to execute.</summary>
+        private readonly Queue<Task> _waitingExclusive = new Queue<Task>();
+        /// <summary>The number of concurrent readers currently executing.</summary>
+        private int _currentConcurrent = 0;
+        /// <summary>The number of exclusive writers currently executing.</summary>
+        private bool _currentlyExclusive = false;
+        /// <summary>The non-generic factory to use for task creation.</summary>
+        private TaskFactory _factory;
+
+        /// <summary>Initializes the ReaderWriterAsync.</summary>
+        public AsyncReaderWriter() { _factory = Task.Factory; }
+
+        /// <summary>Initializes the ReaderWriterAsync with the specified TaskFactory for us in creating all tasks.</summary>
+        /// <param name="factory">The TaskFactory to use to create all tasks.</param>
+        public AsyncReaderWriter(TaskFactory factory)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            _factory = factory;
+        }
+
+        /// <summary>Gets the number of exclusive operations currently queued.</summary>
+        public int WaitingExclusive { get { lock (_lock) return _waitingExclusive.Count; } }
+        /// <summary>Gets the number of concurrent operations currently queued.</summary>
+        public int WaitingConcurrent { get { lock (_lock) return _waitingConcurrent.Count; } }
+        /// <summary>Gets the number of concurrent operations currently executing.</summary>
+        public int CurrentConcurrent { get { lock (_lock) return _currentConcurrent; } }
+        /// <summary>Gets whether an exclusive operation is currently executing.</summary>
+        public bool CurrentlyExclusive { get { lock (_lock) return _currentlyExclusive; } }
+
+        /// <summary>Queues an exclusive writer action to the ReaderWriterAsync.</summary>
+        /// <param name="action">The action to be executed exclusively.</param>
+        /// <returns>A Task that represents the execution of the provided action.</returns>
+        public Task QueueExclusiveWriter(Action action)
+        {
+            // Create the task.  This Task will be started by the coordination primitive
+            // when it's safe to do so, e.g. when there are no other tasks associated
+            // with this async primitive executing.
+            var task = _factory.Create(state =>
+            {
+                // Run the user-provided action
+                try { ((Action)state)(); }
+                // Ensure that we clean up when we're done
+                finally { FinishExclusiveWriter(); }
+            }, action);
+
+            // Now that we've created the task, we need to do something with it, either queueing it or scheduling it immediately
+            lock (_lock)
+            {
+                // If there's already a task running, or if there are any other exclusive tasks that need to run,
+                // queue it.  Otherwise, no one else is running or wants to run, so schedule it now.
+                if (_currentlyExclusive || _currentConcurrent > 0 || _waitingExclusive.Count > 0) _waitingExclusive.Enqueue(task);
+                else RunExclusive_RequiresLock(task);
+            }
+
+            // Return the created task for the caller to track.
+            return task;
+        }
+
+        /// <summary>Queues an exclusive writer function to the ReaderWriterAsync.</summary>
+        /// <param name="function">The function to be executed exclusively.</param>
+        /// <returns>A Task that represents the execution of the provided function.</returns>
+        public Task<TResult> QueueExclusiveWriter<TResult>(Func<TResult> function)
+        {
+            // Create the task.  This Task will be started by the coordination primitive
+            // when it's safe to do so, e.g. when there are no other tasks associated
+            // with this async primitive executing.
+            var task = _factory.Create(state =>
+            {
+                // Run the user-provided function
+                try { return ((Func<TResult>)state)(); }
+                // Ensure that we clean up when we're done
+                finally { FinishExclusiveWriter(); }
+            }, function);
+
+            // Now that we've created the task, we need to do something with it, either queueing it or scheduling it immediately
+            lock (_lock)
+            {
+                // If there's already a task running, or if there are any other exclusive tasks that need to run,
+                // queue it.  Otherwise, no one else is running or wants to run, so schedule it now.
+                if (_currentlyExclusive || _currentConcurrent > 0 || _waitingExclusive.Count > 0) _waitingExclusive.Enqueue(task);
+                else RunExclusive_RequiresLock(task);
+            }
+
+            // Return the created task for the caller to track.
+            return task;
+        }
+
+        /// <summary>Queues a concurrent reader action to the ReaderWriterAsync.</summary>
+        /// <param name="action">The action to be executed concurrently.</param>
+        /// <returns>A Task that represents the execution of the provided action.</returns>
+        public Task QueueConcurrentReader(Action action)
+        {
+            // Create the task.  This Task will be started by the coordination primitive
+            // when it's safe to do so, e.g. when there are no exclusive tasks running
+            // or waiting to run.
+            Task task = _factory.Create(state =>
+            {
+                // Run the user-provided action
+                try { ((Action)state)(); }
+                // Ensure that we clean up when we're done
+                finally { FinishConcurrentReader(); }
+            }, action);
+
+            // Now that we've created the task, we need to do something with it, either queueing it or scheduling it immediately
+            lock (_lock)
+            {
+                // If there are any exclusive tasks running or waiting, queue the concurrent task
+                if (_currentlyExclusive || _waitingExclusive.Count > 0) _waitingConcurrent.Enqueue(task);
+                // Otherwise schedule it immediately
+                else RunConcurrent_RequiresLock(task);
+            }
+
+            // Return the task to the caller.
+            return task;
+        }
+
+        /// <summary>Queues a concurrent reader function to the ReaderWriterAsync.</summary>
+        /// <param name="function">The function to be executed concurrently.</param>
+        /// <returns>A Task that represents the execution of the provided function.</returns>
+        public Task<TResult> QueueConcurrentReader<TResult>(Func<TResult> function)
+        {
+            // Create the task.  This Task will be started by the coordination primitive
+            // when it's safe to do so, e.g. when there are no exclusive tasks running
+            // or waiting to run.
+            var task = _factory.Create(state =>
+            {
+                // Run the user-provided function
+                try { return ((Func<TResult>)state)(); }
+                // Ensure that we clean up when we're done
+                finally { FinishConcurrentReader(); }
+            }, function);
+
+            // Now that we've created the task, we need to do something with it, either queueing it or scheduling it immediately
+            lock (_lock)
+            {
+                // If there are any exclusive tasks running or waiting, queue the concurrent task
+                if (_currentlyExclusive || _waitingExclusive.Count > 0) _waitingConcurrent.Enqueue(task);
+                // Otherwise schedule it immediately
+                else RunConcurrent_RequiresLock(task);
+            }
+
+            // Return the task to the caller.
+            return task;
+        }
+
+        /// <summary>Starts the specified exclusive task.</summary>
+        /// <param name="exclusive">The exclusive task to be started.</param>
+        /// <remarks>This must only be executed while holding the instance's lock.</remarks>
+        private void RunExclusive_RequiresLock(Task exclusive)
+        {
+            _currentlyExclusive = true;
+            exclusive.Start(_factory.GetTargetScheduler());
+        }
+
+        /// <summary>Starts the specified concurrent task.</summary>
+        /// <param name="concurrent">The exclusive task to be started.</param>
+        /// <remarks>This must only be executed while holding the instance's lock.</remarks>
+        private void RunConcurrent_RequiresLock(Task concurrent)
+        {
+            _currentConcurrent++;
+            concurrent.Start(_factory.GetTargetScheduler());
+        }
+
+        /// <summary>Starts all queued concurrent tasks.</summary>
+        /// <remarks>This must only be executed while holding the instance's lock.</remarks>
+        private void RunConcurrent_RequiresLock()
+        {
+            while (_waitingConcurrent.Count > 0) RunConcurrent_RequiresLock(_waitingConcurrent.Dequeue());
+        }
+
+        /// <summary>Completes the processing of a concurrent reader.</summary>
+        private void FinishConcurrentReader()
+        {
+            lock (_lock)
+            {
+                // Update the tracking count of the number of concurrently executing tasks
+                _currentConcurrent--;
+
+                // If we've now hit zero tasks running concurrently and there are any waiting writers, run one of them
+                if (_currentConcurrent == 0 && _waitingExclusive.Count > 0) RunExclusive_RequiresLock(_waitingExclusive.Dequeue());
+
+                // Otherwise, if there are no waiting writers but there are waiting readers for some reason (they should
+                // have started when they were added by the user), run all concurrent tasks waiting.
+                else if (_waitingExclusive.Count == 0 && _waitingConcurrent.Count > 0) RunConcurrent_RequiresLock();
+            }
+        }
+
+        /// <summary>Completes the processing of an exclusive writer.</summary>
+        private void FinishExclusiveWriter()
+        {
+            lock (_lock)
+            {
+                // We're no longer executing exclusively, though this might get reversed shortly
+                _currentlyExclusive = false;
+
+                // If there are any more waiting exclusive tasks, run the next one in line
+                if (_waitingExclusive.Count > 0) RunExclusive_RequiresLock(_waitingExclusive.Dequeue());
+
+                // Otherwise, if there are any waiting concurrent tasks, run them all
+                else if (_waitingConcurrent.Count > 0) RunConcurrent_RequiresLock();
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/AsyncCoordination/AsyncSemaphore.cs b/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/AsyncCoordination/AsyncSemaphore.cs
new file mode 100644 (file)
index 0000000..cdbabb7
--- /dev/null
@@ -0,0 +1,158 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: AsyncSemaphore.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using System.Diagnostics;
+
+namespace System.Threading.Async
+{
+    /// <summary>Provides an asynchronous semaphore.</summary>
+    [DebuggerDisplay("CurrentCount={CurrentCount}, MaximumCount={MaximumCount}, WaitingCount={WaitingCount}")]
+    public sealed class AsyncSemaphore : IDisposable
+    {
+        /// <summary>The current count.</summary>
+        private int _currentCount;
+        /// <summary>The maximum count. If _maxCount isn't positive, the instance has been disposed.</remarks>
+        private int _maxCount;
+        /// <summary>Tasks waiting to be completed when the semaphore has count available.</summary>
+        private Queue<TaskCompletionSource<object>> _waitingTasks;
+
+        /// <summary>Initializes the SemaphoreAsync with a count of zero and a maximum count of Int32.MaxValue.</summary>
+        public AsyncSemaphore() : this(0) { }
+
+        /// <summary>Initializes the SemaphoreAsync with the specified count and a maximum count of Int32.MaxValue.</summary>
+        /// <param name="initialCount">The initial count to use as the current count.</param>
+        public AsyncSemaphore(int initialCount) : this(initialCount, Int32.MaxValue) { }
+
+        /// <summary>Initializes the SemaphoreAsync with the specified counts.</summary>
+        /// <param name="initialCount">The initial count to use as the current count.</param>
+        /// <param name="maxCount">The maximum count allowed.</param>
+        public AsyncSemaphore(int initialCount, int maxCount)
+        {
+            if (maxCount <= 0) throw new ArgumentOutOfRangeException("maxCount");
+            if (initialCount > maxCount || initialCount < 0) throw new ArgumentOutOfRangeException("initialCount");
+            _currentCount = initialCount;
+            _maxCount = maxCount;
+            _waitingTasks = new Queue<TaskCompletionSource<object>>();
+        }
+
+        /// <summary>Gets the current count.</summary>
+        public int CurrentCount { get { return _currentCount; } }
+        /// <summary>Gets the maximum count.</summary>
+        public int MaximumCount { get { return _maxCount; } }
+        /// <summary>Gets the number of operations currently waiting on the semaphore.</summary>
+        public int WaitingCount { get { lock(_waitingTasks) return _waitingTasks.Count; } }
+
+        /// <summary>Waits for a unit to be available in the semaphore.</summary>
+        /// <returns>A Task that will be completed when a unit is available and this Wait operation succeeds.</returns>
+        public Task Wait()
+        {
+            ThrowIfDisposed();
+            lock (_waitingTasks)
+            {
+                // If there's room, decrement the count and return a completed task
+                if (_currentCount > 0)
+                {
+                    _currentCount--;
+                    return CompletedTask.Default;
+                }
+                else
+                {
+                    // Otherwise, cache a new task and return it
+                    var tcs = new TaskCompletionSource<object>();
+                    _waitingTasks.Enqueue(tcs);
+                    return tcs.Task;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Queues an action that will be executed when space is available
+        /// in the semaphore.
+        /// </summary>
+        /// <param name="action">The action to be executed.</param>
+        /// <returns>
+        /// A Task that represents the execution of the action.
+        /// </returns>
+        /// <remarks>
+        /// Release does not need to be called for this action, as it will be handled implicitly
+        /// by the Queue method.
+        /// </remarks>
+        public Task Queue(Action action)
+        {
+            return Wait().ContinueWith(_ =>
+            {
+                try { action(); }
+                finally { Release(); }
+            });
+        }
+
+        /// <summary>
+        /// Queues a function that will be executed when space is available
+        /// in the semaphore.
+        /// </summary>
+        /// <param name="function">The function to be executed.</param>
+        /// <returns>
+        /// A Task that represents the execution of the function.
+        /// </returns>
+        /// <remarks>
+        /// Release does not need to be called for this function, as it will be handled implicitly
+        /// by the Queue method.
+        /// </remarks>
+        public Task<TResult> Queue<TResult>(Func<TResult> function)
+        {
+            return Wait().ContinueWith(_ =>
+            {
+                try { return function(); }
+                finally { Release(); }
+            });
+        }
+
+        /// <summary>Releases a unit of work to the semaphore.</summary>
+        public void Release()
+        {
+            ThrowIfDisposed();
+            lock (_waitingTasks)
+            {
+                // Validate that there's room
+                if (_currentCount == _maxCount) throw new SemaphoreFullException();
+
+                // If there are any tasks waiting, allow one of them access
+                if (_waitingTasks.Count > 0)
+                {
+                    var tcs = _waitingTasks.Dequeue();
+                    tcs.SetResult(null);
+                }
+                    // Otherwise, increment the available count
+                else _currentCount++;
+            }
+        }
+
+        private void ThrowIfDisposed()
+        {
+            if (_maxCount <= 0) throw new ObjectDisposedException(GetType().Name);
+        }
+
+        /// <summary>Releases the resources used by the semaphore.</summary>
+        public void Dispose()
+        {
+            if (_maxCount > 0)
+            {
+                _maxCount = 0;
+                lock (_waitingTasks)
+                {
+                    while (_waitingTasks.Count > 0)
+                    {
+                        _waitingTasks.Dequeue().SetCanceled();
+                    }
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/ConcurrentPriorityQueue.cs b/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/ConcurrentPriorityQueue.cs
new file mode 100644 (file)
index 0000000..c333f23
--- /dev/null
@@ -0,0 +1,344 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: ConcurrentPriorityQueue.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Diagnostics;
+
+namespace System.Collections.Concurrent
+{
+    /// <summary>Provides a thread-safe priority queue data structure.</summary>
+    /// <typeparam name="TKey">Specifies the type of keys used to prioritize values.</typeparam>
+    /// <typeparam name="TValue">Specifies the type of elements in the queue.</typeparam>
+    [DebuggerDisplay("Count={Count}")]
+    public class ConcurrentPriorityQueue<TKey, TValue> :
+        IProducerConsumerCollection<KeyValuePair<TKey,TValue>> 
+        where TKey : IComparable<TKey>
+    {
+        private readonly object _syncLock = new object();
+        private readonly MinBinaryHeap _minHeap = new MinBinaryHeap();
+
+        /// <summary>Initializes a new instance of the ConcurrentPriorityQueue class.</summary>
+        public ConcurrentPriorityQueue() {}
+
+        /// <summary>Initializes a new instance of the ConcurrentPriorityQueue class that contains elements copied from the specified collection.</summary>
+        /// <param name="collection">The collection whose elements are copied to the new ConcurrentPriorityQueue.</param>
+        public ConcurrentPriorityQueue(IEnumerable<KeyValuePair<TKey, TValue>> collection)
+        {
+            if (collection == null) throw new ArgumentNullException("collection");
+            foreach (var item in collection) _minHeap.Insert(item);
+        }
+
+        /// <summary>Adds the key/value pair to the priority queue.</summary>
+        /// <param name="priority">The priority of the item to be added.</param>
+        /// <param name="value">The item to be added.</param>
+        public void Enqueue(TKey priority, TValue value)
+        {
+            Enqueue(new KeyValuePair<TKey, TValue>(priority, value));
+        }
+
+        /// <summary>Adds the key/value pair to the priority queue.</summary>
+        /// <param name="item">The key/value pair to be added to the queue.</param>
+        public void Enqueue(KeyValuePair<TKey, TValue> item)
+        {
+            lock (_syncLock) _minHeap.Insert(item);
+        }
+
+        /// <summary>Attempts to remove and return the next prioritized item in the queue.</summary>
+        /// <param name="result">
+        /// When this method returns, if the operation was successful, result contains the object removed. If
+        /// no object was available to be removed, the value is unspecified.
+        /// </param>
+        /// <returns>
+        /// true if an element was removed and returned from the queue succesfully; otherwise, false.
+        /// </returns>
+        public bool TryDequeue(out KeyValuePair<TKey, TValue> result)
+        {
+            result = default(KeyValuePair<TKey, TValue>);
+            lock (_syncLock)
+            {
+                if (_minHeap.Count > 0)
+                {
+                    result = _minHeap.Remove();
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        /// <summary>Attempts to return the next prioritized item in the queue.</summary>
+        /// <param name="result">
+        /// When this method returns, if the operation was successful, result contains the object.
+        /// The queue was not modified by the operation.
+        /// </param>
+        /// <returns>
+        /// true if an element was returned from the queue succesfully; otherwise, false.
+        /// </returns>
+        public bool TryPeek(out KeyValuePair<TKey, TValue> result)
+        {
+            result = default(KeyValuePair<TKey, TValue>);
+            lock (_syncLock)
+            {
+                if (_minHeap.Count > 0)
+                {
+                    result = _minHeap.Peek();
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        /// <summary>Empties the queue.</summary>
+        public void Clear() { lock(_syncLock) _minHeap.Clear(); }
+
+        /// <summary>Gets whether the queue is empty.</summary>
+        public bool IsEmpty { get { return Count == 0; } }
+
+        /// <summary>Gets the number of elements contained in the queue.</summary>
+        public int Count
+        {
+            get { lock (_syncLock) return _minHeap.Count; }
+        }
+
+        /// <summary>Copies the elements of the collection to an array, starting at a particular array index.</summary>
+        /// <param name="array">
+        /// The one-dimensional array that is the destination of the elements copied from the queue.
+        /// </param>
+        /// <param name="index">
+        /// The zero-based index in array at which copying begins.
+        /// </param>
+        /// <remarks>The elements will not be copied to the array in any guaranteed order.</remarks>
+        public void CopyTo(KeyValuePair<TKey, TValue>[] array, int index)
+        {
+            lock (_syncLock) _minHeap.Items.CopyTo(array, index);
+        }
+
+        /// <summary>Copies the elements stored in the queue to a new array.</summary>
+        /// <returns>A new array containing a snapshot of elements copied from the queue.</returns>
+        public KeyValuePair<TKey, TValue>[] ToArray()
+        {
+            lock (_syncLock)
+            {
+                var clonedHeap = new MinBinaryHeap(_minHeap);
+                var result = new KeyValuePair<TKey, TValue>[_minHeap.Count];
+                for (int i = 0; i < result.Length; i++)
+                {
+                    result[i] = clonedHeap.Remove();
+                }
+                return result;
+            }
+        }
+
+        /// <summary>Attempts to add an item in the queue.</summary>
+        /// <param name="item">The key/value pair to be added.</param>
+        /// <returns>
+        /// true if the pair was added; otherwise, false.
+        /// </returns>
+        bool IProducerConsumerCollection<KeyValuePair<TKey, TValue>>.TryAdd(KeyValuePair<TKey, TValue> item)
+        {
+            Enqueue(item);
+            return true;
+        }
+
+        /// <summary>Attempts to remove and return the next prioritized item in the queue.</summary>
+        /// <param name="item">
+        /// When this method returns, if the operation was successful, result contains the object removed. If
+        /// no object was available to be removed, the value is unspecified.
+        /// </param>
+        /// <returns>
+        /// true if an element was removed and returned from the queue succesfully; otherwise, false.
+        /// </returns>
+        bool IProducerConsumerCollection<KeyValuePair<TKey, TValue>>.TryTake(out KeyValuePair<TKey, TValue> item)
+        {
+            return TryDequeue(out item);
+        }
+
+        /// <summary>Returns an enumerator that iterates through the collection.</summary>
+        /// <returns>An enumerator for the contents of the queue.</returns>
+        /// <remarks>
+        /// The enumeration represents a moment-in-time snapshot of the contents of the queue. It does not
+        /// reflect any updates to the collection after GetEnumerator was called. The enumerator is safe to
+        /// use concurrently with reads from and writes to the queue.
+        /// </remarks>
+        public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
+        {
+            var arr = ToArray();
+            return ((IEnumerable<KeyValuePair<TKey, TValue>>)arr).GetEnumerator();
+        }
+
+        /// <summary>Returns an enumerator that iterates through a collection.</summary>
+        /// <returns>An IEnumerator that can be used to iterate through the collection.</returns>
+        IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
+
+        /// <summary>Copies the elements of the collection to an array, starting at a particular array index.</summary>
+        /// <param name="array">
+        /// The one-dimensional array that is the destination of the elements copied from the queue.
+        /// </param>
+        /// <param name="index">
+        /// The zero-based index in array at which copying begins.
+        /// </param>
+        void ICollection.CopyTo(Array array, int index)
+        {
+            lock (_syncLock) ((ICollection)_minHeap.Items).CopyTo(array, index);
+        }
+
+        /// <summary>
+        /// Gets a value indicating whether access to the ICollection is synchronized with the SyncRoot.
+        /// </summary>
+        bool ICollection.IsSynchronized { get { return true; } }
+
+        /// <summary>
+        /// Gets an object that can be used to synchronize access to the collection.
+        /// </summary>
+        object ICollection.SyncRoot { get { return _syncLock; } }
+
+        /// <summary>Implements a binary heap that prioritizes smaller values.</summary>
+        private sealed class MinBinaryHeap
+        {
+            private readonly List<KeyValuePair<TKey, TValue>> _items;
+
+            /// <summary>Initializes an empty heap.</summary>
+            public MinBinaryHeap()
+            {
+                _items = new List<KeyValuePair<TKey, TValue>>();
+            }
+
+            /// <summary>Initializes a heap as a copy of another heap instance.</summary>
+            /// <param name="heapToCopy">The heap to copy.</param>
+            /// <remarks>Key/Value values are not deep cloned.</remarks>
+            public MinBinaryHeap(MinBinaryHeap heapToCopy)
+            {
+                _items = new List<KeyValuePair<TKey, TValue>>(heapToCopy.Items);
+            }
+
+            /// <summary>Empties the heap.</summary>
+            public void Clear() { _items.Clear(); }
+
+            /// <summary>Adds an item to the heap.</summary>
+            public void Insert(TKey key, TValue value)
+            {
+                // Create the entry based on the provided key and value
+                Insert(new KeyValuePair<TKey, TValue>(key, value));
+            }
+
+            /// <summary>Adds an item to the heap.</summary>
+            public void Insert(KeyValuePair<TKey,TValue> entry)
+            {
+                // Add the item to the list, making sure to keep track of where it was added.
+                _items.Add(entry);
+                int pos = _items.Count - 1;
+
+                // If the new item is the only item, we're done.
+                if (pos == 0) return;
+
+                // Otherwise, perform log(n) operations, walking up the tree, swapping
+                // where necessary based on key values
+                while (pos > 0)
+                {
+                    // Get the next position to check
+                    int nextPos = pos / 2;
+
+                    // Extract the entry at the next position
+                    var toCheck = _items[nextPos];
+
+                    // Compare that entry to our new one.  If our entry has a smaller key, move it up.
+                    // Otherwise, we're done.
+                    if (entry.Key.CompareTo(toCheck.Key) < 0)
+                    {
+                        _items[pos] = toCheck;
+                        pos = nextPos;
+                    }
+                    else break;
+                }
+
+                // Make sure we put this entry back in, just in case
+                _items[pos] = entry;
+            }
+
+            /// <summary>Returns the entry at the top of the heap.</summary>
+            public KeyValuePair<TKey, TValue> Peek()
+            {
+                // Returns the first item
+                if (_items.Count == 0) throw new InvalidOperationException("The heap is empty.");
+                return _items[0];
+            }
+
+            /// <summary>Removes the entry at the top of the heap.</summary>
+            public KeyValuePair<TKey, TValue> Remove()
+            {
+                // Get the first item and save it for later (this is what will be returned).
+                if (_items.Count == 0) throw new InvalidOperationException("The heap is empty.");
+                KeyValuePair<TKey, TValue> toReturn = _items[0];
+
+                // Remove the first item if there will only be 0 or 1 items left after doing so.  
+                if (_items.Count <= 2) _items.RemoveAt(0);
+                // A reheapify will be required for the removal
+                else
+                {
+                    // Remove the first item and move the last item to the front.
+                    _items[0] = _items[_items.Count - 1];
+                    _items.RemoveAt(_items.Count - 1);
+
+                    // Start reheapify
+                    int current = 0, possibleSwap = 0;
+
+                    // Keep going until the tree is a heap
+                    while (true)
+                    {
+                        // Get the positions of the node's children
+                        int leftChildPos = 2 * current + 1;
+                        int rightChildPos = leftChildPos + 1;
+
+                        // Should we swap with the left child?
+                        if (leftChildPos < _items.Count)
+                        {
+                            // Get the two entries to compare (node and its left child)
+                            var entry1 = _items[current];
+                            var entry2 = _items[leftChildPos];
+
+                            // If the child has a lower key than the parent, set that as a possible swap
+                            if (entry2.Key.CompareTo(entry1.Key) < 0) possibleSwap = leftChildPos;
+                        }
+                        else break; // if can't swap this, we're done
+
+                        // Should we swap with the right child?  Note that now we check with the possible swap
+                        // position (which might be current and might be left child).
+                        if (rightChildPos < _items.Count)
+                        {
+                            // Get the two entries to compare (node and its left child)
+                            var entry1 = _items[possibleSwap];
+                            var entry2 = _items[rightChildPos];
+
+                            // If the child has a lower key than the parent, set that as a possible swap
+                            if (entry2.Key.CompareTo(entry1.Key) < 0) possibleSwap = rightChildPos;
+                        }
+
+                        // Now swap current and possible swap if necessary
+                        if (current != possibleSwap)
+                        {
+                            var temp = _items[current];
+                            _items[current] = _items[possibleSwap];
+                            _items[possibleSwap] = temp;
+                        }
+                        else break; // if nothing to swap, we're done
+
+                        // Update current to the location of the swap
+                        current = possibleSwap;
+                    }
+                }
+
+                // Return the item from the heap
+                return toReturn;
+            }
+
+            /// <summary>Gets the number of objects stored in the heap.</summary>
+            public int Count { get { return _items.Count; } }
+
+            internal List<KeyValuePair<TKey, TValue>> Items { get { return _items; } }
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/ObjectPool.cs b/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/ObjectPool.cs
new file mode 100644 (file)
index 0000000..a83d291
--- /dev/null
@@ -0,0 +1,71 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: ObjectPool.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Diagnostics;
+
+namespace System.Collections.Concurrent
+{
+    /// <summary>Provides a thread-safe object pool.</summary>
+    /// <typeparam name="T">Specifies the type of the elements stored in the pool.</typeparam>
+    [DebuggerDisplay("Count={Count}")]
+    [DebuggerTypeProxy(typeof(IProducerConsumerCollection_DebugView<>))]
+    public sealed class ObjectPool<T> : ProducerConsumerCollectionBase<T>
+    {
+        private readonly Func<T> _generator;
+
+        /// <summary>Initializes an instance of the ObjectPool class.</summary>
+        /// <param name="generator">The function used to create items when no items exist in the pool.</param>
+        public ObjectPool(Func<T> generator) : this(generator, new ConcurrentQueue<T>()) { }
+
+        /// <summary>Initializes an instance of the ObjectPool class.</summary>
+        /// <param name="generator">The function used to create items when no items exist in the pool.</param>
+        /// <param name="collection">The collection used to store the elements of the pool.</param>
+        public ObjectPool(Func<T> generator, IProducerConsumerCollection<T> collection)
+            : base(collection)
+        {
+            if (generator == null) throw new ArgumentNullException("generator");
+            _generator = generator;
+        }
+
+        /// <summary>Adds the provided item into the pool.</summary>
+        /// <param name="item">The item to be added.</param>
+        public void PutObject(T item) { base.TryAdd(item); }
+
+        /// <summary>Gets an item from the pool.</summary>
+        /// <returns>The removed or created item.</returns>
+        /// <remarks>If the pool is empty, a new item will be created and returned.</remarks>
+        public T GetObject()
+        {
+            T value;
+            return base.TryTake(out value) ? value : _generator();
+        }
+
+        /// <summary>Clears the object pool, returning all of the data that was in the pool.</summary>
+        /// <returns>An array containing all of the elements in the pool.</returns>
+        public T[] ToArrayAndClear()
+        {
+            var items = new List<T>();
+            T value;
+            while (base.TryTake(out value)) items.Add(value);
+            return items.ToArray();
+        }
+
+        protected override bool TryAdd(T item)
+        {
+            PutObject(item);
+            return true;
+        }
+
+        protected override bool TryTake(out T item)
+        {
+            item = GetObject();
+            return true;
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/ObservableConcurrentCollection.cs b/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/ObservableConcurrentCollection.cs
new file mode 100644 (file)
index 0000000..77424a9
--- /dev/null
@@ -0,0 +1,89 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: ObservableConcurrentCollection.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Specialized;
+using System.ComponentModel;
+using System.Threading;
+using System.Diagnostics;
+
+namespace System.Collections.Concurrent
+{
+    /// <summary>
+    /// Provides a thread-safe, concurrent collection for use with data binding.
+    /// </summary>
+    /// <typeparam name="T">Specifies the type of the elements in this collection.</typeparam>
+    [DebuggerDisplay("Count={Count}")]
+    [DebuggerTypeProxy(typeof(IProducerConsumerCollection_DebugView<>))]
+    public class ObservableConcurrentCollection<T> : 
+        ProducerConsumerCollectionBase<T>, INotifyCollectionChanged, INotifyPropertyChanged
+    {
+        private readonly SynchronizationContext _context;
+
+        /// <summary>
+        /// Initializes an instance of the ObservableConcurrentCollection class with an underlying
+        /// queue data structure.
+        /// </summary>
+        public ObservableConcurrentCollection() : this(new ConcurrentQueue<T>()) { }
+
+        /// <summary>
+        /// Initializes an instance of the ObservableConcurrentCollection class with the specified
+        /// collection as the underlying data structure.
+        /// </summary>
+        public ObservableConcurrentCollection(IProducerConsumerCollection<T> collection) : base(collection)
+        {
+            _context = AsyncOperationManager.SynchronizationContext;
+        }
+
+        /// <summary>Event raised when the collection changes.</summary>
+        public event NotifyCollectionChangedEventHandler CollectionChanged;
+        /// <summary>Event raised when a property on the collection changes.</summary>
+        public event PropertyChangedEventHandler PropertyChanged;
+
+        /// <summary>
+        /// Notifies observers of CollectionChanged or PropertyChanged of an update to the dictionary.
+        /// </summary>
+        private void NotifyObserversOfChange()
+        {
+            var collectionHandler = CollectionChanged;
+            var propertyHandler = PropertyChanged;
+            if (collectionHandler != null || propertyHandler != null)
+            {
+                _context.Post(s =>
+                {
+                    if (collectionHandler != null)
+                    {
+                        collectionHandler(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
+                    }
+                    if (propertyHandler != null)
+                    {
+                        propertyHandler(this, new PropertyChangedEventArgs("Count"));
+                    }
+                }, null);
+            }
+        }
+
+        protected override bool TryAdd(T item)
+        {
+            // Try to add the item to the underlying collection.  If we were able to,
+            // notify any listeners.
+            bool result = base.TryAdd(item);
+            if (result) NotifyObserversOfChange();
+            return result;
+        }
+
+
+        protected override bool TryTake(out T item)
+        {
+            // Try to remove an item from the underlying collection.  If we were able to,
+            // notify any listeners.
+            bool result = base.TryTake(out item);
+            if (result) NotifyObserversOfChange();
+            return result;
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/ObservableConcurrentDictionary.cs b/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/ObservableConcurrentDictionary.cs
new file mode 100644 (file)
index 0000000..916a3b2
--- /dev/null
@@ -0,0 +1,199 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: ObservableConcurrentDictionary.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.ComponentModel;
+using System.Threading;
+using System.Diagnostics;
+
+namespace System.Collections.Concurrent
+{
+    /// <summary>
+    /// Provides a thread-safe dictionary for use with data binding.
+    /// </summary>
+    /// <typeparam name="TKey">Specifies the type of the keys in this collection.</typeparam>
+    /// <typeparam name="TValue">Specifies the type of the values in this collection.</typeparam>
+    [DebuggerDisplay("Count={Count}")]
+    public class ObservableConcurrentDictionary<TKey, TValue> :
+        ICollection<KeyValuePair<TKey, TValue>>, IDictionary<TKey, TValue>,
+        INotifyCollectionChanged, INotifyPropertyChanged
+    {
+        private readonly SynchronizationContext _context;
+        private readonly ConcurrentDictionary<TKey, TValue> _dictionary;
+
+        /// <summary>
+        /// Initializes an instance of the ObservableConcurrentDictionary class.
+        /// </summary>
+        public ObservableConcurrentDictionary()
+        {
+            _context = AsyncOperationManager.SynchronizationContext;
+            _dictionary = new ConcurrentDictionary<TKey, TValue>();
+        }
+
+        /// <summary>Event raised when the collection changes.</summary>
+        public event NotifyCollectionChangedEventHandler CollectionChanged;
+        /// <summary>Event raised when a property on the collection changes.</summary>
+        public event PropertyChangedEventHandler PropertyChanged;
+
+        /// <summary>
+        /// Notifies observers of CollectionChanged or PropertyChanged of an update to the dictionary.
+        /// </summary>
+        private void NotifyObserversOfChange()
+        {
+            var collectionHandler = CollectionChanged;
+            var propertyHandler = PropertyChanged;
+            if (collectionHandler != null || propertyHandler != null)
+            {
+                _context.Post(s =>
+                {
+                    if (collectionHandler != null)
+                    {
+                        collectionHandler(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
+                    }
+                    if (propertyHandler != null)
+                    {
+                        propertyHandler(this, new PropertyChangedEventArgs("Count"));
+                        propertyHandler(this, new PropertyChangedEventArgs("Keys"));
+                        propertyHandler(this, new PropertyChangedEventArgs("Values"));
+                    }
+                }, null);
+            }
+        }
+
+        /// <summary>Attempts to add an item to the dictionary, notifying observers of any changes.</summary>
+        /// <param name="item">The item to be added.</param>
+        /// <returns>Whether the add was successful.</returns>
+        private bool TryAddWithNotification(KeyValuePair<TKey, TValue> item)
+        {
+            return TryAddWithNotification(item.Key, item.Value);
+        }
+
+        /// <summary>Attempts to add an item to the dictionary, notifying observers of any changes.</summary>
+        /// <param name="key">The key of the item to be added.</param>
+        /// <param name="value">The value of the item to be added.</param>
+        /// <returns>Whether the add was successful.</returns>
+        private bool TryAddWithNotification(TKey key, TValue value)
+        {
+            bool result = _dictionary.TryAdd(key, value);
+            if (result) NotifyObserversOfChange();
+            return result;
+        }
+
+        /// <summary>Attempts to remove an item from the dictionary, notifying observers of any changes.</summary>
+        /// <param name="key">The key of the item to be removed.</param>
+        /// <param name="value">The value of the item removed.</param>
+        /// <returns>Whether the removal was successful.</returns>
+        private bool TryRemoveWithNotification(TKey key, out TValue value)
+        {
+            bool result = _dictionary.TryRemove(key, out value);
+            if (result) NotifyObserversOfChange();
+            return result;
+        }
+
+        /// <summary>Attempts to add or update an item in the dictionary, notifying observers of any changes.</summary>
+        /// <param name="key">The key of the item to be updated.</param>
+        /// <param name="value">The new value to set for the item.</param>
+        /// <returns>Whether the update was successful.</returns>
+        private void UpdateWithNotification(TKey key, TValue value)
+        {
+            _dictionary[key] = value;
+            NotifyObserversOfChange();
+        }
+
+        #region ICollection<KeyValuePair<TKey,TValue>> Members
+        void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
+        {
+            TryAddWithNotification(item);
+        }
+
+        void ICollection<KeyValuePair<TKey, TValue>>.Clear()
+        {
+            ((ICollection<KeyValuePair<TKey, TValue>>)_dictionary).Clear();
+            NotifyObserversOfChange();
+        }
+
+        bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
+        {
+            return ((ICollection<KeyValuePair<TKey, TValue>>)_dictionary).Contains(item);
+        }
+
+        void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
+        {
+            ((ICollection<KeyValuePair<TKey, TValue>>)_dictionary).CopyTo(array, arrayIndex);
+        }
+
+        int ICollection<KeyValuePair<TKey, TValue>>.Count
+        {
+            get { return ((ICollection<KeyValuePair<TKey, TValue>>)_dictionary).Count; }
+        }
+
+        bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly
+        {
+            get { return ((ICollection<KeyValuePair<TKey, TValue>>)_dictionary).IsReadOnly; }
+        }
+
+        bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
+        {
+            TValue temp;
+            return TryRemoveWithNotification(item.Key, out temp);
+        }
+        #endregion
+
+        #region IEnumerable<KeyValuePair<TKey,TValue>> Members
+        IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator()
+        {
+            return ((ICollection<KeyValuePair<TKey, TValue>>)_dictionary).GetEnumerator();
+        }
+
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            return ((ICollection<KeyValuePair<TKey, TValue>>)_dictionary).GetEnumerator();
+        }
+        #endregion
+
+        #region IDictionary<TKey,TValue> Members
+        public void Add(TKey key, TValue value)
+        {
+            TryAddWithNotification(key, value);
+        }
+
+        public bool ContainsKey(TKey key)
+        {
+            return _dictionary.ContainsKey(key);
+        }
+
+        public ICollection<TKey> Keys
+        {
+            get { return _dictionary.Keys; }
+        }
+
+        public bool Remove(TKey key)
+        {
+            TValue temp;
+            return TryRemoveWithNotification(key, out temp);
+        }
+
+        public bool TryGetValue(TKey key, out TValue value)
+        {
+            return _dictionary.TryGetValue(key, out value);
+        }
+
+        public ICollection<TValue> Values
+        {
+            get { return _dictionary.Values; }
+        }
+
+        public TValue this[TKey key]
+        {
+            get { return _dictionary[key]; }
+            set { UpdateWithNotification(key, value); }
+        }
+        #endregion
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/Pipeline.cs b/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/Pipeline.cs
new file mode 100644 (file)
index 0000000..1352683
--- /dev/null
@@ -0,0 +1,182 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: Pipeline.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using System.Threading.Tasks.Schedulers;
+
+namespace System.Threading
+{
+    /// <summary>Provides support for pipelined data processing.</summary>
+    public static class Pipeline
+    {
+        internal readonly static TaskScheduler Scheduler = new ThreadPerTaskScheduler();
+
+        /// <summary>Creates a new pipeline, with the specified function as the sole stage.</summary>
+        /// <typeparam name="TInput">Specifies the type of the input data to the pipeline.</typeparam>
+        /// <typeparam name="TOutput">Specifies the type of the output data from this stage of the pipeline.</typeparam>
+        /// <param name="func">The function used to process input data into output data.</param>
+        /// <returns>A pipeline for converting from input data to output data.</returns>
+        public static Pipeline<TInput, TOutput> Create<TInput, TOutput>(Func<TInput, TOutput> func)
+        {
+            return Create(func, 1);
+        }
+
+        /// <summary>Creates a new pipeline, with the specified function as the sole stage.</summary>
+        /// <typeparam name="TInput">Specifies the type of the input data to the pipeline.</typeparam>
+        /// <typeparam name="TOutput">Specifies the type of the output data from this stage of the pipeline.</typeparam>
+        /// <param name="func">The function used to process input data into output data.</param>
+        /// <param name="degreeOfParallelism">The concurrency level for this stage of the pipeline.</param>
+        /// <returns>A pipeline for converting from input data to output data.</returns>
+        public static Pipeline<TInput, TOutput> Create<TInput, TOutput>(Func<TInput, TOutput> func, int degreeOfParallelism)
+        {
+            if (func == null) throw new ArgumentNullException("func");
+            if (degreeOfParallelism < 1) throw new ArgumentOutOfRangeException("degreeOfParallelism");
+            return new Pipeline<TInput, TOutput>(func, degreeOfParallelism);
+        }
+    }
+
+    /// <summary>Provides support for pipelined data processing.</summary>
+    /// <typeparam name="TInput">Specifies the type of the input data to the pipeline.</typeparam>
+    /// <typeparam name="TOutput">Specifies the type of the output data from this stage of the pipeline.</typeparam>
+    public class Pipeline<TInput, TOutput>
+    {
+        private readonly Func<TInput, TOutput> _stageFunc;
+        private readonly int _degreeOfParallelism;
+
+        internal Pipeline(int degreeOfParallelism) : this(null, degreeOfParallelism) { }
+
+        internal Pipeline(Func<TInput, TOutput> func, int degreeOfParallelism)
+        {
+            _stageFunc = func;
+            _degreeOfParallelism = degreeOfParallelism;
+        }
+
+        /// <summary>Creates a new pipeline that combines the current pipeline with a new stage.</summary>
+        /// <typeparam name="TNextOutput">Specifies the new output type of the pipeline.</typeparam>
+        /// <param name="func">
+        /// The function used to convert the output of the current pipeline into the new
+        /// output of the new pipeline.
+        /// </param>
+        /// <returns>A new pipeline that combines the current pipeline with the new stage.</returns>
+        /// <remarks>This overload creates a parallel pipeline stage.</remarks>
+        public Pipeline<TInput, TNextOutput> Next<TNextOutput>(Func<TOutput, TNextOutput> func)
+        {
+            return Next(func, 1);
+        }
+
+        /// <summary>Creates a new pipeline that combines the current pipeline with a new stage.</summary>
+        /// <typeparam name="TNextOutput">Specifies the new output type of the pipeline.</typeparam>
+        /// <param name="func">
+        /// The function used to convert the output of the current pipeline into the new
+        /// output of the new pipeline.
+        /// </param>
+        /// <param name="degreeOfParallelism">The concurrency level for this stage of the pipeline.</param>
+        /// <returns>A new pipeline that combines the current pipeline with the new stage.</returns>
+        public Pipeline<TInput, TNextOutput> Next<TNextOutput>(Func<TOutput, TNextOutput> func, int degreeOfParallelism)
+        {
+            if (func == null) throw new ArgumentNullException("func");
+            if (degreeOfParallelism < 1) throw new ArgumentOutOfRangeException("degreeOfParallelism");
+            return new InternalPipeline<TNextOutput>(this, func, degreeOfParallelism);
+        }
+
+        /// <summary>Runs the pipeline and returns an enumerable over the results.</summary>
+        /// <param name="source">The source data to be processed by the pipeline.</param>
+        /// <returns>An enumerable of the results of the pipeline.</returns>
+        public IEnumerable<TOutput> Process(IEnumerable<TInput> source)
+        {
+            return Process(source, new CancellationToken());
+        }
+
+        /// <summary>Runs the pipeline and returns an enumerable over the results.</summary>
+        /// <param name="source">The source data to be processed by the pipeline.</param>
+        /// <param name="cancellationToken">The cancellation token used to signal cancellation of the pipelining.</param>
+        /// <returns>An enumerable of the results of the pipeline.</returns>
+        public IEnumerable<TOutput> Process(IEnumerable<TInput> source, CancellationToken cancellationToken)
+        {
+            // Validate arguments
+            if (source == null) throw new ArgumentNullException("source");
+            return ProcessNoArgValidation(source, cancellationToken);
+        }
+
+        /// <summary>Runs the pipeline and returns an enumerable over the results.</summary>
+        /// <param name="source">The source data to be processed by the pipeline.</param>
+        /// <param name="cancellationToken">The cancellation token used to signal cancellation of the pipelining.</param>
+        /// <returns>An enumerable of the results of the pipeline.</returns>
+        private IEnumerable<TOutput> ProcessNoArgValidation(IEnumerable<TInput> source, CancellationToken cancellationToken)
+        {
+            // Create a blocking collection for communication with the query running in a background task
+            using (var output = new BlockingCollection<TOutput>())
+            {
+                // Start a task to run the core of the stage
+                var processingTask = Task.Factory.StartNew(() =>
+                {
+                    try { ProcessCore(source, cancellationToken, output); }
+                    finally { output.CompleteAdding(); }
+                }, CancellationToken.None, TaskCreationOptions.None, Pipeline.Scheduler);
+
+                // Enumerate and yield the results.  This makes ProcessNoArgValidation
+                // lazy, in that processing won't start until enumeration begins.
+                foreach (var result in output.GetConsumingEnumerable(cancellationToken))
+                {
+                    yield return result;
+                }
+
+                // Make sure the processing task has shut down, and propagate any exceptions that occurred
+                processingTask.Wait();
+            }
+        }
+
+        /// <summary>Implements the core processing for a pipeline stage.</summary>
+        /// <param name="source">The source data to be processed by the pipeline.</param>
+        /// <param name="cancellationToken">The cancellation token used to signal cancellation of the pipelining.</param>
+        /// <param name="output">The collection into which to put the output.</param>
+        protected virtual void ProcessCore(IEnumerable<TInput> source, CancellationToken cancellationToken, BlockingCollection<TOutput> output)
+        {
+            var options = new ParallelOptions
+            {
+                CancellationToken = cancellationToken,
+                MaxDegreeOfParallelism = _degreeOfParallelism,
+                TaskScheduler = Pipeline.Scheduler
+            };
+            Parallel.ForEach(source, options, item => output.Add(_stageFunc(item)));
+        }
+
+        /// <summary>Helper used to add a new stage to a pipeline.</summary>
+        /// <typeparam name="TNextOutput">Specifies the type of the output for the new pipeline.</typeparam>
+        private sealed class InternalPipeline<TNextOutput> : Pipeline<TInput, TNextOutput>
+        {
+            private readonly Pipeline<TInput, TOutput> _beginningPipeline;
+            private readonly Func<TOutput, TNextOutput> _lastStageFunc;
+
+            public InternalPipeline(Pipeline<TInput, TOutput> beginningPipeline, Func<TOutput, TNextOutput> func, int degreeOfParallelism)
+                : base(degreeOfParallelism)
+            {
+                _beginningPipeline = beginningPipeline;
+                _lastStageFunc = func;
+            }
+
+            /// <summary>Implements the core processing for a pipeline stage.</summary>
+            /// <param name="source">The source data to be processed by the pipeline.</param>
+            /// <param name="cancellationToken">The cancellation token used to signal cancellation of the pipelining.</param>
+            /// <param name="output">The collection into which to put the output.</param>
+            protected override void ProcessCore(
+                IEnumerable<TInput> source, CancellationToken cancellationToken, BlockingCollection<TNextOutput> output)
+            {
+                var options = new ParallelOptions
+                {
+                    CancellationToken = cancellationToken,
+                    MaxDegreeOfParallelism = _degreeOfParallelism,
+                    TaskScheduler = Pipeline.Scheduler
+                };
+                Parallel.ForEach(_beginningPipeline.Process(source, cancellationToken), options, item => output.Add(_lastStageFunc(item)));
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/ProducerConsumerCollectionBase.cs b/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/ProducerConsumerCollectionBase.cs
new file mode 100644 (file)
index 0000000..383a700
--- /dev/null
@@ -0,0 +1,111 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: ProducerConsumerCollectionBase.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Diagnostics;
+
+namespace System.Collections.Concurrent
+{
+    /// <summary>Debug view for the IProducerConsumerCollection.</summary>
+    /// <typeparam name="T">Specifies the type of the data being aggregated.</typeparam>
+    internal sealed class IProducerConsumerCollection_DebugView<T>
+    {
+        private IProducerConsumerCollection<T> _collection;
+
+        public IProducerConsumerCollection_DebugView(IProducerConsumerCollection<T> collection)
+        {
+            _collection = collection;
+        }
+
+        [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
+        public T[] Values { get { return _collection.ToArray(); } }
+    }
+
+    /// <summary>
+    /// Provides a base implementation for producer-consumer collections that wrap other
+    /// producer-consumer collections.
+    /// </summary>
+    /// <typeparam name="T">Specifies the type of elements in the collection.</typeparam>
+    [Serializable]
+    public abstract class ProducerConsumerCollectionBase<T> : IProducerConsumerCollection<T>
+    {
+        private readonly IProducerConsumerCollection<T> _contained;
+
+        /// <summary>Initializes the ProducerConsumerCollectionBase instance.</summary>
+        /// <param name="contained">The collection to be wrapped by this instance.</param>
+        protected ProducerConsumerCollectionBase(IProducerConsumerCollection<T> contained)
+        {
+            if (contained == null) throw new ArgumentNullException("contained");
+            _contained = contained;
+        }
+
+        /// <summary>Gets the contained collection.</summary>
+        protected IProducerConsumerCollection<T> ContainedCollection { get { return _contained; } }
+
+        /// <summary>Attempts to add the specified value to the end of the deque.</summary>
+        /// <param name="item">The item to add.</param>
+        /// <returns>true if the item could be added; otherwise, false.</returns>
+        protected virtual bool TryAdd(T item) { return _contained.TryAdd(item); }
+
+        /// <summary>Attempts to remove and return an item from the collection.</summary>
+        /// <param name="item">
+        /// When this method returns, if the operation was successful, item contains the item removed. If
+        /// no item was available to be removed, the value is unspecified.
+        /// </param>
+        /// <returns>
+        /// true if an element was removed and returned from the collection; otherwise, false.
+        /// </returns>
+        protected virtual bool TryTake(out T item) { return _contained.TryTake(out item); }
+
+        /// <summary>Attempts to add the specified value to the end of the deque.</summary>
+        /// <param name="item">The item to add.</param>
+        /// <returns>true if the item could be added; otherwise, false.</returns>
+        bool IProducerConsumerCollection<T>.TryAdd(T item) { return TryAdd(item); }
+
+        /// <summary>Attempts to remove and return an item from the collection.</summary>
+        /// <param name="item">
+        /// When this method returns, if the operation was successful, item contains the item removed. If
+        /// no item was available to be removed, the value is unspecified.
+        /// </param>
+        /// <returns>
+        /// true if an element was removed and returned from the collection; otherwise, false.
+        /// </returns>
+        bool IProducerConsumerCollection<T>.TryTake(out T item) { return TryTake(out item); }
+
+        /// <summary>Gets the number of elements contained in the collection.</summary>
+        public int Count { get { return _contained.Count; } }
+        
+        /// <summary>Creates an array containing the contents of the collection.</summary>
+        /// <returns>The array.</returns>
+        public T[] ToArray() { return _contained.ToArray(); }
+
+        /// <summary>Copies the contents of the collection to an array.</summary>
+        /// <param name="array">The array to which the data should be copied.</param>
+        /// <param name="index">The starting index at which data should be copied.</param>
+        public void CopyTo(T[] array, int index) { _contained.CopyTo(array, index); }
+
+        /// <summary>Copies the contents of the collection to an array.</summary>
+        /// <param name="array">The array to which the data should be copied.</param>
+        /// <param name="index">The starting index at which data should be copied.</param>
+        void ICollection.CopyTo(Array array, int index) { _contained.CopyTo(array, index); }
+
+        /// <summary>Gets an enumerator for the collection.</summary>
+        /// <returns>An enumerator.</returns>
+        public IEnumerator<T> GetEnumerator() { return _contained.GetEnumerator(); }
+
+        /// <summary>Gets an enumerator for the collection.</summary>
+        /// <returns>An enumerator.</returns>
+        IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
+
+        /// <summary>Gets whether the collection is synchronized.</summary>
+        bool ICollection.IsSynchronized { get { return _contained.IsSynchronized; } }
+
+        /// <summary>Gets the synchronization root object for the collection.</summary>
+        object ICollection.SyncRoot { get { return _contained.SyncRoot; } }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/ReductionVariable.cs b/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/ReductionVariable.cs
new file mode 100644 (file)
index 0000000..6e4f297
--- /dev/null
@@ -0,0 +1,99 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: ReductionVariable.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Runtime.CompilerServices;
+
+namespace System.Threading
+{
+    /// <summary>Provides a reduction variable for aggregating data across multiple threads involved in a computation.</summary>
+    /// <typeparam name="T">Specifies the type of the data being aggregated.</typeparam>
+    [DebuggerDisplay("Count={_values.Count}")]
+    [DebuggerTypeProxy(typeof(ReductionVariable_DebugView<>))]
+    public sealed class ReductionVariable<T>
+    {
+        /// <summary>The factory used to initialize a value on a thread.</summary>
+        private readonly Func<T> _seedFactory;
+        /// <summary>Thread-local storage for each thread's value.</summary>
+        private readonly ThreadLocal<StrongBox<T>> _threadLocal;
+        /// <summary>The list of all thread-local values for later enumeration.</summary>
+        private readonly ConcurrentQueue<StrongBox<T>> _values = new ConcurrentQueue<StrongBox<T>>();
+
+        /// <summary>Initializes the instances.</summary>
+        public ReductionVariable()
+        {
+            _threadLocal = new ThreadLocal<StrongBox<T>>(CreateValue);
+        }
+
+        /// <summary>Initializes the instances.</summary>
+        /// <param name="seedFactory">
+        /// The function invoked to provide the initial value for a thread.  
+        /// If null, the default value of T will be used as the seed.
+        /// </param>
+        public ReductionVariable(Func<T> seedFactory) : this()
+        {
+            _seedFactory = seedFactory;
+        }
+
+        /// <summary>Creates a value for the current thread and stores it in the central list of values.</summary>
+        /// <returns>The boxed value.</returns>
+        private StrongBox<T> CreateValue()
+        {
+            var s = new StrongBox<T>(_seedFactory != null ? _seedFactory() : default(T));
+            _values.Enqueue(s);
+            return s;
+        }
+
+        /// <summary>Gets or sets the value for the current thread.</summary>
+        public T Value
+        {
+            get { return _threadLocal.Value.Value; }
+            set { _threadLocal.Value.Value = value; }
+        }
+
+        /// <summary>Gets the values for all of the threads that have used this instance.</summary>
+        public IEnumerable<T> Values { get { return _values.Select(s => s.Value); } }
+
+        /// <summary>Applies an accumulator function over the values in this variable.</summary>
+        /// <param name="function">An accumulator function to be invoked on each value.</param>
+        /// <returns>The accumulated value.</returns>
+        public T Reduce(Func<T, T, T> function)
+        {
+            return Values.Aggregate(function);
+        }
+
+        /// <summary>
+        /// Applies an accumulator function over the values in this variable.
+        /// The specified seed is used as the initial accumulator value.
+        /// </summary>
+        /// <param name="function">An accumulator function to be invoked on each value.</param>
+        /// <returns>The accumulated value.</returns>
+        public TAccumulate Reduce<TAccumulate>(TAccumulate seed, Func<TAccumulate, T, TAccumulate> function)
+        {
+            return Values.Aggregate(seed, function);
+        }
+    }
+
+    /// <summary>Debug view for the reductino variable</summary>
+    /// <typeparam name="T">Specifies the type of the data being aggregated.</typeparam>
+    internal sealed class ReductionVariable_DebugView<T>
+    {
+        private ReductionVariable<T> _variable;
+
+        public ReductionVariable_DebugView(ReductionVariable<T> variable)
+        {
+            _variable = variable;
+        }
+
+        [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
+        public T[] Values { get { return _variable.Values.ToArray(); } }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/SerialTaskQueue.cs b/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/SerialTaskQueue.cs
new file mode 100644 (file)
index 0000000..27eea0f
--- /dev/null
@@ -0,0 +1,74 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: SerialTaskQueue.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Diagnostics;
+
+namespace System.Threading.Tasks
+{
+    /// <summary>Represents a queue of tasks to be started and executed serially.</summary>
+    public class SerialTaskQueue
+    {
+        /// <summary>The ordered queue of tasks to be executed. Also serves as a lock protecting all shared state.</summary>
+        private Queue<object> _tasks = new Queue<object>();
+        /// <summary>The task currently executing, or null if there is none.</summary>
+        private Task _taskInFlight;
+
+        /// <summary>Enqueues the task to be processed serially and in order.</summary>
+        /// <param name="taskGenerator">The function that generates a non-started task.</param>
+        public void Enqueue(Func<Task> taskGenerator) { EnqueueInternal(taskGenerator); }
+
+        /// <summary>Enqueues the non-started task to be processed serially and in order.</summary>
+        /// <param name="task">The task.</param>
+        public Task Enqueue(Task task) { EnqueueInternal(task); return task; }
+
+        /// <summary>Gets a Task that represents the completion of all previously queued tasks.</summary>
+        public Task Completed() { return Enqueue(new Task(() => { })); }
+
+        /// <summary>Enqueues the task to be processed serially and in order.</summary>
+        /// <param name="taskOrFunction">The task or functino that generates a task.</param>
+        /// <remarks>The task must not be started and must only be started by this instance.</remarks>
+        private void EnqueueInternal(object taskOrFunction)
+        {
+            // Validate the task
+            if (taskOrFunction == null) throw new ArgumentNullException("task");
+            lock(_tasks)
+            {
+                // If there is currently no task in flight, we'll start this one
+                if (_taskInFlight == null) StartTask_CallUnderLock(taskOrFunction);
+                    // Otherwise, just queue the task to be started later
+                else _tasks.Enqueue(taskOrFunction);
+            }
+        }
+
+        /// <summary>Called when a Task completes to potentially start the next in the queue.</summary>
+        /// <param name="ignored">The task that completed.</param>
+        private void OnTaskCompletion(Task ignored)
+        {
+            lock (_tasks)
+            {
+                // The task completed, so nothing is currently in flight.
+                // If there are any tasks in the queue, start the next one.
+                _taskInFlight = null;
+                if (_tasks.Count > 0) StartTask_CallUnderLock(_tasks.Dequeue());
+            }
+        }
+
+        /// <summary>Starts the provided task (or function that returns a task).</summary>
+        /// <param name="nextItem">The next task or function that returns a task.</param>
+        private void StartTask_CallUnderLock(object nextItem)
+        {
+            Task next = nextItem as Task;
+            if (next == null) next = ((Func<Task>)nextItem)();
+
+            if (next.Status == TaskStatus.Created) next.Start();
+            _taskInFlight = next;
+            next.ContinueWith(OnTaskCompletion);
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/SpinLockClass.cs b/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/SpinLockClass.cs
new file mode 100644 (file)
index 0000000..2693b76
--- /dev/null
@@ -0,0 +1,74 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: SpinLockClass.cs
+//
+//--------------------------------------------------------------------------
+
+namespace System.Threading
+{
+    /// <summary>Provides a simple, reference type wrapper for SpinLock.</summary>
+    public class SpinLockClass
+    {
+        private SpinLock _spinLock; // NOTE: must *not* be readonly due to SpinLock being a mutable struct
+
+        /// <summary>Initializes an instance of the SpinLockClass class.</summary>
+        public SpinLockClass()
+        {
+            _spinLock = new SpinLock();
+        }
+
+        /// <summary>Initializes an instance of the SpinLockClass class.</summary>
+        /// <param name="enableThreadOwnerTracking">
+        /// Controls whether the SpinLockClass should track
+        /// thread-ownership fo the lock.
+        /// </param>
+        public SpinLockClass(bool enableThreadOwnerTracking)
+        {
+            _spinLock = new SpinLock(enableThreadOwnerTracking);
+        }
+
+        /// <summary>Runs the specified delegate under the lock.</summary>
+        /// <param name="runUnderLock">The delegate to be executed while holding the lock.</param>
+        public void Execute(Action runUnderLock)
+        {
+            bool lockTaken = false;
+            try
+            {
+                Enter(ref lockTaken);
+                runUnderLock();
+            }
+            finally
+            {
+                if (lockTaken) Exit();
+            }
+        }
+
+        /// <summary>Enters the lock.</summary>
+        /// <param name="lockTaken">
+        /// Upon exit of the Enter method, specifies whether the lock was acquired. 
+        /// The variable passed by reference must be initialized to false.
+        /// </param>
+        public void Enter(ref bool lockTaken)
+        {
+            _spinLock.Enter(ref lockTaken);
+        }
+
+        /// <summary>Exits the SpinLock.</summary>
+        public void Exit()
+        {
+            _spinLock.Exit();
+        }
+
+        /// <summary>Exits the SpinLock.</summary>
+        /// <param name="useMemoryBarrier">
+        /// A Boolean value that indicates whether a memory fence should be issued in
+        /// order to immediately publish the exit operation to other threads.
+        /// </param>
+        public void Exit(bool useMemoryBarrier)
+        {
+            _spinLock.Exit(useMemoryBarrier);
+        }
+    }
+}
diff --git a/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/ThreadSafeRandom.cs b/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/ThreadSafeRandom.cs
new file mode 100644 (file)
index 0000000..64cbf9d
--- /dev/null
@@ -0,0 +1,77 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: ThreadSafeRandom.cs
+//
+//--------------------------------------------------------------------------
+
+using System;
+using System.Security.Cryptography;
+
+namespace System.Threading
+{
+    /// <summary>
+    /// Represents a thread-safe, pseudo-random number generator.
+    /// </summary>
+    public class ThreadSafeRandom : Random
+    {
+        /// <summary>Seed provider.</summary>
+        private static readonly RNGCryptoServiceProvider _global = new RNGCryptoServiceProvider();
+        /// <summary>The underlyin provider of randomness, one instance per thread, initialized with _global.</summary>
+        private ThreadLocal<Random> _local = new ThreadLocal<Random>(() =>
+        {
+            var buffer = new byte[4];
+            _global.GetBytes(buffer); // RNGCryptoServiceProvider is thread-safe for use in this manner
+            return new Random(BitConverter.ToInt32(buffer, 0));
+        });
+
+        /// <summary>Returns a nonnegative random number.</summary>
+        /// <returns>A 32-bit signed integer greater than or equal to zero and less than MaxValue.</returns>
+        public override int Next()
+        {
+            return _local.Value.Next();
+        }
+
+        /// <summary>Returns a nonnegative random number less than the specified maximum.</summary>
+        /// <param name="maxValue">
+        /// The exclusive upper bound of the random number to be generated. maxValue must be greater than or equal to zero. 
+        /// </param>
+        /// <returns>
+        /// A 32-bit signed integer greater than or equal to zero, and less than maxValue; 
+        /// that is, the range of return values ordinarily includes zero but not maxValue. However, 
+        /// if maxValue equals zero, maxValue is returned.
+        /// </returns>
+        public override int Next(int maxValue)
+        {
+            return _local.Value.Next(maxValue);
+        }
+
+        /// <summary>Returns a random number within a specified range.</summary>
+        /// <param name="minValue">The inclusive lower bound of the random number returned.</param>
+        /// <param name="maxValue">The exclusive upper bound of the random number returned. maxValue must be greater than or equal to minValue.</param>
+        /// <returns>
+        /// A 32-bit signed integer greater than or equal to minValue and less than maxValue; 
+        /// that is, the range of return values includes minValue but not maxValue. 
+        /// If minValue equals maxValue, minValue is returned.
+        /// </returns>
+        public override int Next(int minValue, int maxValue)
+        {
+            return _local.Value.Next(minValue, maxValue);
+        }
+
+        /// <summary>Returns a random number between 0.0 and 1.0.</summary>
+        /// <returns>A double-precision floating point number greater than or equal to 0.0, and less than 1.0.</returns>
+        public override double NextDouble()
+        {
+            return _local.Value.NextDouble();
+        }
+
+        /// <summary>Fills the elements of a specified array of bytes with random numbers.</summary>
+        /// <param name="buffer">An array of bytes to contain random numbers.</param>
+        public override void NextBytes(byte[] buffer)
+        {
+            _local.Value.NextBytes(buffer);
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/TransferStream.cs b/trunk/Libraries/ParallelExtensionsExtras/CoordinationDataStructures/TransferStream.cs
new file mode 100644 (file)
index 0000000..84cbb56
--- /dev/null
@@ -0,0 +1,74 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: TransferStream.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Concurrent;
+using System.IO;
+using System.Threading.Tasks;
+
+namespace System.Threading
+{
+    /// <summary>Writeable stream for using a separate thread in a producer/consumer scenario.</summary>
+    public sealed class TransferStream : AbstractStreamBase
+    {
+        /// <summary>The underlying stream to target.</summary>
+        private Stream _writeableStream;
+        /// <summary>The collection of chunks to be written.</summary>
+        private BlockingCollection<byte[]> _chunks;
+        /// <summary>The Task to use for background writing.</summary>
+        private Task _processingTask;
+
+        /// <summary>Initializes a new instance of the TransferStream.</summary>
+        /// <param name="writeableStream">The underlying stream to which to write.</param>
+        public TransferStream(Stream writeableStream)
+        {
+            // Validate arguments
+            if (writeableStream == null) throw new ArgumentNullException("writeableStream");
+            if (!writeableStream.CanWrite) throw new ArgumentException("Target stream is not writeable.");
+
+            // Set up the producer/consumer relationship, including starting the consumer running
+            _writeableStream = writeableStream;
+            _chunks = new BlockingCollection<byte[]>();
+            _processingTask = Task.Factory.StartNew(() =>
+            {
+                // Write out all chunks to the underlying stream
+                foreach (var chunk in _chunks.GetConsumingEnumerable())
+                    _writeableStream.Write(chunk, 0, chunk.Length);
+            }, TaskCreationOptions.LongRunning);
+        }
+
+        /// <summary>Determines whether data can be written to the stream.</summary>
+        public override bool CanWrite { get { return true; } }
+
+        /// <summary>Writes a sequence of bytes to the stream.</summary>
+        /// <param name="buffer">An array of bytes. Write copies count bytes from buffer to the stream.</param>
+        /// <param name="offset">The zero-based byte offset in buffer at which to begin copying bytes to the stream.</param>
+        /// <param name="count">The number of bytes to be written to the current stream.</param>
+        public override void Write(byte[] buffer, int offset, int count)
+        {
+            // Validate all arguments
+            if (buffer == null) throw new ArgumentNullException("buffer");
+            if (offset < 0 || offset >= buffer.Length) throw new ArgumentOutOfRangeException("offset");
+            if (count < 0 || offset + count > buffer.Length) throw new ArgumentOutOfRangeException("count");
+            if (count == 0) return;
+
+            // Store the data to the collection
+            var chunk = new byte[count];
+            Buffer.BlockCopy(buffer, offset, chunk, 0, count);
+            _chunks.Add(chunk);
+        }
+
+        /// <summary>Closes the stream and releases all resources associated with it.</summary>
+        public override void Close()
+        {
+            // Complete the collection and waits for the consumer to process all of the data
+            _chunks.CompleteAdding();
+            try { _processingTask.Wait(); }
+            finally { base.Close(); }
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Drawing/FastBitmap.cs b/trunk/Libraries/ParallelExtensionsExtras/Drawing/FastBitmap.cs
new file mode 100644 (file)
index 0000000..02037fe
--- /dev/null
@@ -0,0 +1,104 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: FastBitmap.cs
+//
+//--------------------------------------------------------------------------
+
+using System;
+using System.Drawing;
+using System.Drawing.Imaging;
+
+namespace Microsoft.Drawing
+{
+    public struct PixelData
+    {
+        public byte B;
+        public byte G;
+        public byte R;
+    }
+
+    public unsafe class FastBitmap : IDisposable
+    {
+        private Bitmap _bitmap;
+        private int _width;
+        private BitmapData _bitmapData = null;
+        private byte* _pBase = null;
+        private PixelData* _pInitPixel = null;
+        private Point _size;
+        private bool _locked = false;
+
+        public FastBitmap(Bitmap bmp)
+        {
+            if (bmp == null) throw new ArgumentNullException("bitmap");
+
+            _bitmap = bmp;
+            _size = new Point(bmp.Width, bmp.Height);
+
+            LockBitmap();
+        }
+
+        public PixelData* GetInitialPixelForRow(int rowNumber)
+        {
+            return (PixelData*)(_pBase + rowNumber * _width);
+        }
+
+        public PixelData* this[int x, int y]
+        {
+            get { return (PixelData*)(_pBase + y * _width + x * sizeof(PixelData)); }
+        }
+
+        public Color GetColor(int x, int y)
+        {
+            PixelData* data = this[x, y];
+            return Color.FromArgb(data->R, data->G, data->B);
+        }
+
+        public void SetColor(int x, int y, Color c)
+        {
+            PixelData* data = this[x, y];
+            data->R = c.R;
+            data->G = c.G;
+            data->B = c.B;
+        }
+
+        private void LockBitmap()
+        {
+            if (_locked) throw new InvalidOperationException("Already locked");
+
+            Rectangle bounds = new Rectangle(0, 0, _bitmap.Width, _bitmap.Height);
+
+            // Figure out the number of bytes in a row. This is rounded up to be a multiple 
+            // of 4 bytes, since a scan line in an image must always be a multiple of 4 bytes
+            // in length. 
+            _width = bounds.Width * sizeof(PixelData);
+            if (_width % 4 != 0) _width = 4 * (_width / 4 + 1);
+
+            _bitmapData = _bitmap.LockBits(bounds, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
+
+            _pBase = (byte*)_bitmapData.Scan0.ToPointer();
+            _locked = true;
+        }
+
+        private void InitCurrentPixel()
+        {
+            _pInitPixel = (PixelData*)_pBase;
+        }
+
+        private void UnlockBitmap()
+        {
+            if (!_locked) throw new InvalidOperationException("Not currently locked");
+
+            _bitmap.UnlockBits(_bitmapData);
+            _bitmapData = null;
+            _pBase = null;
+            _locked = false;
+        }
+
+        public void Dispose()
+        {
+            if (_locked) UnlockBitmap();
+        }
+    }
+}
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Extensions/APM/FileAsync.cs b/trunk/Libraries/ParallelExtensionsExtras/Extensions/APM/FileAsync.cs
new file mode 100644 (file)
index 0000000..5fb9513
--- /dev/null
@@ -0,0 +1,133 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: FileAsync.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Diagnostics;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace System.IO
+{
+    /// <summary>Provides asynchronous counterparts to members of the File class.</summary>
+    public static class FileAsync
+    {
+        private const int BUFFER_SIZE = 0x2000;
+
+        /// <summary>Opens an existing file for asynchronous reading.</summary>
+        /// <param name="path">The path to the file to be opened for reading.</param>
+        /// <returns>A read-only FileStream on the specified path.</returns>
+        public static FileStream OpenRead(string path)
+        {
+            // Open a file stream for reading and that supports asynchronous I/O
+            return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, BUFFER_SIZE, true);
+        }
+
+        /// <summary>Opens an existing file for asynchronous writing.</summary>
+        /// <param name="path">The path to the file to be opened for writing.</param>
+        /// <returns>An unshared FileStream on the specified path with access for writing.</returns>
+        public static FileStream OpenWrite(string path)
+        {
+            // Open a file stream for writing and that supports asynchronous I/O
+            return new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None, BUFFER_SIZE, true);
+        }
+
+        /// <summary>
+        /// Opens a binary file for asynchronosu operation, reads the contents of the file into a byte array, and then closes the file.
+        /// </summary>
+        /// <param name="path">The path to the file to be read.</param>
+        /// <returns>A task that will contain the contents of the file.</returns>
+        public static Task<byte[]> ReadAllBytes(string path)
+        {
+            // Open the file for reading
+            var fs = OpenRead(path);
+
+            // Read all of its contents
+            var asyncRead = fs.ReadAllBytesAsync();
+
+            // When we're done reading its contents, close the file and propagate the file's contents
+            var closedFile = asyncRead.ContinueWith(t =>
+            {
+                fs.Close();
+                return t.Result;
+            }, TaskContinuationOptions.ExecuteSynchronously);
+
+            // Return the task that represents the entire operation being complete and that returns the
+            // file's contents
+            return closedFile;
+        }
+
+        /// <summary>
+        /// Opens a binary file for asynchronous operation, writes the contents of the byte array into the file, and then closes the file.
+        /// </summary>
+        /// <param name="path">The path to the file to be written.</param>
+        /// <returns>A task that will signal the completion of the operation.</returns>
+        public static Task WriteAllBytes(string path, byte[] bytes)
+        {
+            // Open the file for writing
+            var fs = OpenWrite(path);
+
+            // Write the contents to the file
+            var asyncWrite = fs.WriteAsync(bytes, 0, bytes.Length);
+
+            // When complete, close the file and propagate any exceptions
+            var closedFile = asyncWrite.ContinueWith(t => 
+            {
+                var e = t.Exception;
+                fs.Close();
+                if (e != null) throw e;
+            }, TaskContinuationOptions.ExecuteSynchronously);
+
+            // Return a task that represents the operation having completed
+            return closedFile;
+        }
+
+        /// <summary>
+        /// Opens a text file for asynchronosu operation, reads the contents of the file into a string, and then closes the file.
+        /// </summary>
+        /// <param name="path">The path to the file to be read.</param>
+        /// <returns>A task that will contain the contents of the file.</returns>
+        public static Task<string> ReadAllText(string path)
+        {
+            // Create a StringBuilder to store the text from the file and an encoding object to decode the
+            // contents of the file
+            var text = new StringBuilder();
+            var encoding = new UTF8Encoding();
+
+            // Open the file for reading
+            var fs = OpenRead(path);
+
+            // Continually read buffers from the file, decoding them and storing the results into the StringBuilder
+            var asyncRead = fs.ReadBuffersAsync(BUFFER_SIZE, (buffer, count) => text.Append(encoding.GetString(buffer, 0, count)));
+
+            // When done, close the file, propagate any exceptions, and return the decoded text
+            return asyncRead.ContinueWith(t =>
+            {
+                var e = t.Exception;
+                fs.Close();
+                if (e != null) throw e;
+                return text.ToString();
+            }, TaskContinuationOptions.ExecuteSynchronously);
+        }
+
+        /// <summary>
+        /// Opens a text file for asynchronosu operation, writes a string into the file, and then closes the file.
+        /// </summary>
+        /// <param name="path">The path to the file to be written.</param>
+        /// <returns>A task that will signal the completion of the operation.</returns>
+        public static Task WriteAllText(string path, string contents)
+        {
+            // First encode the string contents into a byte array
+            var encoded = Task.Factory.StartNew(
+                state => Encoding.UTF8.GetBytes((string)state), 
+                contents);
+
+            // When encoding is done, write all of the contents to the file.  Return
+            // a task that represents the completion of that write.
+            return encoded.ContinueWith(t => WriteAllBytes(path, t.Result)).Unwrap();
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Extensions/APM/StreamExtensions.cs b/trunk/Libraries/ParallelExtensionsExtras/Extensions/APM/StreamExtensions.cs
new file mode 100644 (file)
index 0000000..b056c56
--- /dev/null
@@ -0,0 +1,196 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: StreamExtensions.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace System.IO
+{
+    /// <summary>Extension methods for asynchronously working with streams.</summary>
+    public static class StreamExtensions
+    {
+        private const int BUFFER_SIZE = 0x2000;
+
+        /// <summary>Read from a stream asynchronously.</summary>
+        /// <param name="stream">The stream.</param>
+        /// <param name="buffer">An array of bytes to be filled by the read operation.</param>
+        /// <param name="offset">The offset at which data should be stored.</param>
+        /// <param name="count">The number of bytes to be read.</param>
+        /// <returns>A Task containing the number of bytes read.</returns>
+        public static Task<int> ReadAsync(
+            this Stream stream, byte[] buffer, int offset, int count)
+        {
+            if (stream == null) throw new ArgumentNullException("stream");
+            return Task<int>.Factory.FromAsync(
+                stream.BeginRead, stream.EndRead,
+                buffer, offset, count, stream /* object state */);
+        }
+
+        /// <summary>Write to a stream asynchronously.</summary>
+        /// <param name="stream">The stream.</param>
+        /// <param name="buffer">An array of bytes to be written.</param>
+        /// <param name="offset">The offset from which data should be read to be written.</param>
+        /// <param name="count">The number of bytes to be written.</param>
+        /// <returns>A Task representing the completion of the asynchronous operation.</returns>
+        public static Task WriteAsync(
+            this Stream stream, byte[] buffer, int offset, int count)
+        {
+            if (stream == null) throw new ArgumentNullException("stream");
+            return Task.Factory.FromAsync(
+                stream.BeginWrite, stream.EndWrite,
+                buffer, offset, count, stream);
+        }
+
+        /// <summary>Reads the contents of the stream asynchronously.</summary>
+        /// <param name="stream">The stream.</param>
+        /// <returns>A Task representing the contents of the file in bytes.</returns>
+        public static Task<byte[]> ReadAllBytesAsync(this Stream stream)
+        {
+            if (stream == null) throw new ArgumentNullException("stream");
+
+            // Create a MemoryStream to store the data read from the input stream
+            int initialCapacity = stream.CanSeek ? (int)stream.Length : 0;
+            var readData = new MemoryStream(initialCapacity);
+
+            // Copy from the source stream to the memory stream and return the copied data
+            return stream.CopyStreamToStreamAsync(readData).ContinueWith(t =>
+            {
+                t.PropagateExceptions();
+                return readData.ToArray();
+            });
+        }
+
+        /// <summary>Read the content of the stream, yielding its data in buffers to the provided delegate.</summary>
+        /// <param name="stream">The stream.</param>
+        /// <param name="bufferSize">The size of the buffers to use.</param>
+        /// <param name="bufferAvailable">The delegate to be called when a new buffer is available.</param>
+        /// <returns>A Task that represents the completion of the asynchronous operation.</returns>
+        public static Task ReadBuffersAsync(this Stream stream, int bufferSize, Action<byte[], int> bufferAvailable)
+        {
+            if (stream == null) throw new ArgumentNullException("stream");
+            if (bufferSize < 1) throw new ArgumentOutOfRangeException("bufferSize");
+            if (bufferAvailable == null) throw new ArgumentNullException("bufferAvailable");
+
+            // Read from the stream over and over, handing the buffers off to the bufferAvailable delegate
+            // as they're available.  Delegate invocation will be serialized.
+            return Task.Factory.Iterate(
+                ReadIterator(stream, bufferSize, bufferAvailable));
+        }
+
+        /// <summary>
+        /// Creates an enumerable to be used with TaskFactoryExtensions.Iterate that reads data
+        /// from an input stream and passes it to a user-provided delegate.
+        /// </summary>
+        /// <param name="input">The source stream.</param>
+        /// <param name="bufferSize">The size of the buffers to be used.</param>
+        /// <param name="bufferAvailable">
+        /// A delegate to be invoked when a buffer is available (provided the
+        /// buffer and the number of bytes in the buffer starting at offset 0.
+        /// </param>
+        /// <returns>An enumerable containing yielded tasks from the operation.</returns>
+        private static IEnumerable<Task> ReadIterator(Stream input, int bufferSize, Action<byte[], int> bufferAvailable)
+        {
+            // Create a buffer that will be used over and over
+            var buffer = new byte[bufferSize];
+
+            // Until there's no more data
+            while (true)
+            {
+                // Asynchronously read a buffer and yield until the operation completes
+                var readTask = input.ReadAsync(buffer, 0, buffer.Length);
+                yield return readTask;
+
+                // If there's no more data in the stream, we're done.
+                if (readTask.Result <= 0) break;
+
+                // Otherwise, hand the data off to the delegate
+                bufferAvailable(buffer, readTask.Result);
+            }
+        }
+
+        /// <summary>Copies the contents of a stream to a file, asynchronously.</summary>
+        /// <param name="source">The source stream.</param>
+        /// <param name="destinationPath">The path to the destination file.</param>
+        /// <returns>A Task that represents the asynchronous operation.</returns>
+        public static Task CopyStreamToFileAsync(this Stream source, string destinationPath)
+        {
+            if (source == null) throw new ArgumentNullException("source");
+            if (destinationPath == null) throw new ArgumentNullException("destinationPath");
+
+            // Open the output file for writing
+            var destinationStream = FileAsync.OpenWrite(destinationPath);
+
+            // Copy the source to the destination stream, then close the output file.
+            return CopyStreamToStreamAsync(source, destinationStream).ContinueWith(t =>
+            {
+                var e = t.Exception;
+                destinationStream.Close();
+                if (e != null) throw e;
+            }, TaskContinuationOptions.ExecuteSynchronously);
+        }
+
+        /// <summary>Copies the contents of one stream to another, asynchronously.</summary>
+        /// <param name="source">The source stream.</param>
+        /// <param name="destination">The destination stream.</param>
+        /// <returns>A Task that represents the completion of the asynchronous operation.</returns>
+        public static Task CopyStreamToStreamAsync(this Stream source, Stream destination)
+        {
+            if (source == null) throw new ArgumentNullException("source");
+            if (destination == null) throw new ArgumentNullException("destination");
+            return Task.Factory.Iterate(
+                CopyStreamIterator(source, destination));
+        }
+
+        /// <summary>
+        /// Creates an enumerable to be used with TaskFactoryExtensions.Iterate that copies data from one
+        /// stream to another.
+        /// </summary>
+        /// <param name="input">The input stream.</param>
+        /// <param name="output">The output stream.</param>
+        /// <returns>An enumerable containing yielded tasks from the copy operation.</returns>
+        private static IEnumerable<Task> CopyStreamIterator(Stream input, Stream output)
+        {
+            // Create two buffers.  One will be used for the current read operation and one for the current
+            // write operation.  We'll continually swap back and forth between them.
+            byte[][] buffers = new byte[2][] { new byte[BUFFER_SIZE], new byte[BUFFER_SIZE] };
+            int filledBufferNum = 0;
+            Task writeTask = null;
+            
+            // Until there's no more data to be read
+            while (true)
+            {
+                // Read from the input asynchronously
+                var readTask = input.ReadAsync(buffers[filledBufferNum], 0, buffers[filledBufferNum].Length);
+
+                // If we have no pending write operations, just yield until the read operation has
+                // completed.  If we have both a pending read and a pending write, yield until both the read
+                // and the write have completed.
+                if (writeTask == null)
+                {
+                    yield return readTask;
+                    readTask.Wait(); // propagate any exception that may have occurred
+                }
+                else
+                {
+                    var tasks = new[] { readTask, writeTask };
+                    yield return Task.Factory.WhenAll(tasks);
+                    Task.WaitAll(tasks); // propagate any exceptions that may have occurred
+                }
+                
+                // If no data was read, nothing more to do.
+                if (readTask.Result <= 0) break;
+
+                // Otherwise, write the written data out to the file
+                writeTask = output.WriteAsync(buffers[filledBufferNum], 0, readTask.Result);
+
+                // Swap buffers
+                filledBufferNum ^= 1;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Extensions/APM/WebRequestExtensions.cs b/trunk/Libraries/ParallelExtensionsExtras/Extensions/APM/WebRequestExtensions.cs
new file mode 100644 (file)
index 0000000..c613b11
--- /dev/null
@@ -0,0 +1,49 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: WebRequestExtensions.cs
+//
+//--------------------------------------------------------------------------
+
+using System.IO;
+using System.Threading.Tasks;
+
+namespace System.Net
+{
+    /// <summary>Extension methods for working with WebRequest asynchronously.</summary>
+    public static class WebRequestExtensions
+    {
+        /// <summary>Creates a Task that represents an asynchronous request to GetResponse.</summary>
+        /// <param name="webRequest">The WebRequest.</param>
+        /// <returns>A Task containing the retrieved WebResponse.</returns>
+        public static Task<WebResponse> GetResponseAsync(this WebRequest webRequest)
+        {
+            if (webRequest == null) throw new ArgumentNullException("webRequest");
+            return Task<WebResponse>.Factory.FromAsync(
+                webRequest.BeginGetResponse, webRequest.EndGetResponse, webRequest /* object state for debugging */);
+        }
+
+        /// <summary>Creates a Task that represents an asynchronous request to GetRequestStream.</summary>
+        /// <param name="webRequest">The WebRequest.</param>
+        /// <returns>A Task containing the retrieved Stream.</returns>
+        public static Task<Stream> GetRequestStreamAsync(this WebRequest webRequest)
+        {
+            if (webRequest == null) throw new ArgumentNullException("webRequest");
+            return Task<Stream>.Factory.FromAsync(
+                webRequest.BeginGetRequestStream, webRequest.EndGetRequestStream, webRequest /* object state for debugging */);
+        }
+
+        /// <summary>Creates a Task that respresents downloading all of the data from a WebRequest.</summary>
+        /// <param name="webRequest">The WebRequest.</param>
+        /// <returns>A Task containing the downloaded content.</returns>
+        public static Task<byte[]> DownloadDataAsync(this WebRequest webRequest)
+        {
+            // Asynchronously get the response.  When that's done, asynchronously read the contents.
+            return webRequest.GetResponseAsync().ContinueWith(response =>
+            {
+                return response.Result.GetResponseStream().ReadAllBytesAsync();
+            }).Unwrap();
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Extensions/AggregateExceptionExtensions.cs b/trunk/Libraries/ParallelExtensionsExtras/Extensions/AggregateExceptionExtensions.cs
new file mode 100644 (file)
index 0000000..6429712
--- /dev/null
@@ -0,0 +1,77 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: AggregateExceptionExtensions.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Generic;
+
+namespace System
+{
+    /// <summary>Extension methods for AggregateException.</summary>
+    public static class AggregateExceptionExtensions
+    {
+        /// <summary>Invokes a handler on each Exception contained by this AggregateException.</summary>
+        /// <param name="aggregateException">The AggregateException.</param>
+        /// <param name="predicate">
+        /// The predicate to execute for each exception. The predicate accepts as an argument the Exception
+        /// to be processed and returns a Boolean to indicate whether the exception was handled.
+        /// </param>
+        /// <param name="leaveStructureIntact">
+        /// Whether the rethrown AggregateException should maintain the same hierarchy as the original.
+        /// </param>
+        public static void Handle(
+            this AggregateException aggregateException,
+            Func<Exception, bool> predicate, bool leaveStructureIntact)
+        {
+            if (aggregateException == null) throw new ArgumentNullException("aggregateException");
+            if (predicate == null) throw new ArgumentNullException("predicate");
+
+            // If leaveStructureIntact, use this implementation
+            if (leaveStructureIntact)
+            {
+                var result = HandleRecursively(aggregateException, predicate);
+                if (result != null) throw result;
+            }
+                // Otherwise, default back to the implementation on AggregateException
+            else aggregateException.Handle(predicate);
+        }
+
+        private static AggregateException HandleRecursively(
+            AggregateException aggregateException, Func<Exception, bool> predicate)
+        {   
+            // Maintain a list of exceptions to be rethrown
+            List<Exception> innerExceptions = null;
+
+            // Loop over all of the inner exceptions
+            foreach(var inner in aggregateException.InnerExceptions)
+            {
+                // If the inner exception is itself an aggregate, process recursively
+                AggregateException innerAsAggregate = inner as AggregateException;
+                if (innerAsAggregate != null)
+                {
+                    // Process recursively, and if we get back a new aggregate, store it
+                    AggregateException newChildAggregate = HandleRecursively(innerAsAggregate, predicate);
+                    if (newChildAggregate != null)
+                    {
+                        if (innerExceptions != null) innerExceptions = new List<Exception>();
+                        innerExceptions.Add(newChildAggregate);
+                    }
+                }
+                    // Otherwise, if the exception does not match the filter, store it
+                else if (!predicate(inner))
+                {
+                    if (innerExceptions != null) innerExceptions = new List<Exception>();
+                    innerExceptions.Add(inner);
+                }
+            }
+            
+            // If there are any remaining exceptions, return them in a new aggregate.
+            return innerExceptions.Count > 0 ?
+                new AggregateException(aggregateException.Message, innerExceptions) :
+                null;
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Extensions/BlockingCollectionExtensions.cs b/trunk/Libraries/ParallelExtensionsExtras/Extensions/BlockingCollectionExtensions.cs
new file mode 100644 (file)
index 0000000..460aa93
--- /dev/null
@@ -0,0 +1,210 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: BlockingCollectionExtensions.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Threading;
+using System.Linq;
+
+namespace System.Collections.Concurrent
+{
+    /// <summary>Extension methods for BlockingCollection.</summary>
+    public static class BlockingCollectionExtensions
+    {
+        /// <summary>
+        /// Gets a partitioner for a BlockingCollection that consumes and yields the contents of the BlockingCollection.</summary>
+        /// <typeparam name="T">Specifies the type of data in the collection.</typeparam>
+        /// <param name="collection">The collection for which to create a partitioner.</param>
+        /// <returns>A partitioner that completely consumes and enumerates the contents of the collection.</returns>
+        /// <remarks>
+        /// Using this partitioner with a Parallel.ForEach loop or with PLINQ eliminates the need for those
+        /// constructs to do any additional locking.  The only synchronization in place is that used by the
+        /// BlockingCollection internally.
+        /// </remarks>
+        public static Partitioner<T> GetConsumingPartitioner<T>(this BlockingCollection<T> collection)
+        {
+            return new BlockingCollectionPartitioner<T>(collection);
+        }
+
+        /// <summary>Provides a partitioner that consumes a blocking collection and yields its contents.</summary>
+        /// <typeparam name="T">Specifies the type of data in the collection.</typeparam>
+        private class BlockingCollectionPartitioner<T> : Partitioner<T>
+        {
+            /// <summary>The target collection.</summary>
+            private BlockingCollection<T> _collection;
+
+            /// <summary>Initializes the partitioner.</summary>
+            /// <param name="collection">The collection to be enumerated and consumed.</param>
+            internal BlockingCollectionPartitioner(BlockingCollection<T> collection)
+            {
+                if (collection == null) throw new ArgumentNullException("collection");
+                _collection = collection;
+            }
+
+            /// <summary>Gets whether additional partitions can be created dynamically.</summary>
+            public override bool SupportsDynamicPartitions { get { return true; } }
+
+            /// <summary>Partitions the underlying collection into the given number of partitions.</summary>
+            /// <param name="partitionCount">The number of partitions to create.</param>
+            /// <returns>A list containing partitionCount enumerators.</returns>
+            public override IList<IEnumerator<T>> GetPartitions(int partitionCount)
+            {
+                if (partitionCount < 1) throw new ArgumentOutOfRangeException("partitionCount");
+                var dynamicPartitioner = GetDynamicPartitions();
+                return Enumerable.Range(0, partitionCount).Select(_ => dynamicPartitioner.GetEnumerator()).ToArray();
+            }
+
+            /// <summary>
+            /// Creates an object that can partition the underlying collection into a variable number of partitions.
+            /// </summary>
+            /// <returns>An object that can create partitions over the underlying data source.</returns>
+            public override IEnumerable<T> GetDynamicPartitions()
+            {
+                return _collection.GetConsumingEnumerable();
+            }
+        }
+
+        /// <summary>Adds the contents of an enumerable to the BlockingCollection.</summary>
+        /// <typeparam name="T">Specifies the type of the elements in the collection.</typeparam>
+        /// <param name="target">The target BlockingCollection to be augmented.</param>
+        /// <param name="source">The source enumerable containing the data to be added.</param>
+        /// <param name="completeAddingWhenDone">
+        /// Whether to mark the target BlockingCollection as complete for adding when 
+        /// all elements of the source enumerable have been transfered.
+        /// </param>
+        public static void AddFromEnumerable<T>(this BlockingCollection<T> target, IEnumerable<T> source, bool completeAddingWhenDone)
+        {
+            try { foreach (var item in source) target.Add(item); }
+            finally { if (completeAddingWhenDone) target.CompleteAdding(); }
+        }
+
+        /// <summary>Adds the contents of an observable to the BlockingCollection.</summary>
+        /// <typeparam name="T">Specifies the type of the elements in the collection.</typeparam>
+        /// <param name="target">The target BlockingCollection to be augmented.</param>
+        /// <param name="source">The source observable containing the data to be added.</param>
+        /// <param name="completeAddingWhenDone">
+        /// Whether to mark the target BlockingCollection as complete for adding when 
+        /// all elements of the source observable have been transfered.
+        /// </param>
+        /// <returns>An IDisposable that may be used to cancel the transfer.</returns>
+        public static IDisposable AddFromObservable<T>(this BlockingCollection<T> target, IObservable<T> source, bool completeAddingWhenDone)
+        {
+            if (target == null) throw new ArgumentNullException("target");
+            if (source == null) throw new ArgumentNullException("source");
+            return source.Subscribe(new DelegateBasedObserver<T>
+            (
+                onNext: item => target.Add(item),
+                onError: error => { if (completeAddingWhenDone) target.CompleteAdding(); },
+                onCompleted: () => { if (completeAddingWhenDone) target.CompleteAdding(); }
+            ));
+        }
+
+        /// <summary>Creates an IProducerConsumerCollection-facade for a BlockingCollection instance.</summary>
+        /// <typeparam name="T">Specifies the type of the elements in the collection.</typeparam>
+        /// <param name="collection">The BlockingCollection.</param>
+        /// <returns>
+        /// An IProducerConsumerCollection that wraps the provided BlockingCollection.
+        /// </returns>
+        public static IProducerConsumerCollection<T> ToProducerConsumerCollection<T>(
+            this BlockingCollection<T> collection)
+        {
+            return ToProducerConsumerCollection(collection, Timeout.Infinite);
+        }
+
+        /// <summary>Creates an IProducerConsumerCollection-facade for a BlockingCollection instance.</summary>
+        /// <typeparam name="T">Specifies the type of the elements in the collection.</typeparam>
+        /// <param name="collection">The BlockingCollection.</param>
+        /// <param name="millisecondsTimeout">-1 for infinite blocking add and take operations. 0 for non-blocking, 1 or greater for blocking with timeout.</param>
+        /// <returns>An IProducerConsumerCollection that wraps the provided BlockingCollection.</returns>
+        public static IProducerConsumerCollection<T> ToProducerConsumerCollection<T>(
+            this BlockingCollection<T> collection, int millisecondsTimeout)
+        {
+            return new ProducerConsumerWrapper<T>(collection, millisecondsTimeout, new CancellationToken());
+        }
+
+        /// <summary>Creates an IProducerConsumerCollection-facade for a BlockingCollection instance.</summary>
+        /// <typeparam name="T">Specifies the type of the elements in the collection.</typeparam>
+        /// <param name="collection">The BlockingCollection.</param>
+        /// <param name="millisecondsTimeout">-1 for infinite blocking add and take operations. 0 for non-blocking, 1 or greater for blocking with timeout.</param>
+        /// <param name="cancellationToken">The CancellationToken to use for any blocking operations.</param>
+        /// <returns>An IProducerConsumerCollection that wraps the provided BlockingCollection.</returns>
+        public static IProducerConsumerCollection<T> ToProducerConsumerCollection<T>(
+            this BlockingCollection<T> collection, int millisecondsTimeout, CancellationToken cancellationToken)
+        {
+            return new ProducerConsumerWrapper<T>(collection, millisecondsTimeout, cancellationToken);
+        }
+
+        /// <summary>Provides a producer-consumer collection facade for a BlockingCollection.</summary>
+        /// <typeparam name="T">Specifies the type of the elements in the collection.</typeparam>
+        internal sealed class ProducerConsumerWrapper<T> : IProducerConsumerCollection<T>
+        {
+            private readonly BlockingCollection<T> _collection;
+            private readonly int _millisecondsTimeout;
+            private readonly CancellationToken _cancellationToken;
+
+            public ProducerConsumerWrapper(
+                BlockingCollection<T> collection, int millisecondsTimeout, CancellationToken cancellationToken) 
+            { 
+                if (collection == null) throw new ArgumentNullException("bc");
+                if (millisecondsTimeout < -1) throw new ArgumentOutOfRangeException("millisecondsTimeout");
+                _collection = collection;
+                _millisecondsTimeout = millisecondsTimeout;
+                _cancellationToken = cancellationToken;
+            }
+
+            public void CopyTo(T[] array, int index)
+            {
+                _collection.CopyTo(array, index);
+            }
+
+            public T[] ToArray()
+            {
+                return _collection.ToArray();
+            }
+
+            public bool TryAdd(T item)
+            {
+                return _collection.TryAdd(item, _millisecondsTimeout, _cancellationToken);
+            }
+
+            public bool TryTake(out T item)
+            {
+                return _collection.TryTake(out item, _millisecondsTimeout, _cancellationToken);
+            }
+
+            public IEnumerator<T> GetEnumerator()
+            {
+                return ((IEnumerable<T>)_collection).GetEnumerator();
+            }
+
+            IEnumerator IEnumerable.GetEnumerator()
+            {
+                return GetEnumerator();
+            }
+
+            public void CopyTo(Array array, int index)
+            {
+                ((ICollection)_collection).CopyTo(array, index);
+            }
+
+            public int Count
+            {
+                get { return _collection.Count; }
+            }
+
+            public bool IsSynchronized
+            {
+                get { return ((ICollection)_collection).IsSynchronized; }
+            }
+
+            public object SyncRoot
+            {
+                get { return ((ICollection)_collection).SyncRoot; }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Extensions/CancellationTokenExtensions.cs b/trunk/Libraries/ParallelExtensionsExtras/Extensions/CancellationTokenExtensions.cs
new file mode 100644 (file)
index 0000000..5868d7f
--- /dev/null
@@ -0,0 +1,35 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: CancellationTokenExtensions.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Concurrent.Partitioners;
+using System.Collections.Generic;
+
+namespace System.Threading
+{
+    /// <summary>Extension methods for CancellationToken.</summary>
+    public static class CancellationTokenExtensions
+    {
+        /// <summary>Cancels a CancellationTokenSource and throws a corresponding OperationCanceledException.</summary>
+        /// <param name="source">The source to be canceled.</param>
+        public static void CancelAndThrow(this CancellationTokenSource source)
+        {
+            source.Cancel();
+            source.Token.ThrowIfCancellationRequested();
+        }
+
+        /// <summary>
+        /// Creates a CancellationTokenSource that will be canceled when the specified token has cancellation requested.
+        /// </summary>
+        /// <param name="token">The token.</param>
+        /// <returns>The created CancellationTokenSource.</returns>
+        public static CancellationTokenSource CreateLinkedSource(this CancellationToken token)
+        {
+            return CancellationTokenSource.CreateLinkedTokenSource(token, new CancellationToken());
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Extensions/CompletedTask.cs b/trunk/Libraries/ParallelExtensionsExtras/Extensions/CompletedTask.cs
new file mode 100644 (file)
index 0000000..67f94fb
--- /dev/null
@@ -0,0 +1,34 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: CompletedTask.cs
+//
+//--------------------------------------------------------------------------
+
+namespace System.Threading.Tasks
+{
+    /// <summary>Provides access to an already completed task.</summary>
+    /// <remarks>A completed task can be useful for using ContinueWith overloads where there aren't StartNew equivalents.</remarks>
+    public static class CompletedTask
+    {
+        /// <summary>Gets a completed Task.</summary>
+        public readonly static Task Default = CompletedTask<object>.Default;
+    }
+
+    /// <summary>Provides access to an already completed task.</summary>
+    /// <remarks>A completed task can be useful for using ContinueWith overloads where there aren't StartNew equivalents.</remarks>
+    public static class CompletedTask<TResult>
+    {
+        /// <summary>Initializes a Task.</summary>
+        static CompletedTask()
+        {
+            var tcs = new TaskCompletionSource<TResult>();
+            tcs.TrySetResult(default(TResult));
+            Default = tcs.Task;
+        }
+
+        /// <summary>Gets a completed Task.</summary>
+        public readonly static Task<TResult> Default;
+    }
+}
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Extensions/DelegateBasedObserver.cs b/trunk/Libraries/ParallelExtensionsExtras/Extensions/DelegateBasedObserver.cs
new file mode 100644 (file)
index 0000000..d9497eb
--- /dev/null
@@ -0,0 +1,33 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: IProducerConsumerCollectionExtensions.cs
+//
+//--------------------------------------------------------------------------
+
+using System;
+
+namespace System
+{
+    internal class DelegateBasedObserver<T> : IObserver<T>
+    {
+        private Action<T> _onNext;
+        private Action<Exception> _onError;
+        private Action _onCompleted;
+
+        internal DelegateBasedObserver(Action<T> onNext, Action<Exception> onError, Action onCompleted)
+        {
+            if (onNext == null) throw new ArgumentNullException("onNext");
+            if (onError == null) throw new ArgumentNullException("onError");
+            if (onCompleted == null) throw new ArgumentNullException("onCompleted");
+            _onNext = onNext;
+            _onError = onError;
+            _onCompleted = onCompleted;
+        }
+
+        public void OnCompleted() { _onCompleted(); }
+        public void OnError(Exception error) { _onError(error); }
+        public void OnNext(T value) { _onNext(value); }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Extensions/DelegateExtensions.cs b/trunk/Libraries/ParallelExtensionsExtras/Extensions/DelegateExtensions.cs
new file mode 100644 (file)
index 0000000..05655c0
--- /dev/null
@@ -0,0 +1,68 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: DelegateExtensions.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Diagnostics;
+using System.Linq;
+
+namespace System
+{
+    /// <summary>Parallel extensions for the Delegate class.</summary>
+    public static class DelegateExtensions
+    {
+        /// <summary>Dynamically invokes (late-bound) in parallel the methods represented by the delegate.</summary>
+        /// <param name="multicastDelegate">The delegate to be invoked.</param>
+        /// <param name="args">An array of objects that are the arguments to pass to the delegates.</param>
+        /// <returns>The return value of one of the delegate invocations.</returns>
+        public static object ParallelDynamicInvoke(this Delegate multicastDelegate, params object[] args)
+        {
+            if (multicastDelegate == null) throw new ArgumentNullException("multicastDelegate");
+            if (args == null) throw new ArgumentNullException("args");
+            return multicastDelegate.GetInvocationList()
+                   .AsParallel().AsOrdered()
+                   .Select(d => d.DynamicInvoke(args))
+                   .Last();
+        }
+
+        /// <summary>
+        /// Provides a delegate that runs the specified action and fails fast if the action throws an exception.
+        /// </summary>
+        /// <param name="action">The action to invoke.</param>
+        /// <returns>The wrapper delegate.</returns>
+        public static Action WithFailFast(this Action action)
+        {
+            return () =>
+            {
+                try { action(); }
+                catch (Exception exc) 
+                {
+                    if (Debugger.IsAttached) Debugger.Break();
+                    else Environment.FailFast("An unhandled exception occurred.", exc); 
+                }
+            };
+        }
+
+        /// <summary>
+        /// Provides a delegate that runs the specified function and fails fast if the function throws an exception.
+        /// </summary>
+        /// <param name="function">The function to invoke.</param>
+        /// <returns>The wrapper delegate.</returns>
+        public static Func<T> WithFailFast<T>(this Func<T> function)
+        {
+            return () =>
+            {
+                try { return function(); }
+                catch (Exception exc) 
+                {
+                    if (Debugger.IsAttached) Debugger.Break();
+                    else Environment.FailFast("An unhandled exception occurred.", exc); 
+                }
+                throw new Exception("Will never get here");
+            };
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Extensions/EAP/EAPCommon.cs b/trunk/Libraries/ParallelExtensionsExtras/Extensions/EAP/EAPCommon.cs
new file mode 100644 (file)
index 0000000..92b9298
--- /dev/null
@@ -0,0 +1,31 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: EAPCommon.cs
+//
+//--------------------------------------------------------------------------
+
+using System.ComponentModel;
+
+namespace System.Threading.Tasks
+{
+    internal class EAPCommon
+    {
+        internal static void HandleCompletion<T>(
+            TaskCompletionSource<T> tcs, AsyncCompletedEventArgs e, Func<T> getResult, Action unregisterHandler)
+        {
+            // Transfers the results from the AsyncCompletedEventArgs and getResult() to the
+            // TaskCompletionSource, but only AsyncCompletedEventArg's UserState matches the TCS
+            // (this check is important if the same WebClient is used for multiple, asynchronous
+            // operations concurrently).  Also unregisters the handler to avoid a leak.
+            if (e.UserState == tcs)
+            {
+                if (e.Cancelled) tcs.TrySetCanceled();
+                else if (e.Error != null) tcs.TrySetException(e.Error);
+                else tcs.TrySetResult(getResult());
+                unregisterHandler();
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Extensions/EAP/PingExtensions.cs b/trunk/Libraries/ParallelExtensionsExtras/Extensions/EAP/PingExtensions.cs
new file mode 100644 (file)
index 0000000..b9378e4
--- /dev/null
@@ -0,0 +1,204 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: PingExtensions.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Threading.Tasks;
+
+namespace System.Net.NetworkInformation
+{
+    /// <summary>Extension methods for working with Ping asynchronously.</summary>
+    public static class PingExtensions
+    {
+        /// <summary>
+        /// Asynchronously attempts to send an Internet Control Message Protocol (ICMP) echo message.
+        /// </summary>
+        /// <param name="ping">The Ping.</param>
+        /// <param name="address">An IPAddress that identifies the computer that is the destination for the ICMP echo message.</param>
+        /// <param name="userToken">A user-defined object stored in the resulting Task.</param>
+        /// <returns>A task that represents the asynchronous operation.</returns>
+        public static Task<PingReply> SendTask(this Ping ping, IPAddress address, object userToken)
+        {
+            return SendTaskCore(ping, userToken, tcs => ping.SendAsync(address, tcs));
+        }
+
+        /// <summary>
+        /// Asynchronously attempts to send an Internet Control Message Protocol (ICMP) echo message.
+        /// </summary>
+        /// <param name="ping">The Ping.</param>
+        /// <param name="hostNameOrAddress">
+        /// A String that identifies the computer that is the destination for the ICMP echo message. 
+        /// The value specified for this parameter can be a host name or a string representation of an IP address.
+        /// </param>
+        /// <param name="userToken">A user-defined object stored in the resulting Task.</param>
+        /// <returns>A task that represents the asynchronous operation.</returns>
+        public static Task<PingReply> SendTask(this Ping ping, string hostNameOrAddress, object userToken)
+        {
+            return SendTaskCore(ping, userToken, tcs => ping.SendAsync(hostNameOrAddress, tcs));
+        }
+
+        /// <summary>
+        /// Asynchronously attempts to send an Internet Control Message Protocol (ICMP) echo message.
+        /// </summary>
+        /// <param name="ping">The Ping.</param>
+        /// <param name="address">An IPAddress that identifies the computer that is the destination for the ICMP echo message.</param>
+        /// <param name="timeout">
+        /// An Int32 value that specifies the maximum number of milliseconds (after sending the echo message) 
+        /// to wait for the ICMP echo reply message.
+        /// </param>
+        /// <param name="userToken">A user-defined object stored in the resulting Task.</param>
+        /// <returns>A task that represents the asynchronous operation.</returns>
+        public static Task<PingReply> SendTask(this Ping ping, IPAddress address, int timeout, object userToken)
+        {
+            return SendTaskCore(ping, userToken, tcs => ping.SendAsync(address, timeout, tcs));
+        }
+
+        /// <summary>
+        /// Asynchronously attempts to send an Internet Control Message Protocol (ICMP) echo message.
+        /// </summary>
+        /// <param name="ping">The Ping.</param>
+        /// <param name="hostNameOrAddress">
+        /// A String that identifies the computer that is the destination for the ICMP echo message. 
+        /// The value specified for this parameter can be a host name or a string representation of an IP address.
+        /// </param>
+        /// <param name="timeout">
+        /// An Int32 value that specifies the maximum number of milliseconds (after sending the echo message) 
+        /// to wait for the ICMP echo reply message.
+        /// </param>
+        /// <param name="userToken">A user-defined object stored in the resulting Task.</param>
+        /// <returns>A task that represents the asynchronous operation.</returns>
+        public static Task<PingReply> SendTask(this Ping ping, string hostNameOrAddress, int timeout, object userToken)
+        {
+            return SendTaskCore(ping, userToken, tcs => ping.SendAsync(hostNameOrAddress, timeout, tcs));
+        }
+
+        /// <summary>
+        /// Asynchronously attempts to send an Internet Control Message Protocol (ICMP) echo message.
+        /// </summary>
+        /// <param name="ping">The Ping.</param>
+        /// <param name="address">An IPAddress that identifies the computer that is the destination for the ICMP echo message.</param>
+        /// <param name="timeout">
+        /// An Int32 value that specifies the maximum number of milliseconds (after sending the echo message) 
+        /// to wait for the ICMP echo reply message.
+        /// </param>
+        /// <param name="buffer">
+        /// A Byte array that contains data to be sent with the ICMP echo message and returned 
+        /// in the ICMP echo reply message. The array cannot contain more than 65,500 bytes.
+        /// </param>
+        /// <param name="userToken">A user-defined object stored in the resulting Task.</param>
+        /// <returns>A task that represents the asynchronous operation.</returns>
+        public static Task<PingReply> SendTask(this Ping ping, IPAddress address, int timeout, byte[] buffer, object userToken)
+        {
+            return SendTaskCore(ping, userToken, tcs => ping.SendAsync(address, timeout, buffer, tcs));
+        }
+
+        /// <summary>
+        /// Asynchronously attempts to send an Internet Control Message Protocol (ICMP) echo message.
+        /// </summary>
+        /// <param name="ping">The Ping.</param>
+        /// <param name="hostNameOrAddress">
+        /// A String that identifies the computer that is the destination for the ICMP echo message. 
+        /// The value specified for this parameter can be a host name or a string representation of an IP address.
+        /// </param>
+        /// <param name="timeout">
+        /// An Int32 value that specifies the maximum number of milliseconds (after sending the echo message) 
+        /// to wait for the ICMP echo reply message.
+        /// </param>
+        /// <param name="buffer">
+        /// A Byte array that contains data to be sent with the ICMP echo message and returned 
+        /// in the ICMP echo reply message. The array cannot contain more than 65,500 bytes.
+        /// </param>
+        /// <param name="userToken">A user-defined object stored in the resulting Task.</param>
+        /// <returns>A task that represents the asynchronous operation.</returns>
+        public static Task<PingReply> SendTask(this Ping ping, string hostNameOrAddress, int timeout, byte[] buffer, object userToken)
+        {
+            return SendTaskCore(ping, userToken, tcs => ping.SendAsync(hostNameOrAddress, timeout, buffer, tcs));
+        }
+
+        /// <summary>
+        /// Asynchronously attempts to send an Internet Control Message Protocol (ICMP) echo message.
+        /// </summary>
+        /// <param name="ping">The Ping.</param>
+        /// <param name="address">An IPAddress that identifies the computer that is the destination for the ICMP echo message.</param>
+        /// <param name="timeout">
+        /// An Int32 value that specifies the maximum number of milliseconds (after sending the echo message) 
+        /// to wait for the ICMP echo reply message.
+        /// </param>
+        /// <param name="buffer">
+        /// A Byte array that contains data to be sent with the ICMP echo message and returned 
+        /// in the ICMP echo reply message. The array cannot contain more than 65,500 bytes.
+        /// </param>
+        /// <param name="options">A PingOptions object used to control fragmentation and Time-to-Live values for the ICMP echo message packet.</param>
+        /// <param name="userToken">A user-defined object stored in the resulting Task.</param>
+        /// <returns>A task that represents the asynchronous operation.</returns>
+        public static Task<PingReply> SendTask(this Ping ping, IPAddress address, int timeout, byte[] buffer, PingOptions options, object userToken)
+        {
+            return SendTaskCore(ping, userToken, tcs => ping.SendAsync(address, timeout, buffer, options, tcs));
+        }
+
+        /// <summary>
+        /// Asynchronously attempts to send an Internet Control Message Protocol (ICMP) echo message.
+        /// </summary>
+        /// <param name="ping">The Ping.</param>
+        /// <param name="hostNameOrAddress">
+        /// A String that identifies the computer that is the destination for the ICMP echo message. 
+        /// The value specified for this parameter can be a host name or a string representation of an IP address.
+        /// </param>
+        /// <param name="timeout">
+        /// An Int32 value that specifies the maximum number of milliseconds (after sending the echo message) 
+        /// to wait for the ICMP echo reply message.
+        /// </param>
+        /// <param name="buffer">
+        /// A Byte array that contains data to be sent with the ICMP echo message and returned 
+        /// in the ICMP echo reply message. The array cannot contain more than 65,500 bytes.
+        /// </param>
+        /// <param name="options">A PingOptions object used to control fragmentation and Time-to-Live values for the ICMP echo message packet.</param>
+        /// <param name="userToken">A user-defined object stored in the resulting Task.</param>
+        /// <returns>A task that represents the asynchronous operation.</returns>
+        public static Task<PingReply> SendTask(this Ping ping, string hostNameOrAddress, int timeout, byte[] buffer, PingOptions options, object userToken)
+        {
+            return SendTaskCore(ping, userToken, tcs => ping.SendAsync(hostNameOrAddress, timeout, buffer, options, tcs));
+        }
+
+        /// <summary>The core implementation of SendTask.</summary>
+        /// <param name="ping">The Ping.</param>
+        /// <param name="userToken">A user-defined object stored in the resulting Task.</param>
+        /// <param name="sendAsync">
+        /// A delegate that initiates the asynchronous send.
+        /// The provided TaskCompletionSource must be passed as the user-supplied state to the actual Ping.SendAsync method.
+        /// </param>
+        /// <returns></returns>
+        private static Task<PingReply> SendTaskCore(Ping ping, object userToken, Action<TaskCompletionSource<PingReply>> sendAsync)
+        {
+            // Validate we're being used with a real smtpClient.  The rest of the arg validation
+            // will happen in the call to sendAsync.
+            if (ping == null) throw new ArgumentNullException("ping");
+
+            // Create a TaskCompletionSource to represent the operation
+            var tcs = new TaskCompletionSource<PingReply>(userToken);
+
+            // Register a handler that will transfer completion results to the TCS Task
+            PingCompletedEventHandler handler = null;
+            handler = (sender, e) => EAPCommon.HandleCompletion(tcs, e, () => e.Reply, () => ping.PingCompleted -= handler);
+            ping.PingCompleted += handler;
+
+            // Try to start the async operation.  If starting it fails (due to parameter validation)
+            // unregister the handler before allowing the exception to propagate.
+            try
+            {
+                sendAsync(tcs);
+            }
+            catch(Exception exc)
+            {
+                ping.PingCompleted -= handler;
+                tcs.TrySetException(exc);
+            }
+
+            // Return the task to represent the asynchronous operation
+            return tcs.Task;
+        }
+    }
+}
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Extensions/EAP/SmtpClientExtensions.cs b/trunk/Libraries/ParallelExtensionsExtras/Extensions/EAP/SmtpClientExtensions.cs
new file mode 100644 (file)
index 0000000..cba4b4a
--- /dev/null
@@ -0,0 +1,79 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: SmtpClientExtensions.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Net.Mail;
+using System.Threading.Tasks;
+
+namespace System.Net.NetworkInformation
+{
+    /// <summary>Extension methods for working with SmtpClient asynchronously.</summary>
+    public static class SmtpClientExtensions
+    {
+        /// <summary>Sends an e-mail message asynchronously.</summary>
+        /// <param name="smtpClient">The client.</param>
+        /// <param name="message">A MailMessage that contains the message to send.</param>
+        /// <param name="userToken">A user-defined object stored in the resulting Task.</param>
+        /// <returns>A Task that represents the asynchronous send.</returns>
+        public static Task SendTask(this SmtpClient smtpClient, MailMessage message, object userToken)
+        {
+            return SendTaskCore(smtpClient, userToken, tcs => smtpClient.SendAsync(message, tcs));
+        }
+
+        /// <summary>Sends an e-mail message asynchronously.</summary>
+        /// <param name="smtpClient">The client.</param>
+        /// <param name="message">A MailMessage that contains the message to send.</param>
+        /// <param name="from">A String that contains the address information of the message sender.</param>
+        /// <param name="recipients">A String that contains the address that the message is sent to.</param>
+        /// <param name="subject">A String that contains the subject line for the message.</param>
+        /// <param name="body">A String that contains the message body.</param>
+        /// <param name="userToken">A user-defined object stored in the resulting Task.</param>
+        /// <returns>A Task that represents the asynchronous send.</returns>
+        public static Task SendTask(this SmtpClient smtpClient, string from, string recipients, string subject, string body, object userToken)
+        {
+            return SendTaskCore(smtpClient, userToken, tcs => smtpClient.SendAsync(from, recipients, subject, body, tcs));
+        }
+
+        /// <summary>The core implementation of SendTask.</summary>
+        /// <param name="smtpClient">The client.</param>
+        /// <param name="userToken">The user-supplied state.</param>
+        /// <param name="sendAsync">
+        /// A delegate that initiates the asynchronous send.
+        /// The provided TaskCompletionSource must be passed as the user-supplied state to the actual SmtpClient.SendAsync method.
+        /// </param>
+        /// <returns></returns>
+        private static Task SendTaskCore(SmtpClient smtpClient, object userToken, Action<TaskCompletionSource<object>> sendAsync)
+        {
+            // Validate we're being used with a real smtpClient.  The rest of the arg validation
+            // will happen in the call to sendAsync.
+            if (smtpClient == null) throw new ArgumentNullException("smtpClient");
+
+            // Create a TaskCompletionSource to represent the operation
+             var tcs = new TaskCompletionSource<object>(userToken);
+
+            // Register a handler that will transfer completion results to the TCS Task
+            SendCompletedEventHandler handler = null;
+            handler = (sender, e) => EAPCommon.HandleCompletion(tcs, e, () => null, () => smtpClient.SendCompleted -= handler);
+            smtpClient.SendCompleted += handler;
+
+            // Try to start the async operation.  If starting it fails (due to parameter validation)
+            // unregister the handler before allowing the exception to propagate.
+            try
+            {
+                sendAsync(tcs);
+            }
+            catch(Exception exc)
+            {
+                smtpClient.SendCompleted -= handler;
+                tcs.TrySetException(exc);
+            }
+
+            // Return the task to represent the asynchronous operation
+            return tcs.Task;
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Extensions/EAP/WebClientExtensions.cs b/trunk/Libraries/ParallelExtensionsExtras/Extensions/EAP/WebClientExtensions.cs
new file mode 100644 (file)
index 0000000..faa39d0
--- /dev/null
@@ -0,0 +1,354 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: WebClientExtensions.cs
+//
+//--------------------------------------------------------------------------
+
+using System.ComponentModel;
+using System.IO;
+using System.Threading.Tasks;
+
+namespace System.Net
+{
+    /// <summary>Extension methods for working with WebClient asynchronously.</summary>
+    public static class WebClientExtensions
+    {
+        /// <summary>Downloads the resource with the specified URI as a byte array, asynchronously.</summary>
+        /// <param name="webClient">The WebClient.</param>
+        /// <param name="address">The URI from which to download data.</param>
+        /// <returns>A Task that contains the downloaded data.</returns>
+        public static Task<byte[]> DownloadDataTask(this WebClient webClient, string address)
+        {
+            return DownloadDataTask(webClient, new Uri(address));
+        }
+
+        /// <summary>Downloads the resource with the specified URI as a byte array, asynchronously.</summary>
+        /// <param name="webClient">The WebClient.</param>
+        /// <param name="address">The URI from which to download data.</param>
+        /// <returns>A Task that contains the downloaded data.</returns>
+        public static Task<byte[]> DownloadDataTask(this WebClient webClient, Uri address)
+        {
+            // Create the task to be returned
+            var tcs = new TaskCompletionSource<byte[]>(address);
+
+            // Setup the callback event handler
+            DownloadDataCompletedEventHandler handler = null;
+            handler = (sender, e) => EAPCommon.HandleCompletion(tcs, e, () => e.Result, () => webClient.DownloadDataCompleted -= handler);
+            webClient.DownloadDataCompleted += handler;
+
+            // Start the async work
+            try
+            {
+                webClient.DownloadDataAsync(address, tcs);
+            }
+            catch(Exception exc)
+            {
+                // If something goes wrong kicking off the async work,
+                // unregister the callback and cancel the created task
+                webClient.DownloadDataCompleted -= handler;
+                tcs.TrySetException(exc);
+            }
+
+            // Return the task that represents the async operation
+            return tcs.Task;
+        }
+
+        /// <summary>Downloads the resource with the specified URI to a local file, asynchronously.</summary>
+        /// <param name="webClient">The WebClient.</param>
+        /// <param name="address">The URI from which to download data.</param>
+        /// <param name="fileName">The name of the local file that is to receive the data.</param>
+        /// <returns>A Task that contains the downloaded data.</returns>
+        public static Task DownloadFileTask(this WebClient webClient, string address, string fileName)
+        {
+            return DownloadFileTask(webClient, new Uri(address), fileName);
+        }
+
+        /// <summary>Downloads the resource with the specified URI to a local file, asynchronously.</summary>
+        /// <param name="webClient">The WebClient.</param>
+        /// <param name="address">The URI from which to download data.</param>
+        /// <param name="fileName">The name of the local file that is to receive the data.</param>
+        /// <returns>A Task that contains the downloaded data.</returns>
+        public static Task DownloadFileTask(this WebClient webClient, Uri address, string fileName)
+        {
+            // Create the task to be returned
+            var tcs = new TaskCompletionSource<object>(address);
+            
+            // Setup the callback event handler
+            AsyncCompletedEventHandler handler = null;
+            handler = (sender, e) => EAPCommon.HandleCompletion(tcs, e, () => null, () => webClient.DownloadFileCompleted -= handler);
+            webClient.DownloadFileCompleted += handler;
+
+            // Start the async work
+            try
+            {
+                webClient.DownloadFileAsync(address, fileName, tcs);
+            }
+            catch(Exception exc)
+            {
+                // If something goes wrong kicking off the async work,
+                // unregister the callback and cancel the created task
+                webClient.DownloadFileCompleted -= handler;
+                tcs.TrySetException(exc);
+            }
+
+            // Return the task that represents the async operation
+            return tcs.Task;
+        }
+
+        /// <summary>Downloads the resource with the specified URI as a string, asynchronously.</summary>
+        /// <param name="webClient">The WebClient.</param>
+        /// <param name="address">The URI from which to download data.</param>
+        /// <returns>A Task that contains the downloaded string.</returns>
+        public static Task<string> DownloadStringTask(this WebClient webClient, string address)
+        {
+            return DownloadStringTask(webClient, new Uri(address));
+        }
+
+        /// <summary>Downloads the resource with the specified URI as a string, asynchronously.</summary>
+        /// <param name="webClient">The WebClient.</param>
+        /// <param name="address">The URI from which to download data.</param>
+        /// <returns>A Task that contains the downloaded string.</returns>
+        public static Task<string> DownloadStringTask(this WebClient webClient, Uri address)
+        {
+            // Create the task to be returned
+            var tcs = new TaskCompletionSource<string>(address);
+
+            // Setup the callback event handler
+            DownloadStringCompletedEventHandler handler = null;
+            handler = (sender, e) => EAPCommon.HandleCompletion(tcs, e, () => e.Result, () => webClient.DownloadStringCompleted -= handler);
+            webClient.DownloadStringCompleted += handler;
+
+            // Start the async work
+            try
+            {
+                webClient.DownloadStringAsync(address, tcs);
+            }
+            catch(Exception exc)
+            {
+                // If something goes wrong kicking off the async work,
+                // unregister the callback and cancel the created task
+                webClient.DownloadStringCompleted -= handler;
+                tcs.TrySetException(exc);
+            }
+
+            // Return the task that represents the async operation
+            return tcs.Task;
+        }
+
+        /// <summary>Opens a readable stream for the data downloaded from a resource, asynchronously.</summary>
+        /// <param name="webClient">The WebClient.</param>
+        /// <param name="address">The URI for which the stream should be opened.</param>
+        /// <returns>A Task that contains the opened stream.</returns>
+        public static Task<Stream> OpenReadTask(this WebClient webClient, string address)
+        {
+            return OpenReadTask(webClient, new Uri(address));
+        }
+
+        /// <summary>Opens a readable stream for the data downloaded from a resource, asynchronously.</summary>
+        /// <param name="webClient">The WebClient.</param>
+        /// <param name="address">The URI for which the stream should be opened.</param>
+        /// <returns>A Task that contains the opened stream.</returns>
+        public static Task<Stream> OpenReadTask(this WebClient webClient, Uri address)
+        {
+            // Create the task to be returned
+            var tcs = new TaskCompletionSource<Stream>(address);
+
+            // Setup the callback event handler
+            OpenReadCompletedEventHandler handler = null;
+            handler = (sender, e) => EAPCommon.HandleCompletion(tcs, e, () => e.Result, () => webClient.OpenReadCompleted -= handler);
+            webClient.OpenReadCompleted += handler;
+
+            // Start the async work
+            try
+            {
+                webClient.OpenReadAsync(address, tcs);
+            }
+            catch(Exception exc)
+            {
+                // If something goes wrong kicking off the async work,
+                // unregister the callback and cancel the created task
+                webClient.OpenReadCompleted -= handler;
+                tcs.TrySetException(exc);
+            }
+
+            // Return the task that represents the async operation
+            return tcs.Task;
+        }
+
+        /// <summary>Opens a writeable stream for uploading data to a resource, asynchronously.</summary>
+        /// <param name="webClient">The WebClient.</param>
+        /// <param name="address">The URI for which the stream should be opened.</param>
+        /// <param name="method">The HTTP method that should be used to open the stream.</param>
+        /// <returns>A Task that contains the opened stream.</returns>
+        public static Task<Stream> OpenWriteTask(this WebClient webClient, string address, string method)
+        {
+            return OpenWriteTask(webClient, new Uri(address), method);
+        }
+
+        /// <summary>Opens a writeable stream for uploading data to a resource, asynchronously.</summary>
+        /// <param name="webClient">The WebClient.</param>
+        /// <param name="address">The URI for which the stream should be opened.</param>
+        /// <param name="method">The HTTP method that should be used to open the stream.</param>
+        /// <returns>A Task that contains the opened stream.</returns>
+        public static Task<Stream> OpenWriteTask(this WebClient webClient, Uri address, string method)
+        {
+            // Create the task to be returned
+            var tcs = new TaskCompletionSource<Stream>(address);
+
+            // Setup the callback event handler
+            OpenWriteCompletedEventHandler handler = null;
+            handler = (sender, e) => EAPCommon.HandleCompletion(tcs, e, () => e.Result, () => webClient.OpenWriteCompleted -= handler);
+            webClient.OpenWriteCompleted += handler;
+
+            // Start the async work
+            try
+            {
+                webClient.OpenWriteAsync(address, method, tcs);
+            }
+            catch(Exception exc)
+            {
+                // If something goes wrong kicking off the async work,
+                // unregister the callback and cancel the created task
+                webClient.OpenWriteCompleted -= handler;
+                tcs.TrySetException(exc);
+            }
+            
+            // Return the task that represents the async operation
+            return tcs.Task;
+        }
+
+        /// <summary>Uploads data to the specified resource, asynchronously.</summary>
+        /// <param name="webClient">The WebClient.</param>
+        /// <param name="address">The URI to which the data should be uploaded.</param>
+        /// <param name="method">The HTTP method that should be used to upload the data.</param>
+        /// <param name="data">The data to upload.</param>
+        /// <returns>A Task containing the data in the response from the upload.</returns>
+        public static Task<byte[]> UploadDataTask(this WebClient webClient, string address, string method, byte[] data)
+        {
+            return UploadDataTask(webClient, new Uri(address), method, data);
+        }
+
+        /// <summary>Uploads data to the specified resource, asynchronously.</summary>
+        /// <param name="webClient">The WebClient.</param>
+        /// <param name="address">The URI to which the data should be uploaded.</param>
+        /// <param name="method">The HTTP method that should be used to upload the data.</param>
+        /// <param name="data">The data to upload.</param>
+        /// <returns>A Task containing the data in the response from the upload.</returns>
+        public static Task<byte[]> UploadDataTask(this WebClient webClient, Uri address, string method, byte [] data)
+        {
+            // Create the task to be returned
+            var tcs = new TaskCompletionSource<byte[]>(address);
+
+            // Setup the callback event handler
+            UploadDataCompletedEventHandler handler = null;
+            handler = (sender, e) => EAPCommon.HandleCompletion(tcs, e, () => e.Result, () => webClient.UploadDataCompleted -= handler);
+            webClient.UploadDataCompleted += handler;
+
+            // Start the async work
+            try
+            {
+                webClient.UploadDataAsync(address, method, data, tcs);
+            }
+            catch(Exception exc)
+            {
+                // If something goes wrong kicking off the async work,
+                // unregister the callback and cancel the created task
+                webClient.UploadDataCompleted -= handler;
+                tcs.TrySetException(exc);
+            }
+
+            // Return the task that represents the async operation
+            return tcs.Task;
+        }
+
+        /// <summary>Uploads a file to the specified resource, asynchronously.</summary>
+        /// <param name="webClient">The WebClient.</param>
+        /// <param name="address">The URI to which the file should be uploaded.</param>
+        /// <param name="method">The HTTP method that should be used to upload the file.</param>
+        /// <param name="fileName">A path to the file to upload.</param>
+        /// <returns>A Task containing the data in the response from the upload.</returns>
+        public static Task<byte[]> UploadFileTask(this WebClient webClient, string address, string method, string fileName)
+        {
+            return UploadFileTask(webClient, new Uri(address), method, fileName);
+        }
+
+        /// <summary>Uploads a file to the specified resource, asynchronously.</summary>
+        /// <param name="webClient">The WebClient.</param>
+        /// <param name="address">The URI to which the file should be uploaded.</param>
+        /// <param name="method">The HTTP method that should be used to upload the file.</param>
+        /// <param name="fileName">A path to the file to upload.</param>
+        /// <returns>A Task containing the data in the response from the upload.</returns>
+        public static Task<byte[]> UploadFileTask(this WebClient webClient, Uri address, string method, string fileName)
+        {
+            // Create the task to be returned
+            var tcs = new TaskCompletionSource<byte[]>(address);
+
+            // Setup the callback event handler
+            UploadFileCompletedEventHandler handler = null;
+            handler = (sender, e) => EAPCommon.HandleCompletion(tcs, e, () => e.Result, () => webClient.UploadFileCompleted -= handler);
+            webClient.UploadFileCompleted += handler;
+
+            // Start the async work
+            try
+            {
+                webClient.UploadFileAsync(address, method, fileName, tcs);
+            }
+            catch(Exception exc)
+            {
+                // If something goes wrong kicking off the async work,
+                // unregister the callback and cancel the created task
+                webClient.UploadFileCompleted -= handler;
+                tcs.TrySetException(exc);
+            }
+
+            // Return the task that represents the async operation
+            return tcs.Task;
+        }
+
+        /// <summary>Uploads data in a string to the specified resource, asynchronously.</summary>
+        /// <param name="webClient">The WebClient.</param>
+        /// <param name="address">The URI to which the data should be uploaded.</param>
+        /// <param name="method">The HTTP method that should be used to upload the data.</param>
+        /// <param name="data">The data to upload.</param>
+        /// <returns>A Task containing the data in the response from the upload.</returns>
+        public static Task<string> UploadStringTask(this WebClient webClient, string address, string method, string data)
+        {
+            return UploadStringTask(webClient, address, method, data);
+        }
+
+        /// <summary>Uploads data in a string to the specified resource, asynchronously.</summary>
+        /// <param name="webClient">The WebClient.</param>
+        /// <param name="address">The URI to which the data should be uploaded.</param>
+        /// <param name="method">The HTTP method that should be used to upload the data.</param>
+        /// <param name="data">The data to upload.</param>
+        /// <returns>A Task containing the data in the response from the upload.</returns>
+        public static Task<string> UploadStringTask(this WebClient webClient, Uri address, string method, string data)
+        {
+            // Create the task to be returned
+            var tcs = new TaskCompletionSource<string>(address);
+
+            // Setup the callback event handler
+            UploadStringCompletedEventHandler handler = null;
+            handler = (sender, e) => EAPCommon.HandleCompletion(tcs, e, () => e.Result, ()=> webClient.UploadStringCompleted -= handler);
+            webClient.UploadStringCompleted += handler;
+
+            // Start the async work
+            try
+            {
+                webClient.UploadStringAsync(address, method, data, tcs);
+            }
+            catch(Exception exc)
+            {
+                // If something goes wrong kicking off the async work,
+                // unregister the callback and cancel the created task
+                webClient.UploadStringCompleted -= handler;
+                tcs.TrySetException(exc);
+            }
+
+            // Return the task that represents the async operation
+            return tcs.Task;
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Extensions/IProducerConsumerCollectionExtensions.cs b/trunk/Libraries/ParallelExtensionsExtras/Extensions/IProducerConsumerCollectionExtensions.cs
new file mode 100644 (file)
index 0000000..132a8b6
--- /dev/null
@@ -0,0 +1,114 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: IProducerConsumerCollectionExtensions.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Generic;
+
+namespace System.Collections.Concurrent
+{
+    /// <summary>Extension methods for IProducerConsumerCollection.</summary>
+    public static class ProducerConsumerCollectionExtensions
+    {
+        /// <summary>Clears the collection by repeatedly taking elements until it's empty.</summary>
+        /// <typeparam name="T">Specifies the type of the elements in the collection.</typeparam>
+        /// <param name="collection">The collection to be cleared.</param>
+        public static void Clear<T>(this IProducerConsumerCollection<T> collection)
+        {
+            T ignored;
+            while (collection.TryTake(out ignored));
+        }
+
+        /// <summary>Creates an enumerable which will consume and return elements from the collection.</summary>
+        /// <typeparam name="T">Specifies the type of the elements in the collection.</typeparam>
+        /// <param name="collection">The collection to be consumed.</param>
+        /// <returns>An enumerable that consumes elements from the collection and returns them.</returns>
+        public static IEnumerable<T> GetConsumingEnumerable<T>(
+            this IProducerConsumerCollection<T> collection)
+        {
+            T item;
+            while (collection.TryTake(out item)) yield return item;
+        }
+
+        /// <summary>Adds the contents of an enumerable to the collection.</summary>
+        /// <typeparam name="T">Specifies the type of the elements in the collection.</typeparam>
+        /// <param name="target">The target collection to be augmented.</param>
+        /// <param name="source">The source enumerable containing the data to be added.</param>
+        public static void AddFromEnumerable<T>(this IProducerConsumerCollection<T> target, IEnumerable<T> source)
+        {
+            foreach (var item in source) target.TryAdd(item);
+        }
+
+        /// <summary>Adds the contents of an observable to the collection.</summary>
+        /// <typeparam name="T">Specifies the type of the elements in the collection.</typeparam>
+        /// <param name="target">The target collection to be augmented.</param>
+        /// <param name="source">The source observable containing the data to be added.</param>
+        /// <param name="completeAddingWhenDone">
+        /// Whether to mark the target collection as complete for adding when 
+        /// all elements of the source observable have been transfered.
+        /// </param>
+        /// <returns>An IDisposable that may be used to cancel the transfer.</returns>
+        public static IDisposable AddFromObservable<T>(this IProducerConsumerCollection<T> target, IObservable<T> source)
+        {
+            if (target == null) throw new ArgumentNullException("target");
+            if (source == null) throw new ArgumentNullException("source");
+            return source.Subscribe(new DelegateBasedObserver<T>
+            (
+                onNext: item => target.TryAdd(item),
+                onError: error => {},
+                onCompleted: () => {}
+            ));
+        }
+
+        /// <summary>Creates an add-only facade for the collection.</summary>
+        /// <typeparam name="T">Specifies the type of the elements in the collection.</typeparam>
+        /// <param name="collection">The collection to be wrapped.</param>
+        /// <returns>
+        /// An IProducerConsumerCollection that wraps the target collection and supports only add
+        /// functionality, not take.
+        /// </returns>
+        public static IProducerConsumerCollection<T> ToProducerOnlyCollection<T>(this IProducerConsumerCollection<T> collection)
+        {
+            return new ProduceOrConsumeOnlyCollection<T>(collection, true);
+        }
+
+        /// <summary>Creates a take-only facade for the collection.</summary>
+        /// <typeparam name="T">Specifies the type of the elements in the collection.</typeparam>
+        /// <param name="collection">The collection to be wrapped.</param>
+        /// <returns>
+        /// An IProducerConsumerCollection that wraps the target collection and supports only take
+        /// functionality, not add.
+        /// </returns>
+        public static IProducerConsumerCollection<T> ToConsumerOnlyCollection<T>(this IProducerConsumerCollection<T> collection)
+        {
+            return new ProduceOrConsumeOnlyCollection<T>(collection, false);
+        }
+
+        // Internal wrapper that throws NotSupportedException when mutating methods (add/take) are used from the wrong mode
+        private sealed class ProduceOrConsumeOnlyCollection<T> : ProducerConsumerCollectionBase<T>
+        {
+            private readonly bool _produceOnly; // true for produce-only, false for consume-only
+
+            public ProduceOrConsumeOnlyCollection(IProducerConsumerCollection<T> contained, bool produceOnly) :
+                base(contained)
+            {
+                _produceOnly = produceOnly;
+            }
+
+            protected override bool TryAdd(T item)
+            {
+                if (!_produceOnly) throw new NotSupportedException();
+                return base.TryAdd(item);
+            }
+
+            protected override bool TryTake(out T item)
+            {
+                if (_produceOnly) throw new NotSupportedException();
+                return base.TryTake(out item);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Extensions/LazyExtensions.cs b/trunk/Libraries/ParallelExtensionsExtras/Extensions/LazyExtensions.cs
new file mode 100644 (file)
index 0000000..754a2cc
--- /dev/null
@@ -0,0 +1,45 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: LazyExtensions.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace System
+{
+    /// <summary>Extension methods for Lazy.</summary>
+    public static class LazyExtensions
+    {
+        /// <summary>Forces value creation of a Lazy instance.</summary>
+        /// <typeparam name="T">Specifies the type of the value being lazily initialized.</typeparam>
+        /// <param name="lazy">The Lazy instance.</param>
+        /// <returns>The initialized Lazy instance.</returns>
+        public static Lazy<T> Force<T>(this Lazy<T> lazy)
+        {
+            var ignored = lazy.Value;
+            return lazy;
+        }
+
+        /// <summary>Retrieves the value of a Lazy asynchronously.</summary>
+        /// <typeparam name="T">Specifies the type of the value being lazily initialized.</typeparam>
+        /// <param name="lazy">The Lazy instance.</param>
+        /// <returns>A Task representing the Lazy's value.</returns>
+        public static Task<T> GetValueAsync<T>(this Lazy<T> lazy)
+        {
+            return Task.Factory.StartNew(() => lazy.Value);
+        }
+
+        /// <summary>Creates a Lazy that's already been initialized to a specified value.</summary>
+        /// <typeparam name="T">The type of the data to be initialized.</typeparam>
+        /// <param name="value">The value with which to initialize the Lazy instance.</param>
+        /// <returns>The initialized Lazy.</returns>
+        public static Lazy<T> Create<T>(T value)
+        {
+            return new Lazy<T>(() => value, false).Force();
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Extensions/LinqToTasks.cs b/trunk/Libraries/ParallelExtensionsExtras/Extensions/LinqToTasks.cs
new file mode 100644 (file)
index 0000000..1019bf2
--- /dev/null
@@ -0,0 +1,238 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: LinqToTasks.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace System.Linq
+{
+    /// <summary>
+    /// Provides LINQ support for Tasks by implementing the primary standard query operators.
+    /// </summary>
+    public static class LinqToTasks
+    {
+        public static Task<TResult> Select<TSource, TResult>(this Task<TSource> source, Func<TSource, TResult> selector)
+        {
+            // Validate arguments
+            if (source == null) throw new ArgumentNullException("source");
+            if (selector == null) throw new ArgumentNullException("selector");
+
+            // Use a continuation to run the selector function
+            return source.ContinueWith(t => selector(t.Result), TaskContinuationOptions.NotOnCanceled);
+        }
+
+        public static Task<TResult> SelectMany<TSource, TResult>(this Task<TSource> source, Func<TSource, Task<TResult>> selector)
+        {
+            // Validate arguments
+            if (source == null) throw new ArgumentNullException("source");
+            if (selector == null) throw new ArgumentNullException("selector");
+
+            // Use a continuation to run the selector function.
+            return source.ContinueWith(t => selector(t.Result), TaskContinuationOptions.NotOnCanceled).Unwrap();
+        }
+
+        public static Task<TResult> SelectMany<TSource, TCollection, TResult>(
+            this Task<TSource> source, 
+            Func<TSource, Task<TCollection>> collectionSelector, 
+            Func<TSource, TCollection, TResult> resultSelector)
+        {
+            // Validate arguments
+            if (source == null) throw new ArgumentNullException("source");
+            if (collectionSelector == null) throw new ArgumentNullException("collectionSelector");
+            if (resultSelector == null) throw new ArgumentNullException("resultSelector");
+
+            // When the source completes, run the collectionSelector to get the next Task,
+            // and continue off of it to run the result selector
+            return source.ContinueWith(t =>
+            {
+                return collectionSelector(t.Result).
+                    ContinueWith(c => resultSelector(t.Result, c.Result), TaskContinuationOptions.NotOnCanceled);
+            }, TaskContinuationOptions.NotOnCanceled).Unwrap();
+        }
+
+        public static Task<TSource> Where<TSource>(this Task<TSource> source, Func<TSource, bool> predicate)
+        {
+            // Validate arguments
+            if (source == null) throw new ArgumentNullException("source");
+            if (predicate == null) throw new ArgumentNullException("predicate");
+
+            // Create a continuation to run the predicate and return the source's result.
+            // If the predicate returns false, cancel the returned Task.
+            var cts = new CancellationTokenSource();
+            return source.ContinueWith(t =>
+            {
+                var result = t.Result;
+                if (!predicate(result)) cts.CancelAndThrow();
+                return result;
+            }, cts.Token, TaskContinuationOptions.NotOnCanceled, TaskScheduler.Default);
+        }
+
+        public static Task<TResult> Join<TOuter, TInner, TKey, TResult>(
+            this Task<TOuter> outer, Task<TInner> inner, 
+            Func<TOuter, TKey> outerKeySelector, 
+            Func<TInner, TKey> innerKeySelector, 
+            Func<TOuter, TInner, TResult> resultSelector)
+        {
+            // Argument validation handled by delegated method call
+            return Join(outer, inner, outerKeySelector, innerKeySelector, resultSelector, EqualityComparer<TKey>.Default);
+        }
+
+        public static Task<TResult> Join<TOuter, TInner, TKey, TResult>(
+            this Task<TOuter> outer, Task<TInner> inner, 
+            Func<TOuter, TKey> outerKeySelector, 
+            Func<TInner, TKey> innerKeySelector, 
+            Func<TOuter, TInner, TResult> resultSelector, 
+            IEqualityComparer<TKey> comparer)
+        {
+            // Validate arguments
+            if (outer == null) throw new ArgumentNullException("outer");
+            if (inner == null) throw new ArgumentNullException("inner");
+            if (outerKeySelector == null) throw new ArgumentNullException("outerKeySelector");
+            if (innerKeySelector == null) throw new ArgumentNullException("innerKeySelector");
+            if (resultSelector == null) throw new ArgumentNullException("resultSelector");
+            if (comparer == null) throw new ArgumentNullException("comparer");
+
+            // First continue off of the outer and then off of the inner.  Two separate
+            // continuations are used so that each may be canceled easily using the NotOnCanceled option.
+            return outer.ContinueWith(delegate
+            {
+                var cts = new CancellationTokenSource();
+                return inner.ContinueWith(delegate
+                {
+                    // Propagate all exceptions
+                    Task.WaitAll(outer, inner);
+
+                    // Both completed successfully, so if their keys are equal, return the result
+                    if (comparer.Equals(outerKeySelector(outer.Result), innerKeySelector(inner.Result)))
+                    {
+                        return resultSelector(outer.Result, inner.Result);
+                    }
+                    // Otherwise, cancel this task.  
+                    else
+                    {
+                        cts.CancelAndThrow();
+                        return default(TResult); // won't be reached
+                    }
+                }, cts.Token, TaskContinuationOptions.NotOnCanceled, TaskScheduler.Default);
+            }, TaskContinuationOptions.NotOnCanceled).Unwrap();
+        }
+
+        public static Task<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(
+            this Task<TOuter> outer, Task<TInner> inner, 
+            Func<TOuter, TKey> outerKeySelector, 
+            Func<TInner, TKey> innerKeySelector,
+            Func<TOuter, Task<TInner>, TResult> resultSelector)
+        {
+            // Argument validation handled by delegated method call
+            return GroupJoin(outer, inner, outerKeySelector, innerKeySelector, resultSelector, EqualityComparer<TKey>.Default);
+        }
+
+        public static Task<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(
+            this Task<TOuter> outer, Task<TInner> inner, 
+            Func<TOuter, TKey> outerKeySelector, 
+            Func<TInner, TKey> innerKeySelector,
+            Func<TOuter, Task<TInner>, TResult> resultSelector, 
+            IEqualityComparer<TKey> comparer)
+        {
+            // Validate arguments
+            if (outer == null) throw new ArgumentNullException("outer");
+            if (inner == null) throw new ArgumentNullException("inner");
+            if (outerKeySelector == null) throw new ArgumentNullException("outerKeySelector");
+            if (innerKeySelector == null) throw new ArgumentNullException("innerKeySelector");
+            if (resultSelector == null) throw new ArgumentNullException("resultSelector");
+            if (comparer == null) throw new ArgumentNullException("comparer");
+
+            // First continue off of the outer and then off of the inner.  Two separate
+            // continuations are used so that each may be canceled easily using the NotOnCanceled option.
+            return outer.ContinueWith(delegate
+            {
+                var cts = new CancellationTokenSource();
+                return inner.ContinueWith(delegate
+                {
+                    // Propagate all exceptions
+                    Task.WaitAll(outer, inner);
+
+                    // Both completed successfully, so if their keys are equal, return the result
+                    if (comparer.Equals(outerKeySelector(outer.Result), innerKeySelector(inner.Result)))
+                    {
+                        return resultSelector(outer.Result, inner);
+                    }
+                    // Otherwise, cancel this task.
+                    else
+                    {
+                        cts.CancelAndThrow();
+                        return default(TResult); // won't be reached
+                    }
+                }, cts.Token, TaskContinuationOptions.NotOnCanceled, TaskScheduler.Default);
+            }, TaskContinuationOptions.NotOnCanceled).Unwrap();
+        }
+
+        public static Task<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement>(
+            this Task<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
+        {
+            // Validate arguments
+            if (source == null) throw new ArgumentNullException("source");
+            if (keySelector == null) throw new ArgumentNullException("keySelector");
+            if (elementSelector == null) throw new ArgumentNullException("elementSelector");
+
+            // When the source completes, return a grouping of just the one element
+            return source.ContinueWith(t =>
+            {
+                var result = t.Result;
+                var key = keySelector(result);
+                var element = elementSelector(result);
+                return (IGrouping<TKey,TElement>)new OneElementGrouping<TKey,TElement> { Key = key, Element = element };
+            }, TaskContinuationOptions.NotOnCanceled);
+        }
+
+        /// <summary>Represents a grouping of one element.</summary>
+        /// <typeparam name="TKey">The type of the key for the element.</typeparam>
+        /// <typeparam name="TElement">The type of the element.</typeparam>
+        private class OneElementGrouping<TKey,TElement> : IGrouping<TKey, TElement>
+        {
+            public TKey Key { get; internal set; }
+            internal TElement Element { get; set; }
+            public IEnumerator<TElement> GetEnumerator() { yield return Element; }
+            IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
+        }
+
+        public static Task<TSource> OrderBy<TSource, TKey>(this Task<TSource> source, Func<TSource, TKey> keySelector)
+        {
+            // A single item is already in sorted order, no matter what the key selector is, so just
+            // return the original.
+            if (source == null) throw new ArgumentNullException("source");
+            return source;
+        }
+
+        public static Task<TSource> OrderByDescending<TSource, TKey>(this Task<TSource> source, Func<TSource, TKey> keySelector)
+        {
+            // A single item is already in sorted order, no matter what the key selector is, so just
+            // return the original.
+            if (source == null) throw new ArgumentNullException("source");
+            return source;
+        }
+
+        public static Task<TSource> ThenBy<TSource, TKey>(this Task<TSource> source, Func<TSource, TKey> keySelector)
+        {
+            // A single item is already in sorted order, no matter what the key selector is, so just
+            // return the original.
+            if (source == null) throw new ArgumentNullException("source");
+            return source;
+        }
+
+        public static Task<TSource> ThenByDescending<TSource, TKey>(this Task<TSource> source, Func<TSource, TKey> keySelector)
+        {
+            // A single item is already in sorted order, no matter what the key selector is, so just
+            // return the original.
+            if (source == null) throw new ArgumentNullException("source");
+            return source;
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Extensions/ParallelLinqOptions.cs b/trunk/Libraries/ParallelExtensionsExtras/Extensions/ParallelLinqOptions.cs
new file mode 100644 (file)
index 0000000..fd8c36c
--- /dev/null
@@ -0,0 +1,54 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: ParallelLinqOptions.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace System.Linq
+{
+    /// <summary>Provides a grouping for common Parallel LINQ options.</summary>
+    public sealed class ParallelLinqOptions : ParallelOptions
+    {
+        private ParallelExecutionMode _executionMode = ParallelExecutionMode.Default;
+        private ParallelMergeOptions _mergeOptions = ParallelMergeOptions.Default;
+        private bool _ordered = false;
+
+        /// <summary>Gets or sets the execution mode.</summary>
+        public ParallelExecutionMode ExecutionMode
+        {
+            get { return _executionMode; }
+            set
+            {
+                if (value != ParallelExecutionMode.Default &&
+                    value != ParallelExecutionMode.ForceParallelism) throw new ArgumentOutOfRangeException("ExecutionMode");
+                _executionMode = value;
+            }
+        }
+
+        /// <summary>Gets or sets the merge options.</summary>
+        public ParallelMergeOptions MergeOptions
+        {
+            get { return _mergeOptions; }
+            set
+            {
+                if (value != ParallelMergeOptions.AutoBuffered &&
+                    value != ParallelMergeOptions.Default &&
+                    value != ParallelMergeOptions.FullyBuffered &&
+                    value != ParallelMergeOptions.NotBuffered) throw new ArgumentOutOfRangeException("MergeOptions");
+                _mergeOptions = value;
+            }
+        }
+
+        /// <summary>Gets or sets whether the query should retain ordering.</summary>
+        public bool Ordered
+        {
+            get { return _ordered; }
+            set { _ordered = value; }
+        }
+    }
+}
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Extensions/ParallelOptionsExtensions.cs b/trunk/Libraries/ParallelExtensionsExtras/Extensions/ParallelOptionsExtensions.cs
new file mode 100644 (file)
index 0000000..c0cab6b
--- /dev/null
@@ -0,0 +1,27 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: ParallelOptionsExtensions.cs
+//
+//--------------------------------------------------------------------------
+
+namespace System.Threading.Tasks
+{
+    /// <summary>Extension methods for ParallelOptions.</summary>
+    public static class ParallelOptionsExtensions
+    {
+        /// <summary>Copies a ParallelOptions instance to a shallow clone.</summary>
+        /// <param name="options">The options to be cloned.</param>
+        /// <returns>The shallow clone.</returns>
+        public static ParallelOptions ShallowClone(this ParallelOptions options)
+        {
+            return new ParallelOptions()
+            {
+                CancellationToken = options.CancellationToken,
+                MaxDegreeOfParallelism = options.MaxDegreeOfParallelism,
+                TaskScheduler = options.TaskScheduler
+            };
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Extensions/PlinqExtensions.cs b/trunk/Libraries/ParallelExtensionsExtras/Extensions/PlinqExtensions.cs
new file mode 100644 (file)
index 0000000..82437ea
--- /dev/null
@@ -0,0 +1,164 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: PlinqExtensions.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace System.Linq
+{
+    /// <summary>Extension methods for Parallel LINQ.</summary>
+    public static class ParallelLinqExtensions
+    {
+        /// <summary>Takes the top elements as if they were sorted.</summary>
+        /// <typeparam name="TSource">Specifies the type of the elements.</typeparam>
+        /// <typeparam name="TKey">Specifies the type of the keys used to compare elements.</typeparam>
+        /// <param name="source">The source elements.</param>
+        /// <param name="keySelector">A function used to extract a key from each element.</param>
+        /// <param name="count">The number of elements to take.</param>
+        /// <returns></returns>
+        public static IEnumerable<TSource> TakeTop<TSource, TKey>(this ParallelQuery<TSource> source,
+            Func<TSource, TKey> keySelector,
+            int count)
+        {
+            // We want to sort in descending order, so we need the opposite of the default comparer
+            var comparer = new DescendingDefaultComparer<TKey>();
+
+            // Aggregate, using a sorted list per thread to keep track of the best N elements,
+            // then merge those at the end.
+            return source.Aggregate(
+                () => new SortedTopN<TKey, TSource>(count, comparer),
+
+                (accum, item) =>
+                {
+                    accum.Add(keySelector(item), item);
+                    return accum;
+                },
+
+                (accum1, accum2) =>
+                {
+                    foreach (var item in accum2) accum1.Add(item);
+                    return accum1;
+                },
+
+                (accum) => accum.Values);
+        }
+
+        /// <summary>A comparer that comparers using the inverse of the default comparer.</summary>
+        /// <typeparam name="T">Specifies the type being compared.</typeparam>
+        private class DescendingDefaultComparer<T> : IComparer<T>
+        {
+            private static Comparer<T> _defaultComparer = Comparer<T>.Default;
+            public int Compare(T x, T y) { return _defaultComparer.Compare(y, x); }
+        }
+
+        /// <summary>Implements a map-reduce operation.</summary>
+        /// <typeparam name="TSource">Specifies the type of the source elements.</typeparam>
+        /// <typeparam name="TMapped">Specifies the type of the mapped elements.</typeparam>
+        /// <typeparam name="TKey">Specifies the type of the element keys.</typeparam>
+        /// <typeparam name="TResult">Specifies the type of the results.</typeparam>
+        /// <param name="source">The source elements.</param>
+        /// <param name="map">A function used to get the target data from a source element.</param>
+        /// <param name="keySelector">A function used to get a key from the target data.</param>
+        /// <param name="reduce">A function used to reduce a group of elements.</param>
+        /// <returns>The result elements of the reductions.</returns>
+        public static ParallelQuery<TResult> MapReduce<TSource, TMapped, TKey, TResult>(
+            this ParallelQuery<TSource> source,
+            Func<TSource, TMapped> map,
+            Func<TMapped, TKey> keySelector,
+            Func<IGrouping<TKey, TMapped>, TResult> reduce)
+        {
+            return source.
+                Select(map).
+                GroupBy(keySelector).
+                Select(reduce);
+        }
+
+        /// <summary>Implements a map-reduce operation.</summary>
+        /// <typeparam name="TSource">Specifies the type of the source elements.</typeparam>
+        /// <typeparam name="TMapped">Specifies the type of the mapped elements.</typeparam>
+        /// <typeparam name="TKey">Specifies the type of the element keys.</typeparam>
+        /// <typeparam name="TResult">Specifies the type of the results.</typeparam>
+        /// <param name="source">The source elements.</param>
+        /// <param name="map">A function used to get an enumerable of target data from a source element.</param>
+        /// <param name="keySelector">A function used to get a key from target data.</param>
+        /// <param name="reduce">A function used to reduce a group of elements to an enumerable of results.</param>
+        /// <returns>The result elements of the reductions.</returns>
+        public static ParallelQuery<TResult> MapReduce<TSource, TMapped, TKey, TResult>(
+            this ParallelQuery<TSource> source,
+            Func<TSource, IEnumerable<TMapped>> map,
+            Func<TMapped, TKey> keySelector,
+            Func<IGrouping<TKey, TMapped>, IEnumerable<TResult>> reduce)
+        {
+            return source.
+                SelectMany(map).
+                GroupBy(keySelector).
+                SelectMany(reduce);
+        }
+
+        /// <summary>Runs the query and outputs its results into the target collection.</summary>
+        /// <typeparam name="TSource">Specifies the type of elements output from the query.</typeparam>
+        /// <param name="source">The source query.</param>
+        /// <param name="target">The target collection.</param>
+        public static void OutputToProducerConsumerCollection<TSource>(
+            this ParallelQuery<TSource> source,
+            IProducerConsumerCollection<TSource> target)
+        {
+            // Validate arguments
+            if (source == null) throw new ArgumentNullException("source");
+            if (target == null) throw new ArgumentNullException("target");
+
+            // Store all results into the collection
+            source.ForAll(item => target.TryAdd(item));
+        }
+
+        /// <summary>This is the method to opt into Parallel LINQ.</summary>
+        /// <typeparam name="TSource">Specifies the type of elements provided to the query.</typeparam>
+        /// <param name="source">The source query.</param>
+        /// <param name="parallelOptions">The options to use for query processing.</param>
+        /// <returns>The source as a ParallelQuery to bind to ParallelEnumerable extension methods.</returns>
+        public static ParallelQuery<TSource> AsParallel<TSource>(
+            this IEnumerable<TSource> source,
+            ParallelLinqOptions parallelOptions)
+        {
+            if (source == null) throw new ArgumentNullException("source");
+
+            // Validate unsupported options
+            if (parallelOptions.TaskScheduler != null && parallelOptions.TaskScheduler != TaskScheduler.Default)
+            {
+                throw new ArgumentException("Parallel LINQ only supports the default TaskScheduler.");
+            }
+
+            // First convert to PLINQ
+            var result = source.AsParallel();
+
+            // Then apply all of the options as requested...
+            if (parallelOptions.Ordered)
+            {
+                result = result.AsOrdered();
+            }
+            if (parallelOptions.CancellationToken.CanBeCanceled)
+            {
+                result = result.WithCancellation(parallelOptions.CancellationToken);
+            }
+            if (parallelOptions.MaxDegreeOfParallelism >= 1)
+            {
+                result = result.WithDegreeOfParallelism(parallelOptions.MaxDegreeOfParallelism);
+            }
+            if (parallelOptions.ExecutionMode != ParallelExecutionMode.Default)
+            {
+                result = result.WithExecutionMode(parallelOptions.ExecutionMode);
+            }
+            if (parallelOptions.MergeOptions != ParallelMergeOptions.Default)
+            {
+                result = result.WithMergeOptions(parallelOptions.MergeOptions);
+            }
+            return result;
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskCompletionSourceExtensions.cs b/trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskCompletionSourceExtensions.cs
new file mode 100644 (file)
index 0000000..82bc1e8
--- /dev/null
@@ -0,0 +1,64 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: TaskCompletionSourceExtensions.cs
+//
+//--------------------------------------------------------------------------
+
+namespace System.Threading.Tasks
+{
+    /// <summary>Extension methods for TaskCompletionSource.</summary>
+    public static class TaskCompletionSourceExtensions
+    {
+        /// <summary>Transfers the result of a Task to the TaskCompletionSource.</summary>
+        /// <typeparam name="TResult">Specifies the type of the result.</typeparam>
+        /// <param name="resultSetter">The TaskCompletionSource.</param>
+        /// <param name="task">The task whose completion results should be transfered.</param>
+        public static void SetFromTask<TResult>(this TaskCompletionSource<TResult> resultSetter, Task task)
+        {
+            switch (task.Status)
+            {
+                case TaskStatus.RanToCompletion: resultSetter.SetResult(task is Task<TResult> ? ((Task<TResult>)task).Result : default(TResult)); break;
+                case TaskStatus.Faulted: resultSetter.SetException(task.Exception.InnerExceptions); break;
+                case TaskStatus.Canceled: resultSetter.SetCanceled(); break;
+                default: throw new InvalidOperationException("The task was not completed.");
+            }
+        }
+
+        /// <summary>Transfers the result of a Task to the TaskCompletionSource.</summary>
+        /// <typeparam name="TResult">Specifies the type of the result.</typeparam>
+        /// <param name="resultSetter">The TaskCompletionSource.</param>
+        /// <param name="task">The task whose completion results should be transfered.</param>
+        public static void SetFromTask<TResult>(this TaskCompletionSource<TResult> resultSetter, Task<TResult> task)
+        {
+            SetFromTask(resultSetter, (Task)task);
+        }
+
+        /// <summary>Attempts to transfer the result of a Task to the TaskCompletionSource.</summary>
+        /// <typeparam name="TResult">Specifies the type of the result.</typeparam>
+        /// <param name="resultSetter">The TaskCompletionSource.</param>
+        /// <param name="task">The task whose completion results should be transfered.</param>
+        /// <returns>Whether the transfer could be completed.</returns>
+        public static bool TrySetFromTask<TResult>(this TaskCompletionSource<TResult> resultSetter, Task task)
+        {
+            switch (task.Status)
+            {
+                case TaskStatus.RanToCompletion: return resultSetter.TrySetResult(task is Task<TResult> ? ((Task<TResult>)task).Result : default(TResult));
+                case TaskStatus.Faulted: return resultSetter.TrySetException(task.Exception.InnerExceptions);
+                case TaskStatus.Canceled: return resultSetter.TrySetCanceled();
+                default: throw new InvalidOperationException("The task was not completed.");
+            }
+        }
+
+        /// <summary>Attempts to transfer the result of a Task to the TaskCompletionSource.</summary>
+        /// <typeparam name="TResult">Specifies the type of the result.</typeparam>
+        /// <param name="resultSetter">The TaskCompletionSource.</param>
+        /// <param name="task">The task whose completion results should be transfered.</param>
+        /// <returns>Whether the transfer could be completed.</returns>
+        public static bool TrySetFromTask<TResult>(this TaskCompletionSource<TResult> resultSetter, Task<TResult> task)
+        {
+            return TrySetFromTask(resultSetter, (Task)task);
+        }
+    }
+}
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskExtrasExtensions.cs b/trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskExtrasExtensions.cs
new file mode 100644 (file)
index 0000000..767e61c
--- /dev/null
@@ -0,0 +1,304 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: TaskExtensions.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Linq;
+using System.Windows.Threading;
+
+namespace System.Threading.Tasks
+{
+    /// <summary>Extensions methods for Task.</summary>
+    public static class TaskExtrasExtensions
+    {
+        #region ContinueWith accepting TaskFactory
+        /// <summary>Creates a continuation task using the specified TaskFactory.</summary>
+        /// <param name="task">The antecedent Task.</param>
+        /// <param name="continuationAction">The continuation action.</param>
+        /// <param name="factory">The TaskFactory.</param>
+        /// <returns>A continuation task.</returns>
+        public static Task ContinueWith(
+            this Task task, Action<Task> continuationAction, TaskFactory factory)
+        {
+            return task.ContinueWith(continuationAction, factory.CancellationToken, factory.ContinuationOptions, factory.Scheduler);
+        }
+
+        /// <summary>Creates a continuation task using the specified TaskFactory.</summary>
+        /// <param name="task">The antecedent Task.</param>
+        /// <param name="continuationFunction">The continuation function.</param>
+        /// <param name="factory">The TaskFactory.</param>
+        /// <returns>A continuation task.</returns>
+        public static Task<TResult> ContinueWith<TResult>(
+            this Task task, Func<Task, TResult> continuationFunction, TaskFactory factory)
+        {
+            return task.ContinueWith(continuationFunction, factory.CancellationToken, factory.ContinuationOptions, factory.Scheduler);
+        }
+        #endregion
+
+        #region ContinueWith accepting TaskFactory<TResult>
+        /// <summary>Creates a continuation task using the specified TaskFactory.</summary>
+        /// <param name="task">The antecedent Task.</param>
+        /// <param name="continuationAction">The continuation action.</param>
+        /// <param name="factory">The TaskFactory.</param>
+        /// <returns>A continuation task.</returns>
+        public static Task ContinueWith<TResult>(
+            this Task<TResult> task, Action<Task<TResult>> continuationAction, TaskFactory<TResult> factory)
+        {
+            return task.ContinueWith(continuationAction, factory.CancellationToken, factory.ContinuationOptions, factory.Scheduler);
+        }
+
+        /// <summary>Creates a continuation task using the specified TaskFactory.</summary>
+        /// <param name="task">The antecedent Task.</param>
+        /// <param name="continuationFunction">The continuation function.</param>
+        /// <param name="factory">The TaskFactory.</param>
+        /// <returns>A continuation task.</returns>
+        public static Task<TNewResult> ContinueWith<TResult, TNewResult>(
+            this Task<TResult> task, Func<Task<TResult>, TNewResult> continuationFunction, TaskFactory<TResult> factory)
+        {
+            return task.ContinueWith(continuationFunction, factory.CancellationToken, factory.ContinuationOptions, factory.Scheduler);
+        }
+        #endregion
+
+        #region ToAsync(AsyncCallback, object)
+        /// <summary>
+        /// Creates a Task that represents the completion of another Task, and 
+        /// that schedules an AsyncCallback to run upon completion.
+        /// </summary>
+        /// <param name="task">The antecedent Task.</param>
+        /// <param name="callback">The AsyncCallback to run.</param>
+        /// <param name="state">The object state to use with the AsyncCallback.</param>
+        /// <returns>The new task.</returns>
+        public static Task ToAsync(this Task task, AsyncCallback callback, object state)
+        {
+            if (task == null) throw new ArgumentNullException("task");
+
+            var tcs = new TaskCompletionSource<object>(state);
+            task.ContinueWith(_ =>
+            {
+                tcs.SetFromTask(task);
+                if (callback != null) callback(tcs.Task);
+            });
+            return tcs.Task;
+        }
+
+        /// <summary>
+        /// Creates a Task that represents the completion of another Task, and 
+        /// that schedules an AsyncCallback to run upon completion.
+        /// </summary>
+        /// <param name="task">The antecedent Task.</param>
+        /// <param name="callback">The AsyncCallback to run.</param>
+        /// <param name="state">The object state to use with the AsyncCallback.</param>
+        /// <returns>The new task.</returns>
+        public static Task<TResult> ToAsync<TResult>(this Task<TResult> task, AsyncCallback callback, object state)
+        {
+            if (task == null) throw new ArgumentNullException("task");
+
+            var tcs = new TaskCompletionSource<TResult>(state);
+            task.ContinueWith(_ =>
+            {
+                tcs.SetFromTask(task);
+                if (callback != null) callback(tcs.Task);
+            });
+            return tcs.Task;
+        }
+        #endregion
+
+        #region Exception Handling
+        /// <summary>Suppresses default exception handling of a Task that would otherwise reraise the exception on the finalizer thread.</summary>
+        /// <param name="task">The Task to be monitored.</param>
+        /// <returns>The original Task.</returns>
+        public static Task IgnoreExceptions(this Task task)
+        {
+            task.ContinueWith(t => { var ignored = t.Exception; }, 
+                CancellationToken.None,
+                TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.OnlyOnFaulted, 
+                TaskScheduler.Default);
+            return task;
+        }
+
+        /// <summary>Suppresses default exception handling of a Task that would otherwise reraise the exception on the finalizer thread.</summary>
+        /// <param name="task">The Task to be monitored.</param>
+        /// <returns>The original Task.</returns>
+        public static Task<T> IgnoreExceptions<T>(this Task<T> task)
+        {
+            return (Task<T>)((Task)task).IgnoreExceptions();
+        }
+
+        /// <summary>Fails immediately when an exception is encountered.</summary>
+        /// <param name="task">The Task to be monitored.</param>
+        /// <returns>The original Task.</returns>
+        public static Task FailFastOnException(this Task task)
+        {
+            task.ContinueWith(t => Environment.FailFast("A task faulted.", t.Exception),
+                CancellationToken.None,
+                TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.OnlyOnFaulted,
+                TaskScheduler.Default);
+            return task;
+        }
+
+        /// <summary>Fails immediately when an exception is encountered.</summary>
+        /// <param name="task">The Task to be monitored.</param>
+        /// <returns>The original Task.</returns>
+        public static Task<T> FailFastOnException<T>(this Task<T> task)
+        {
+            return (Task<T>)((Task)task).FailFastOnException();
+        }
+
+        /// <summary>Propagates any exceptions that occurred on the specified task.</summary>
+        /// <param name="task">The Task whose exceptions are to be propagated.</param>
+        public static void PropagateExceptions(this Task task)
+        {
+            if (!task.IsCompleted) throw new InvalidOperationException("The task has not completed.");
+            if (task.IsFaulted) task.Wait();
+        }
+
+        /// <summary>Propagates any exceptions that occurred on the specified tasks.</summary>
+        /// <param name="task">The Tassk whose exceptions are to be propagated.</param>
+        public static void PropagateExceptions(this Task [] tasks)
+        {
+            if (tasks == null) throw new ArgumentNullException("tasks");
+            if (tasks.Any(t => t == null)) throw new ArgumentException("tasks");
+            if (tasks.Any(t => !t.IsCompleted)) throw new InvalidOperationException("A task has not completed.");
+            Task.WaitAll(tasks);
+        }
+        #endregion
+
+        #region Observables
+        /// <summary>Creates an IObservable that represents the completion of a Task.</summary>
+        /// <typeparam name="TResult">Specifies the type of data returned by the Task.</typeparam>
+        /// <param name="task">The Task to be represented as an IObservable.</param>
+        /// <returns>An IObservable that represents the completion of the Task.</returns>
+        public static IObservable<TResult> ToObservable<TResult>(this Task<TResult> task)
+        {
+            if (task == null) throw new ArgumentNullException("task");
+            return new TaskObservable<TResult> { _task = task };
+        }
+
+        /// <summary>An implementation of IObservable that wraps a Task.</summary>
+        /// <typeparam name="TResult">The type of data returned by the task.</typeparam>
+        private class TaskObservable<TResult> : IObservable<TResult>
+        {
+            internal Task<TResult> _task;
+
+            public IDisposable Subscribe(IObserver<TResult> observer)
+            {
+                // Validate arguments
+                if (observer == null) throw new ArgumentNullException("observer");
+
+                // Support cancelling the continuation if the observer is unsubscribed
+                var cts = new CancellationTokenSource();
+
+                // Create a continuation to pass data along to the observer
+                _task.ContinueWith(t =>
+                {
+                    switch (t.Status)
+                    {
+                        case TaskStatus.RanToCompletion:
+                            observer.OnNext(_task.Result);
+                            observer.OnCompleted();
+                            break;
+
+                        case TaskStatus.Faulted:
+                            observer.OnError(_task.Exception);
+                            break;
+
+                        case TaskStatus.Canceled:
+                            observer.OnError(new TaskCanceledException(t));
+                            break;
+                    }
+                }, cts.Token);
+
+                // Support unsubscribe simply by canceling the continuation if it hasn't yet run
+                return new CancelOnDispose { Source = cts };
+            }
+        }
+
+        /// <summary>Translate a call to IDisposable.Dispose to a CancellationTokenSource.Cancel.</summary>
+        private class CancelOnDispose : IDisposable
+        {
+            internal CancellationTokenSource Source;
+            void IDisposable.Dispose() { Source.Cancel(); }
+        }
+        #endregion
+
+        #region Timeouts
+        /// <summary>Creates a new Task that mirrors the supplied task but that will be canceled after the specified timeout.</summary>
+        /// <typeparam name="TResult">Specifies the type of data contained in the task.</typeparam>
+        /// <param name="task">The task.</param>
+        /// <param name="timeout">The timeout.</param>
+        /// <returns>The new Task that may time out.</returns>
+        public static Task WithTimeout(this Task task, TimeSpan timeout)
+        {
+            var result = new TaskCompletionSource<object>(task.AsyncState);
+            var timer = new Timer(state => ((TaskCompletionSource<object>)state).TrySetCanceled(), result, timeout, TimeSpan.FromMilliseconds(-1));
+            task.ContinueWith(t =>
+            {
+                timer.Dispose();
+                result.TrySetFromTask(t);
+            }, TaskContinuationOptions.ExecuteSynchronously);
+            return result.Task;
+        }
+
+        /// <summary>Creates a new Task that mirrors the supplied task but that will be canceled after the specified timeout.</summary>
+        /// <typeparam name="TResult">Specifies the type of data contained in the task.</typeparam>
+        /// <param name="task">The task.</param>
+        /// <param name="timeout">The timeout.</param>
+        /// <returns>The new Task that may time out.</returns>
+        public static Task<TResult> WithTimeout<TResult>(this Task<TResult> task, TimeSpan timeout)
+        {
+            var result = new TaskCompletionSource<TResult>(task.AsyncState);
+            var timer = new Timer(state => ((TaskCompletionSource<TResult>)state).TrySetCanceled(), result, timeout, TimeSpan.FromMilliseconds(-1));
+            task.ContinueWith(t =>
+            {
+                timer.Dispose();
+                result.TrySetFromTask(t);
+            }, TaskContinuationOptions.ExecuteSynchronously);
+            return result.Task;
+        }
+        #endregion
+
+        #region Children
+        /// <summary>
+        /// Ensures that a parent task can't transition into a completed state
+        /// until the specified task has also completed, even if it's not
+        /// already a child task.
+        /// </summary>
+        /// <param name="task">The task to attach to the current task as a child.</param>
+        public static void AttachToParent(this Task task)
+        {
+            if (task == null) throw new ArgumentNullException("task");
+            task.ContinueWith(t => t.Wait(), CancellationToken.None,
+                TaskContinuationOptions.AttachedToParent | 
+                TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
+        }
+        #endregion
+
+        #region Waiting
+        /// <summary>Waits for the task to complete execution, pumping in the meantime.</summary>
+        /// <param name="task">The task for which to wait.</param>
+        /// <remarks>This method is intended for usage with Windows Presentation Foundation.</remarks>
+        public static void WaitWithPumping(this Task task)
+        {
+            if (task == null) throw new ArgumentNullException("task");
+            var nestedFrame = new DispatcherFrame();
+            task.ContinueWith(_ => nestedFrame.Continue = false);
+            Dispatcher.PushFrame(nestedFrame);
+            task.Wait();
+        }
+
+        /// <summary>Waits for the task to complete execution, returning the task's final status.</summary>
+        /// <param name="task">The task for which to wait.</param>
+        /// <returns>The completion status of the task.</returns>
+        /// <remarks>Unlike Wait, this method will not throw an exception if the task ends in the Faulted or Canceled state.</remarks>
+        public static TaskStatus WaitForCompletionStatus(this Task task)
+        {
+            if (task == null) throw new ArgumentNullException("task");
+            ((IAsyncResult)task).AsyncWaitHandle.WaitOne();
+            return task.Status;
+        }
+        #endregion
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskFactoryExtensions/TaskFactoryExtensions_Common.cs b/trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskFactoryExtensions/TaskFactoryExtensions_Common.cs
new file mode 100644 (file)
index 0000000..543a83c
--- /dev/null
@@ -0,0 +1,59 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: TaskFactoryExtensions_Common.cs
+//
+//--------------------------------------------------------------------------
+
+namespace System.Threading.Tasks
+{
+    /// <summary>Extensions for TaskFactory.</summary>
+    public static partial class TaskFactoryExtensions
+    {
+        /// <summary>Creates a generic TaskFactory from a non-generic one.</summary>
+        /// <typeparam name="TResult">Specifies the type of Task results for the Tasks created by the new TaskFactory.</typeparam>
+        /// <param name="factory">The TaskFactory to serve as a template.</param>
+        /// <returns>The created TaskFactory.</returns>
+        public static TaskFactory<TResult> ToGeneric<TResult>(this TaskFactory factory)
+        {
+            return new TaskFactory<TResult>(
+                factory.CancellationToken, factory.CreationOptions, factory.ContinuationOptions, factory.Scheduler);
+        }
+
+        /// <summary>Creates a generic TaskFactory from a non-generic one.</summary>
+        /// <typeparam name="TResult">Specifies the type of Task results for the Tasks created by the new TaskFactory.</typeparam>
+        /// <param name="factory">The TaskFactory to serve as a template.</param>
+        /// <returns>The created TaskFactory.</returns>
+        public static TaskFactory ToNonGeneric<TResult>(this TaskFactory<TResult> factory)
+        {
+            return new TaskFactory(
+                factory.CancellationToken, factory.CreationOptions, factory.ContinuationOptions, factory.Scheduler);
+        }
+
+        /// <summary>Gets the TaskScheduler instance that should be used to schedule tasks.</summary>
+        public static TaskScheduler GetTargetScheduler(this TaskFactory factory)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            return factory.Scheduler ?? TaskScheduler.Current;
+        }
+
+        /// <summary>Gets the TaskScheduler instance that should be used to schedule tasks.</summary>
+        public static TaskScheduler GetTargetScheduler<TResult>(this TaskFactory<TResult> factory)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            return factory.Scheduler != null ? factory.Scheduler : TaskScheduler.Current;
+        }
+
+        /// <summary>Converts TaskCreationOptions into TaskContinuationOptions.</summary>
+        /// <param name="creationOptions"></param>
+        /// <returns></returns>
+        private static TaskContinuationOptions ContinuationOptionsFromCreationOptions(TaskCreationOptions creationOptions)
+        {
+            return (TaskContinuationOptions)
+                ((creationOptions & TaskCreationOptions.AttachedToParent) |
+                 (creationOptions & TaskCreationOptions.PreferFairness) |
+                 (creationOptions & TaskCreationOptions.LongRunning));
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskFactoryExtensions/TaskFactoryExtensions_ContinueWhenAllAny.cs b/trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskFactoryExtensions/TaskFactoryExtensions_ContinueWhenAllAny.cs
new file mode 100644 (file)
index 0000000..df8cafd
--- /dev/null
@@ -0,0 +1,67 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: TaskFactoryExtensions_ContinueWhenAllAny.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Generic;
+
+namespace System.Threading.Tasks
+{
+    public static partial class TaskFactoryExtensions
+    {
+        /// <summary>
+        /// Creates a continuation Task that will compplete upon
+        /// the completion of a set of provided Tasks.
+        /// </summary>
+        /// <param name="factory">The TaskFactory to use to create the continuation task.</param>
+        /// <param name="tasks">The array of tasks from which to continue.</param>
+        /// <returns>A task that, when completed, will return the array of completed tasks.</returns>
+        public static Task<Task[]> WhenAll(
+            this TaskFactory factory, params Task[] tasks)
+        {
+            return factory.ContinueWhenAll(tasks, completedTasks => completedTasks);
+        }
+
+        /// <summary>
+        /// Creates a continuation Task that will compplete upon
+        /// the completion of a set of provided Tasks.
+        /// </summary>
+        /// <param name="factory">The TaskFactory to use to create the continuation task.</param>
+        /// <param name="tasks">The array of tasks from which to continue.</param>
+        /// <returns>A task that, when completed, will return the array of completed tasks.</returns>
+        public static Task<Task<TAntecedentResult>[]> WhenAll<TAntecedentResult>(
+            this TaskFactory factory, params Task<TAntecedentResult>[] tasks)
+        {
+            return factory.ContinueWhenAll(tasks, completedTasks => completedTasks);
+        }
+
+        /// <summary>
+        /// Creates a continuation Task that will complete upon
+        /// the completion of any one of a set of provided Tasks.
+        /// </summary>
+        /// <param name="factory">The TaskFactory to use to create the continuation task.</param>
+        /// <param name="tasks">The array of tasks from which to continue.</param>
+        /// <returns>A task that, when completed, will return the completed task.</returns>
+        public static Task<Task> WhenAny(
+            this TaskFactory factory, params Task[] tasks)
+        {
+            return factory.ContinueWhenAny(tasks, completedTask => completedTask);
+        }
+
+        /// <summary>
+        /// Creates a continuation Task that will complete upon
+        /// the completion of any one of a set of provided Tasks.
+        /// </summary>
+        /// <param name="factory">The TaskFactory to use to create the continuation task.</param>
+        /// <param name="tasks">The array of tasks from which to continue.</param>
+        /// <returns>A task that, when completed, will return the completed task.</returns>
+        public static Task<Task<TAntecedentResult>> WhenAny<TAntecedentResult>(
+            this TaskFactory factory, params Task<TAntecedentResult>[] tasks)
+        {
+            return factory.ContinueWhenAny(tasks, completedTask => completedTask);
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskFactoryExtensions/TaskFactoryExtensions_Create.cs b/trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskFactoryExtensions/TaskFactoryExtensions_Create.cs
new file mode 100644 (file)
index 0000000..cc8cc46
--- /dev/null
@@ -0,0 +1,157 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: TaskFactoryExtensions_Create.cs
+//
+//--------------------------------------------------------------------------
+
+namespace System.Threading.Tasks
+{
+    public static partial class TaskFactoryExtensions
+    {
+        #region TaskFactory with Action
+        /// <summary>Creates a Task using the TaskFactory.</summary>
+        /// <param name="factory">The factory to use.</param>
+        /// <param name="action">The delegate for the task.</param>
+        /// <returns>The created task.  The task has not been scheduled.</returns>
+        public static Task Create(
+            this TaskFactory factory, Action action)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            return new Task(action, factory.CancellationToken, factory.CreationOptions);
+        }
+
+        /// <summary>Creates a Task using the TaskFactory.</summary>
+        /// <param name="factory">The factory to use.</param>
+        /// <param name="action">The delegate for the task.</param>
+        /// <param name="creationOptions">Options that control the task's behavior.</param>
+        /// <returns>The created task.  The task has not been scheduled.</returns>
+        public static Task Create(
+            this TaskFactory factory, Action action, TaskCreationOptions creationOptions)
+        {
+            return new Task(action, factory.CancellationToken, creationOptions);
+        }
+
+        /// <summary>Creates a Task using the TaskFactory.</summary>
+        /// <param name="factory">The factory to use.</param>
+        /// <param name="action">The delegate for the task.</param>
+        /// <param name="state">An object provided to the delegate.</param>
+        /// <returns>The created task.  The task has not been scheduled.</returns>
+        public static Task Create(
+            this TaskFactory factory, Action<Object> action, object state)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            return new Task(action, state, factory.CancellationToken, factory.CreationOptions);
+        }
+
+        /// <summary>Creates a Task using the TaskFactory.</summary>
+        /// <param name="factory">The factory to use.</param>
+        /// <param name="action">The delegate for the task.</param>
+        /// <param name="state">An object provided to the delegate.</param>
+        /// <param name="creationOptions">Options that control the task's behavior.</param>
+        /// <returns>The created task.  The task has not been scheduled.</returns>
+        public static Task Create(
+            this TaskFactory factory, Action<Object> action, object state, TaskCreationOptions creationOptions)
+        {
+            return new Task(action, state, factory.CancellationToken, creationOptions);
+        }
+        #endregion
+
+        #region TaskFactory with Func
+        /// <summary>Creates a Task using the TaskFactory.</summary>
+        /// <param name="factory">The factory to use.</param>
+        /// <param name="function">The delegate for the task.</param>
+        /// <returns>The created task.  The task has not been scheduled.</returns>
+        public static Task<TResult> Create<TResult>(
+            this TaskFactory factory, Func<TResult> function)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            return new Task<TResult>(function, factory.CancellationToken, factory.CreationOptions);
+        }
+
+        /// <summary>Creates a Task using the TaskFactory.</summary>
+        /// <param name="factory">The factory to use.</param>
+        /// <param name="function">The delegate for the task.</param>
+        /// <param name="creationOptions">Options that control the task's behavior.</param>
+        /// <returns>The created task.  The task has not been scheduled.</returns>
+        public static Task<TResult> Create<TResult>(
+            this TaskFactory factory, Func<TResult> function, TaskCreationOptions creationOptions)
+        {
+            return new Task<TResult>(function, factory.CancellationToken, creationOptions);
+        }
+
+        /// <summary>Creates a Task using the TaskFactory.</summary>
+        /// <param name="factory">The factory to use.</param>
+        /// <param name="function">The delegate for the task.</param>
+        /// <param name="state">An object provided to the delegate.</param>
+        /// <returns>The created task.  The task has not been scheduled.</returns>
+        public static Task<TResult> Create<TResult>(
+            this TaskFactory factory, Func<Object, TResult> function, object state)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            return new Task<TResult>(function, state, factory.CancellationToken, factory.CreationOptions);
+        }
+
+        /// <summary>Creates a Task using the TaskFactory.</summary>
+        /// <param name="factory">The factory to use.</param>
+        /// <param name="function">The delegate for the task.</param>
+        /// <param name="state">An object provided to the delegate.</param>
+        /// <param name="creationOptions">Options that control the task's behavior.</param>
+        /// <returns>The created task.  The task has not been scheduled.</returns>
+        public static Task<TResult> Create<TResult>(
+            this TaskFactory factory, Func<Object, TResult> function, object state, TaskCreationOptions creationOptions)
+        {
+            return new Task<TResult>(function, state, factory.CancellationToken, creationOptions);
+        }
+        #endregion
+
+        #region TaskFactory<TResult> with Func
+        /// <summary>Creates a Task using the TaskFactory.</summary>
+        /// <param name="factory">The factory to use.</param>
+        /// <param name="function">The delegate for the task.</param>
+        /// <returns>The created task.  The task has not been scheduled.</returns>
+        public static Task<TResult> Create<TResult>(
+            this TaskFactory<TResult> factory, Func<TResult> function)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            return new Task<TResult>(function, factory.CancellationToken, factory.CreationOptions);
+        }
+
+        /// <summary>Creates a Task using the TaskFactory.</summary>
+        /// <param name="factory">The factory to use.</param>
+        /// <param name="function">The delegate for the task.</param>
+        /// <param name="creationOptions">Options that control the task's behavior.</param>
+        /// <returns>The created task.  The task has not been scheduled.</returns>
+        public static Task<TResult> Create<TResult>(
+            this TaskFactory<TResult> factory, Func<TResult> function, TaskCreationOptions creationOptions)
+        {
+            return new Task<TResult>(function, factory.CancellationToken, creationOptions);
+        }
+
+        /// <summary>Creates a Task using the TaskFactory.</summary>
+        /// <param name="factory">The factory to use.</param>
+        /// <param name="function">The delegate for the task.</param>
+        /// <param name="state">An object provided to the delegate.</param>
+        /// <returns>The created task.  The task has not been scheduled.</returns>
+        public static Task<TResult> Create<TResult>(
+            this TaskFactory<TResult> factory, Func<Object, TResult> function, object state)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            return new Task<TResult>(function, state, factory.CancellationToken, factory.CreationOptions);
+        }
+
+        /// <summary>Creates a Task using the TaskFactory.</summary>
+        /// <param name="factory">The factory to use.</param>
+        /// <param name="function">The delegate for the task.</param>
+        /// <param name="state">An object provided to the delegate.</param>
+        /// <param name="creationOptions">Options that control the task's behavior.</param>
+        /// <returns>The created task.  The task has not been scheduled.</returns>
+        public static Task<TResult> Create<TResult>(
+            this TaskFactory<TResult> factory, Func<Object, TResult> function, object state, TaskCreationOptions creationOptions)
+        {
+            return new Task<TResult>(function, state, factory.CancellationToken, creationOptions);
+        }
+        #endregion
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskFactoryExtensions/TaskFactoryExtensions_Delayed.cs b/trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskFactoryExtensions/TaskFactoryExtensions_Delayed.cs
new file mode 100644 (file)
index 0000000..ad80a12
--- /dev/null
@@ -0,0 +1,386 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: TaskFactoryExtensions_Delayed.cs
+//
+//--------------------------------------------------------------------------
+
+namespace System.Threading.Tasks
+{
+    public static partial class TaskFactoryExtensions
+    {
+        #region TaskFactory No Action
+        /// <summary>Creates a Task that will complete after the specified delay.</summary>
+        /// <param name="factory">The TaskFactory.</param>
+        /// <param name="millisecondsDelay">The delay after which the Task should transition to RanToCompletion.</param>
+        /// <returns>A Task that will be completed after the specified duration.</returns>
+        public static Task StartNewDelayed(
+            this TaskFactory factory, int millisecondsDelay)
+        {
+            return StartNewDelayed(factory, millisecondsDelay, CancellationToken.None);
+        }
+
+        /// <summary>Creates a Task that will complete after the specified delay.</summary>
+        /// <param name="factory">The TaskFactory.</param>
+        /// <param name="millisecondsDelay">The delay after which the Task should transition to RanToCompletion.</param>
+        /// <param name="cancellationToken">The cancellation token that can be used to cancel the timed task.</param>
+        /// <returns>A Task that will be completed after the specified duration and that's cancelable with the specified token.</returns>
+        public static Task StartNewDelayed(this TaskFactory factory, int millisecondsDelay, CancellationToken cancellationToken)
+        {
+            // Validate arguments
+            if (factory == null) throw new ArgumentNullException("factory");
+            if (millisecondsDelay < 0) throw new ArgumentOutOfRangeException("millisecondsDelay");
+
+            // Create the timed task
+            var tcs = new TaskCompletionSource<object>(factory.CreationOptions);
+            var ctr = default(CancellationTokenRegistration);
+
+            // Create the timer but don't start it yet.  If we start it now,
+            // it might fire before ctr has been set to the right registration.
+            var timer = new Timer(self =>
+            {
+                // Clean up both the cancellation token and the timer, and try to transition to completed
+                ctr.Dispose();
+                ((Timer)self).Dispose();
+                tcs.TrySetResult(null);
+            });
+
+            // Register with the cancellation token.
+            if (cancellationToken.CanBeCanceled)
+            {
+                // When cancellation occurs, cancel the timer and try to transition to canceled.
+                // There could be a race, but it's benign.
+                ctr = cancellationToken.Register(() =>
+                {
+                    timer.Dispose();
+                    tcs.TrySetCanceled();
+                });
+            }
+
+            // Start the timer and hand back the task...
+            timer.Change(millisecondsDelay, Timeout.Infinite);
+            return tcs.Task;
+        }
+        #endregion
+
+        #region TaskFactory with Action
+        /// <summary>Creates and schedules a task for execution after the specified time delay.</summary>
+        /// <param name="factory">The factory to use to create the task.</param>
+        /// <param name="millisecondsDelay">The delay after which the task will be scheduled.</param>
+        /// <param name="action">The delegate executed by the task.</param>
+        /// <returns>The created Task.</returns>
+        public static Task StartNewDelayed(
+            this TaskFactory factory,
+            int millisecondsDelay, Action action)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            return StartNewDelayed(factory, millisecondsDelay, action, factory.CancellationToken, factory.CreationOptions, factory.GetTargetScheduler());
+        }
+
+        /// <summary>Creates and schedules a task for execution after the specified time delay.</summary>
+        /// <param name="factory">The factory to use to create the task.</param>
+        /// <param name="millisecondsDelay">The delay after which the task will be scheduled.</param>
+        /// <param name="action">The delegate executed by the task.</param>
+        /// <param name="creationOptions">Options that control the task's behavior.</param>
+        /// <returns>The created Task.</returns>
+        public static Task StartNewDelayed(
+            this TaskFactory factory,
+            int millisecondsDelay, Action action,
+            TaskCreationOptions creationOptions)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            return StartNewDelayed(factory, millisecondsDelay, action, factory.CancellationToken, creationOptions, factory.GetTargetScheduler());
+        }
+
+        /// <summary>Creates and schedules a task for execution after the specified time delay.</summary>
+        /// <param name="factory">The factory to use to create the task.</param>
+        /// <param name="millisecondsDelay">The delay after which the task will be scheduled.</param>
+        /// <param name="action">The delegate executed by the task.</param>
+        /// <param name="cancellationToken">The cancellation token to assign to the created Task.</param>
+        /// <returns>The created Task.</returns>
+        public static Task StartNewDelayed(
+            this TaskFactory factory,
+            int millisecondsDelay, Action action,
+            CancellationToken cancellationToken)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            return StartNewDelayed(factory, millisecondsDelay, action, cancellationToken, factory.CreationOptions, factory.GetTargetScheduler());
+        }
+
+        /// <summary>Creates and schedules a task for execution after the specified time delay.</summary>
+        /// <param name="factory">The factory to use to create the task.</param>
+        /// <param name="millisecondsDelay">The delay after which the task will be scheduled.</param>
+        /// <param name="action">The delegate executed by the task.</param>
+        /// <param name="cancellationToken">The cancellation token to assign to the created Task.</param>
+        /// <param name="creationOptions">Options that control the task's behavior.</param>
+        /// <param name="scheduler">The scheduler to which the Task will be scheduled.</param>
+        /// <returns>The created Task.</returns>
+        public static Task StartNewDelayed(
+            this TaskFactory factory,
+            int millisecondsDelay, Action action, 
+            CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            if (millisecondsDelay < 0) throw new ArgumentOutOfRangeException("millisecondsDelay");
+            if (action == null) throw new ArgumentNullException("action");
+            if (scheduler == null) throw new ArgumentNullException("scheduler");
+
+            return factory
+                .StartNewDelayed(millisecondsDelay, cancellationToken)
+                .ContinueWith(_ => action(), cancellationToken, TaskContinuationOptions.OnlyOnRanToCompletion, scheduler);
+        }
+
+        /// <summary>Creates and schedules a task for execution after the specified time delay.</summary>
+        /// <param name="factory">The factory to use to create the task.</param>
+        /// <param name="millisecondsDelay">The delay after which the task will be scheduled.</param>
+        /// <param name="action">The delegate executed by the task.</param>
+        /// <param name="state">An object provided to the delegate.</param>
+        /// <returns>The created Task.</returns>
+        public static Task StartNewDelayed(
+            this TaskFactory factory,
+            int millisecondsDelay, Action<object> action, object state)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            return StartNewDelayed(factory, millisecondsDelay, action, state, factory.CancellationToken, factory.CreationOptions, factory.GetTargetScheduler());
+        }
+
+        /// <summary>Creates and schedules a task for execution after the specified time delay.</summary>
+        /// <param name="factory">The factory to use to create the task.</param>
+        /// <param name="millisecondsDelay">The delay after which the task will be scheduled.</param>
+        /// <param name="action">The delegate executed by the task.</param>
+        /// <param name="state">An object provided to the delegate.</param>
+        /// <param name="creationOptions">Options that control the task's behavior.</param>
+        /// <returns>The created Task.</returns>
+        public static Task StartNewDelayed(
+            this TaskFactory factory,
+            int millisecondsDelay, Action<object> action, object state,
+            TaskCreationOptions creationOptions)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            return StartNewDelayed(factory, millisecondsDelay, action, state, factory.CancellationToken, creationOptions, factory.GetTargetScheduler());
+        }
+
+        /// <summary>Creates and schedules a task for execution after the specified time delay.</summary>
+        /// <param name="factory">The factory to use to create the task.</param>
+        /// <param name="millisecondsDelay">The delay after which the task will be scheduled.</param>
+        /// <param name="action">The delegate executed by the task.</param>
+        /// <param name="state">An object provided to the delegate.</param>
+        /// <param name="cancellationToken">The cancellation token to assign to the created Task.</param>
+        /// <returns>The created Task.</returns>
+        public static Task StartNewDelayed(
+            this TaskFactory factory,
+            int millisecondsDelay, Action<object> action, object state,
+            CancellationToken cancellationToken)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            return StartNewDelayed(factory, millisecondsDelay, action, state, cancellationToken, factory.CreationOptions, factory.GetTargetScheduler());
+        }
+
+        /// <summary>Creates and schedules a task for execution after the specified time delay.</summary>
+        /// <param name="factory">The factory to use to create the task.</param>
+        /// <param name="millisecondsDelay">The delay after which the task will be scheduled.</param>
+        /// <param name="action">The delegate executed by the task.</param>
+        /// <param name="state">An object provided to the delegate.</param>
+        /// <param name="cancellationToken">The cancellation token to assign to the created Task.</param>
+        /// <param name="creationOptions">Options that control the task's behavior.</param>
+        /// <param name="scheduler">The scheduler to which the Task will be scheduled.</param>
+        /// <returns>The created Task.</returns>
+        public static Task StartNewDelayed(
+            this TaskFactory factory,
+            int millisecondsDelay, Action<object> action, object state,
+            CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            if (millisecondsDelay < 0) throw new ArgumentOutOfRangeException("millisecondsDelay");
+            if (action == null) throw new ArgumentNullException("action");
+            if (scheduler == null) throw new ArgumentNullException("scheduler");
+
+            // Create the task that will be returned; workaround for no ContinueWith(..., state) overload.
+            var result = new TaskCompletionSource<object>(state);
+
+            // Delay a continuation to run the action
+            factory
+                .StartNewDelayed(millisecondsDelay, cancellationToken)
+                .ContinueWith(t =>
+                {
+                    if (t.IsCanceled) result.TrySetCanceled();
+                    else
+                    {
+                        try
+                        {
+                            action(state);
+                            result.TrySetResult(null);
+                        }
+                        catch (Exception exc) { result.TrySetException(exc); }
+                    }
+                }, scheduler);
+
+            // Return the task
+            return result.Task;
+        }
+        #endregion
+
+        #region TaskFactory<TResult> with Func
+        /// <summary>Creates and schedules a task for execution after the specified time delay.</summary>
+        /// <param name="factory">The factory to use to create the task.</param>
+        /// <param name="millisecondsDelay">The delay after which the task will be scheduled.</param>
+        /// <param name="function">The delegate executed by the task.</param>
+        /// <returns>The created Task.</returns>
+        public static Task<TResult> StartNewDelayed<TResult>(
+            this TaskFactory<TResult> factory,
+            int millisecondsDelay, Func<TResult> function)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            return StartNewDelayed(factory, millisecondsDelay, function, factory.CancellationToken, factory.CreationOptions, factory.GetTargetScheduler());
+        }
+
+        /// <summary>Creates and schedules a task for execution after the specified time delay.</summary>
+        /// <param name="factory">The factory to use to create the task.</param>
+        /// <param name="millisecondsDelay">The delay after which the task will be scheduled.</param>
+        /// <param name="function">The delegate executed by the task.</param>
+        /// <param name="creationOptions">Options that control the task's behavior.</param>
+        /// <returns>The created Task.</returns>
+        public static Task<TResult> StartNewDelayed<TResult>(
+            this TaskFactory<TResult> factory,
+            int millisecondsDelay, Func<TResult> function,
+            TaskCreationOptions creationOptions)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            return StartNewDelayed(factory, millisecondsDelay, function, factory.CancellationToken, creationOptions, factory.GetTargetScheduler());
+        }
+
+        /// <summary>Creates and schedules a task for execution after the specified time delay.</summary>
+        /// <param name="factory">The factory to use to create the task.</param>
+        /// <param name="millisecondsDelay">The delay after which the task will be scheduled.</param>
+        /// <param name="function">The delegate executed by the task.</param>
+        /// <param name="cancellationToken">The CancellationToken to assign to the Task.</param>
+        /// <returns>The created Task.</returns>
+        public static Task<TResult> StartNewDelayed<TResult>(
+            this TaskFactory<TResult> factory,
+            int millisecondsDelay, Func<TResult> function,
+            CancellationToken cancellationToken)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            return StartNewDelayed(factory, millisecondsDelay, function, cancellationToken, factory.CreationOptions, factory.GetTargetScheduler());
+        }
+
+        /// <summary>Creates and schedules a task for execution after the specified time delay.</summary>
+        /// <param name="factory">The factory to use to create the task.</param>
+        /// <param name="millisecondsDelay">The delay after which the task will be scheduled.</param>
+        /// <param name="function">The delegate executed by the task.</param>
+        /// <param name="cancellationToken">The CancellationToken to assign to the Task.</param>
+        /// <param name="creationOptions">Options that control the task's behavior.</param>
+        /// <param name="scheduler">The scheduler to which the Task will be scheduled.</param>
+        /// <returns>The created Task.</returns>
+        public static Task<TResult> StartNewDelayed<TResult>(
+            this TaskFactory<TResult> factory,
+            int millisecondsDelay, Func<TResult> function,
+            CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            if (millisecondsDelay < 0) throw new ArgumentOutOfRangeException("millisecondsDelay");
+            if (function == null) throw new ArgumentNullException("function");
+            if (scheduler == null) throw new ArgumentNullException("scheduler");
+
+            // Create the trigger and the timer to start it
+            var tcs = new TaskCompletionSource<object>();
+            var timer = new Timer(obj => ((TaskCompletionSource<object>)obj).SetResult(null),
+                tcs, millisecondsDelay, Timeout.Infinite);
+
+            // Return a task that executes the function when the trigger fires
+            return tcs.Task.ContinueWith(_ =>
+            {
+                timer.Dispose();
+                return function();
+            }, cancellationToken, ContinuationOptionsFromCreationOptions(creationOptions), scheduler);
+        }
+
+        /// <summary>Creates and schedules a task for execution after the specified time delay.</summary>
+        /// <param name="factory">The factory to use to create the task.</param>
+        /// <param name="millisecondsDelay">The delay after which the task will be scheduled.</param>
+        /// <param name="function">The delegate executed by the task.</param>
+        /// <param name="state">An object provided to the delegate.</param>
+        /// <returns>The created Task.</returns>
+        public static Task<TResult> StartNewDelayed<TResult>(
+            this TaskFactory<TResult> factory,
+            int millisecondsDelay, Func<object, TResult> function, object state)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            return StartNewDelayed(factory, millisecondsDelay, function, state, factory.CancellationToken, factory.CreationOptions, factory.GetTargetScheduler());
+        }
+
+        /// <summary>Creates and schedules a task for execution after the specified time delay.</summary>
+        /// <param name="factory">The factory to use to create the task.</param>
+        /// <param name="millisecondsDelay">The delay after which the task will be scheduled.</param>
+        /// <param name="function">The delegate executed by the task.</param>
+        /// <param name="state">An object provided to the delegate.</param>
+        /// <param name="cancellationToken">The CancellationToken to assign to the Task.</param>
+        /// <returns>The created Task.</returns>
+        public static Task<TResult> StartNewDelayed<TResult>(
+            this TaskFactory<TResult> factory,
+            int millisecondsDelay, Func<object, TResult> function, object state,
+            CancellationToken cancellationToken)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            return StartNewDelayed(factory, millisecondsDelay, function, state, cancellationToken, factory.CreationOptions, factory.GetTargetScheduler());
+        }
+
+        /// <summary>Creates and schedules a task for execution after the specified time delay.</summary>
+        /// <param name="factory">The factory to use to create the task.</param>
+        /// <param name="millisecondsDelay">The delay after which the task will be scheduled.</param>
+        /// <param name="function">The delegate executed by the task.</param>
+        /// <param name="state">An object provided to the delegate.</param>
+        /// <param name="creationOptions">Options that control the task's behavior.</param>
+        /// <returns>The created Task.</returns>
+        public static Task<TResult> StartNewDelayed<TResult>(
+            this TaskFactory<TResult> factory,
+            int millisecondsDelay, Func<object, TResult> function, object state,
+            TaskCreationOptions creationOptions)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            return StartNewDelayed(factory, millisecondsDelay, function, state, factory.CancellationToken, creationOptions, factory.GetTargetScheduler());
+        }
+
+        /// <summary>Creates and schedules a task for execution after the specified time delay.</summary>
+        /// <param name="factory">The factory to use to create the task.</param>
+        /// <param name="millisecondsDelay">The delay after which the task will be scheduled.</param>
+        /// <param name="function">The delegate executed by the task.</param>
+        /// <param name="state">An object provided to the delegate.</param>
+        /// <param name="cancellationToken">The CancellationToken to assign to the Task.</param>
+        /// <param name="creationOptions">Options that control the task's behavior.</param>
+        /// <param name="scheduler">The scheduler to which the Task will be scheduled.</param>
+        /// <returns>The created Task.</returns>
+        public static Task<TResult> StartNewDelayed<TResult>(
+            this TaskFactory<TResult> factory,
+            int millisecondsDelay, Func<object, TResult> function, object state,
+            CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            if (millisecondsDelay < 0) throw new ArgumentOutOfRangeException("millisecondsDelay");
+            if (function == null) throw new ArgumentNullException("action");
+            if (scheduler == null) throw new ArgumentNullException("scheduler");
+
+            // Create the task that will be returned
+            var result = new TaskCompletionSource<TResult>(state);
+            Timer timer = null;
+
+            // Create the task that will run the user's function
+            var functionTask = new Task<TResult>(function, state, creationOptions);
+
+            // When the function task completes, transfer the results to the returned task
+            functionTask.ContinueWith(t =>
+            {
+                result.SetFromTask(t);
+                timer.Dispose();
+            }, cancellationToken, ContinuationOptionsFromCreationOptions(creationOptions) | TaskContinuationOptions.ExecuteSynchronously, scheduler);
+
+            // Start the timer for the trigger
+            timer = new Timer(obj => ((Task)obj).Start(scheduler),
+                functionTask, millisecondsDelay, Timeout.Infinite);
+
+            return result.Task;
+        }
+        #endregion
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskFactoryExtensions/TaskFactoryExtensions_From.cs b/trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskFactoryExtensions/TaskFactoryExtensions_From.cs
new file mode 100644 (file)
index 0000000..0837365
--- /dev/null
@@ -0,0 +1,76 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: TaskFactoryExtensions_From.cs
+//
+//--------------------------------------------------------------------------
+
+namespace System.Threading.Tasks
+{
+    /// <summary>Extensions for TaskFactory.</summary>
+    public static partial class TaskFactoryExtensions
+    {
+        #region TaskFactory
+        /// <summary>Creates a Task that has completed in the Faulted state with the specified exception.</summary>
+        /// <param name="factory">The target TaskFactory.</param>
+        /// <param name="exception">The exception with which the Task should fault.</param>
+        /// <returns>The completed Task.</returns>
+        public static Task FromException(this TaskFactory factory, Exception exception)
+        {
+            var tcs = new TaskCompletionSource<object>(factory.CreationOptions);
+            tcs.SetException(exception);
+            return tcs.Task;
+        }
+
+        /// <summary>Creates a Task that has completed in the Faulted state with the specified exception.</summary>
+        /// <typeparam name="TResult">Specifies the type of payload for the new Task.</typeparam>
+        /// <param name="factory">The target TaskFactory.</param>
+        /// <param name="exception">The exception with which the Task should fault.</param>
+        /// <returns>The completed Task.</returns>
+        public static Task<TResult> FromException<TResult>(this TaskFactory factory, Exception exception)
+        {
+            var tcs = new TaskCompletionSource<TResult>(factory.CreationOptions);
+            tcs.SetException(exception);
+            return tcs.Task;
+        }
+
+        /// <summary>Creates a Task that has completed in the RanToCompletion state with the specified result.</summary>
+        /// <typeparam name="TResult">Specifies the type of payload for the new Task.</typeparam>
+        /// <param name="factory">The target TaskFactory.</param>
+        /// <param name="result">The result with which the Task should complete.</param>
+        /// <returns>The completed Task.</returns>
+        public static Task<TResult> FromResult<TResult>(this TaskFactory factory, TResult result)
+        {
+            var tcs = new TaskCompletionSource<TResult>(factory.CreationOptions);
+            tcs.SetResult(result);
+            return tcs.Task;
+        }
+        #endregion
+
+        #region TaskFactory<TResult>
+        /// <summary>Creates a Task that has completed in the Faulted state with the specified exception.</summary>
+        /// <param name="factory">The target TaskFactory.</param>
+        /// <param name="exception">The exception with which the Task should fault.</param>
+        /// <returns>The completed Task.</returns>
+        public static Task<TResult> FromException<TResult>(this TaskFactory<TResult> factory, Exception exception)
+        {
+            var tcs = new TaskCompletionSource<TResult>(factory.CreationOptions);
+            tcs.SetException(exception);
+            return tcs.Task;
+        }
+
+        /// <summary>Creates a Task that has completed in the RanToCompletion state with the specified result.</summary>
+        /// <typeparam name="TResult">Specifies the type of payload for the new Task.</typeparam>
+        /// <param name="factory">The target TaskFactory.</param>
+        /// <param name="result">The result with which the Task should complete.</param>
+        /// <returns>The completed Task.</returns>
+        public static Task<TResult> FromResult<TResult>(this TaskFactory<TResult> factory, TResult result)
+        {
+            var tcs = new TaskCompletionSource<TResult>(factory.CreationOptions);
+            tcs.SetResult(result);
+            return tcs.Task;
+        }
+        #endregion
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskFactoryExtensions/TaskFactoryExtensions_FromAsync.cs b/trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskFactoryExtensions/TaskFactoryExtensions_FromAsync.cs
new file mode 100644 (file)
index 0000000..c825df2
--- /dev/null
@@ -0,0 +1,30 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: TaskFactoryExtensions_FromAsync.cs
+//
+//--------------------------------------------------------------------------
+
+namespace System.Threading.Tasks
+{
+    /// <summary>Extensions for TaskFactory.</summary>
+    public static partial class TaskFactoryExtensions
+    {
+        /// <summary>Creates a Task that will be completed when the specified WaitHandle is signaled.</summary>
+        /// <param name="factory">The target factory.</param>
+        /// <param name="waitHandle">The WaitHandle.</param>
+        /// <returns>The created Task.</returns>
+        public static Task FromAsync(this TaskFactory factory, WaitHandle waitHandle)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            if (waitHandle == null) throw new ArgumentNullException("waitHandle");
+
+            var tcs = new TaskCompletionSource<object>();
+            var rwh = ThreadPool.RegisterWaitForSingleObject(waitHandle, delegate { tcs.TrySetResult(null); }, null, -1, true);
+            var t = tcs.Task;
+            t.ContinueWith(_ => rwh.Unregister(null), TaskContinuationOptions.ExecuteSynchronously);
+            return t;
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskFactoryExtensions/TaskFactoryExtensions_Iterate.cs b/trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskFactoryExtensions/TaskFactoryExtensions_Iterate.cs
new file mode 100644 (file)
index 0000000..e6ae72b
--- /dev/null
@@ -0,0 +1,228 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: TaskFactoryExtensions_Iterate.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+
+namespace System.Threading.Tasks
+{
+    public static partial class TaskFactoryExtensions
+    {
+        #region No Object State Overloads
+        /// <summary>Asynchronously iterates through an enumerable of tasks.</summary>
+        /// <param name="factory">The target factory.</param>
+        /// <param name="source">The enumerable containing the tasks to be iterated through.</param>
+        /// <returns>A Task that represents the complete asynchronous operation.</returns>
+        public static Task Iterate(
+            this TaskFactory factory,
+            IEnumerable<object> source)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            return Iterate(factory, source, null, factory.CancellationToken, factory.CreationOptions, factory.GetTargetScheduler());
+        }
+
+        /// <summary>Asynchronously iterates through an enumerable of tasks.</summary>
+        /// <param name="factory">The target factory.</param>
+        /// <param name="source">The enumerable containing the tasks to be iterated through.</param>
+        /// <param name="cancellationToken">The cancellation token used to cancel the iteration.</param>
+        /// <returns>A Task that represents the complete asynchronous operation.</returns>
+        public static Task Iterate(
+            this TaskFactory factory,
+            IEnumerable<object> source, 
+            CancellationToken cancellationToken)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            return Iterate(factory, source, null, cancellationToken, factory.CreationOptions, factory.GetTargetScheduler());
+        }
+
+        /// <summary>Asynchronously iterates through an enumerable of tasks.</summary>
+        /// <param name="factory">The target factory.</param>
+        /// <param name="source">The enumerable containing the tasks to be iterated through.</param>
+        /// <param name="creationOptions">Options that control the task's behavior.</param>
+        /// <returns>A Task that represents the complete asynchronous operation.</returns>
+        public static Task Iterate(
+            this TaskFactory factory,
+            IEnumerable<object> source, 
+            TaskCreationOptions creationOptions)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            return Iterate(factory, source, null, factory.CancellationToken, creationOptions, factory.GetTargetScheduler());
+        }
+
+        /// <summary>Asynchronously iterates through an enumerable of tasks.</summary>
+        /// <param name="factory">The target factory.</param>
+        /// <param name="source">The enumerable containing the tasks to be iterated through.</param>
+        /// <param name="scheduler">The scheduler to which tasks will be scheduled.</param>
+        /// <returns>A Task that represents the complete asynchronous operation.</returns>
+        public static Task Iterate(
+            this TaskFactory factory,
+            IEnumerable<object> source, 
+            TaskScheduler scheduler)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            return Iterate(factory, source, null, factory.CancellationToken, factory.CreationOptions, scheduler);
+        }
+
+        /// <summary>Asynchronously iterates through an enumerable of tasks.</summary>
+        /// <param name="factory">The target factory.</param>
+        /// <param name="source">The enumerable containing the tasks to be iterated through.</param>
+        /// <param name="cancellationToken">The cancellation token used to cancel the iteration.</param>
+        /// <param name="creationOptions">Options that control the task's behavior.</param>
+        /// <param name="scheduler">The scheduler to which tasks will be scheduled.</param>
+        /// <returns>A Task that represents the complete asynchronous operation.</returns>
+        public static Task Iterate(
+            this TaskFactory factory,
+            IEnumerable<object> source,
+            CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler)
+        {
+            return Iterate(factory, source, null, cancellationToken, creationOptions, scheduler);
+        }
+        #endregion
+
+        #region Object State Overloads and Full Implementation
+        /// <summary>Asynchronously iterates through an enumerable of tasks.</summary>
+        /// <param name="factory">The target factory.</param>
+        /// <param name="source">The enumerable containing the tasks to be iterated through.</param>
+        /// <param name="state">The asynchronous state for the returned Task.</param>
+        /// <returns>A Task that represents the complete asynchronous operation.</returns>
+        public static Task Iterate(
+            this TaskFactory factory,
+            IEnumerable<object> source, object state)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            return Iterate(factory, source, state, factory.CancellationToken, factory.CreationOptions, factory.GetTargetScheduler());
+        }
+
+        /// <summary>Asynchronously iterates through an enumerable of tasks.</summary>
+        /// <param name="factory">The target factory.</param>
+        /// <param name="source">The enumerable containing the tasks to be iterated through.</param>
+        /// <param name="state">The asynchronous state for the returned Task.</param>
+        /// <param name="cancellationToken">The cancellation token used to cancel the iteration.</param>
+        /// <returns>A Task that represents the complete asynchronous operation.</returns>
+        public static Task Iterate(
+            this TaskFactory factory,
+            IEnumerable<object> source, object state,
+            CancellationToken cancellationToken)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            return Iterate(factory, source, state, cancellationToken, factory.CreationOptions, factory.GetTargetScheduler());
+        }
+
+        /// <summary>Asynchronously iterates through an enumerable of tasks.</summary>
+        /// <param name="factory">The target factory.</param>
+        /// <param name="source">The enumerable containing the tasks to be iterated through.</param>
+        /// <param name="state">The asynchronous state for the returned Task.</param>
+        /// <param name="creationOptions">Options that control the task's behavior.</param>
+        /// <returns>A Task that represents the complete asynchronous operation.</returns>
+        public static Task Iterate(
+            this TaskFactory factory,
+            IEnumerable<object> source, object state,
+            TaskCreationOptions creationOptions)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            return Iterate(factory, source, state, factory.CancellationToken, creationOptions, factory.GetTargetScheduler());
+        }
+
+        /// <summary>Asynchronously iterates through an enumerable of tasks.</summary>
+        /// <param name="factory">The target factory.</param>
+        /// <param name="source">The enumerable containing the tasks to be iterated through.</param>
+        /// <param name="state">The asynchronous state for the returned Task.</param>
+        /// <param name="scheduler">The scheduler to which tasks will be scheduled.</param>
+        /// <returns>A Task that represents the complete asynchronous operation.</returns>
+        public static Task Iterate(
+            this TaskFactory factory,
+            IEnumerable<object> source, object state,
+            TaskScheduler scheduler)
+        {
+            if (factory == null) throw new ArgumentNullException("factory");
+            return Iterate(factory, source, state, factory.CancellationToken, factory.CreationOptions, scheduler);
+        }
+
+        /// <summary>Asynchronously iterates through an enumerable of tasks.</summary>
+        /// <param name="factory">The target factory.</param>
+        /// <param name="source">The enumerable containing the tasks to be iterated through.</param>
+        /// <param name="state">The asynchronous state for the returned Task.</param>
+        /// <param name="cancellationToken">The cancellation token used to cancel the iteration.</param>
+        /// <param name="creationOptions">Options that control the task's behavior.</param>
+        /// <param name="scheduler">The scheduler to which tasks will be scheduled.</param>
+        /// <returns>A Task that represents the complete asynchronous operation.</returns>
+        public static Task Iterate(
+            this TaskFactory factory,
+            IEnumerable<object> source, object state, 
+            CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler)
+        {
+            // Validate/update parameters
+            if (factory == null) throw new ArgumentNullException("factory");
+            if (source == null) throw new ArgumentNullException("asyncIterator");
+            if (scheduler == null) throw new ArgumentNullException("scheduler");
+
+            // Get an enumerator from the enumerable
+            var enumerator = source.GetEnumerator();
+            if (enumerator == null) throw new InvalidOperationException("Invalid enumerable - GetEnumerator returned null");
+
+            // Create the task to be returned to the caller.  And ensure
+            // that when everything is done, the enumerator is cleaned up.
+            var trs = new TaskCompletionSource<object>(state, creationOptions);
+            trs.Task.ContinueWith(_ => enumerator.Dispose(), CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
+
+            // This will be called every time more work can be done.
+            Action<Task> recursiveBody = null;
+            recursiveBody = antecedent =>
+            {
+                try
+                {
+                    // If we should continue iterating and there's more to iterate
+                    // over, create a continuation to continue processing.  We only
+                    // want to continue processing once the current Task (as yielded
+                    // from the enumerator) is complete.
+                    if (enumerator.MoveNext())
+                    {
+                        var nextItem = enumerator.Current;
+                        
+                        // If we got a Task, continue from it to continue iterating
+                        if (nextItem is Task)
+                        {
+                            var nextTask = (Task)nextItem;
+                            /**/ nextTask.IgnoreExceptions(); // TODO: Is this a good idea?
+                            nextTask.ContinueWith(recursiveBody).IgnoreExceptions();
+                        }
+                            // If we got a scheduler, continue iterating under the new scheduler,
+                            // enabling hopping between contexts.
+                        else if (nextItem is TaskScheduler)
+                        {
+                            Task.Factory.StartNew(() => recursiveBody(null), CancellationToken.None, TaskCreationOptions.None, (TaskScheduler)nextItem).IgnoreExceptions();
+                        }
+                            // Anything else is invalid
+                        else trs.TrySetException(new InvalidOperationException("Task or TaskScheduler object expected in Iterate"));
+                    }
+
+                    // Otherwise, we're done!
+                    else trs.TrySetResult(null);
+                }
+                // If MoveNext throws an exception, propagate that to the user,
+                // either as cancellation or as a fault
+                catch (Exception exc) 
+                {
+                    var oce = exc as OperationCanceledException;
+                    if (oce != null && oce.CancellationToken == cancellationToken)
+                    {
+                        trs.TrySetCanceled();
+                    }
+                    else trs.TrySetException(exc); 
+                }
+            };
+
+            // Get things started by launching the first task
+            factory.StartNew(() => recursiveBody(null), CancellationToken.None, TaskCreationOptions.None, scheduler).IgnoreExceptions();
+            
+            // Return the representative task to the user
+            return trs.Task;
+        }
+        #endregion
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskFactoryExtensions/TaskFactoryExtensions_TrackedSequence.cs b/trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskFactoryExtensions/TaskFactoryExtensions_TrackedSequence.cs
new file mode 100644 (file)
index 0000000..bbfb316
--- /dev/null
@@ -0,0 +1,63 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: TaskFactoryExtensions_TrackedSequence.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Generic;
+
+namespace System.Threading.Tasks
+{
+    public static partial class TaskFactoryExtensions
+    {
+        /// <summary>Asynchronously executes a sequence of tasks, maintaining a list of all tasks processed.</summary>
+        /// <param name="factory">The TaskFactory to use to create the task.</param>
+        /// <param name="functions">
+        /// The functions that generate the tasks through which to iterate sequentially.
+        /// Iteration will cease if a task faults.
+        /// </param>
+        /// <returns>A Task that will return the list of tracked tasks iterated.</returns>
+        public static Task<IList<Task>> TrackedSequence(this TaskFactory factory, params Func<Task> [] functions)
+        {
+            var tcs = new TaskCompletionSource<IList<Task>>();
+            factory.Iterate(TrackedSequenceInternal(functions, tcs));
+            return tcs.Task;
+        }
+
+        /// <summary>Creates the enumerable to iterate through with Iterate.</summary>
+        /// <param name="functions">
+        /// The functions that generate the tasks through which to iterate sequentially.
+        /// Iteration will cease if a task faults.
+        /// </param>
+        /// <param name="tcs">The TaskCompletionSource to resolve with the asynchronous results.</param>
+        /// <returns>The enumerable through which to iterate.</returns>
+        private static IEnumerable<Task> TrackedSequenceInternal(
+            IEnumerable<Func<Task>> functions, TaskCompletionSource<IList<Task>> tcs)
+        {
+            // Store a list of all tasks iterated through.  This will be provided
+            // to the resulting task when we're done.
+            var tasks = new List<Task>();
+
+            // Run seqeuentially through all of the provided functions.
+            foreach (var func in functions)
+            {
+                // Get the next task.  If we get an exception while trying to do so,
+                // an invalid function was provided.  Fault the TCS and break out.
+                Task nextTask = null;
+                try { nextTask = func(); } catch (Exception exc) { tcs.TrySetException(exc); }
+                if (nextTask == null) yield break;
+
+                // Store the task that was generated and yield it from the sequence.  If the task
+                // faults, break out of the loop so that no more tasks are processed.
+                tasks.Add(nextTask);
+                yield return nextTask;
+                if (nextTask.IsFaulted) break;
+            }
+
+            // We're done.  Transfer all tasks we iterated through.
+            tcs.TrySetResult(tasks);
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskSchedulerExtensions.cs b/trunk/Libraries/ParallelExtensionsExtras/Extensions/TaskSchedulerExtensions.cs
new file mode 100644 (file)
index 0000000..1861895
--- /dev/null
@@ -0,0 +1,55 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: TaskSchedulerExtensions.cs
+//
+//--------------------------------------------------------------------------
+
+namespace System.Threading.Tasks
+{
+    /// <summary>Extension methods for TaskScheduler.</summary>
+    public static class TaskSchedulerExtensions
+    {
+        /// <summary>Gets a SynchronizationContext that targets this TaskScheduler.</summary>
+        /// <param name="scheduler">The target scheduler.</param>
+        /// <returns>A SynchronizationContext that targets this scheduler.</returns>
+        public static SynchronizationContext ToSynchronizationContext(this TaskScheduler scheduler)
+        {
+            return new TaskSchedulerSynchronizationContext(scheduler);
+        }
+
+        /// <summary>Provides a SynchronizationContext wrapper for a TaskScheduler.</summary>
+        private sealed class TaskSchedulerSynchronizationContext : SynchronizationContext
+        {
+            /// <summary>The scheduler.</summary>
+            private TaskScheduler _scheduler;
+
+            /// <summary>Initializes the context with the specified scheduler.</summary>
+            /// <param name="scheduler">The scheduler to target.</param>
+            internal TaskSchedulerSynchronizationContext(TaskScheduler scheduler)
+            {
+                if (scheduler == null) throw new ArgumentNullException("scheduler");
+                _scheduler = scheduler;
+            }
+
+            /// <summary>Dispatches an asynchronous message to the synchronization context.</summary>
+            /// <param name="d">The System.Threading.SendOrPostCallback delegate to call.</param>
+            /// <param name="state">The object passed to the delegate.</param>
+            public override void Post(SendOrPostCallback d, object state)
+            {
+                Task.Factory.StartNew(() => d(state), CancellationToken.None, TaskCreationOptions.None, _scheduler);
+            }
+
+            /// <summary>Dispatches a synchronous message to the synchronization context.</summary>
+            /// <param name="d">The System.Threading.SendOrPostCallback delegate to call.</param>
+            /// <param name="state">The object passed to the delegate.</param>
+            public override void Send(SendOrPostCallback d, object state)
+            {
+                Task t = new Task(() => d(state));
+                t.RunSynchronously(_scheduler);
+                t.Wait();
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_Common.cs b/trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_Common.cs
new file mode 100644 (file)
index 0000000..50ddaf4
--- /dev/null
@@ -0,0 +1,21 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: ParallelAlgorithms_Common.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Threading.Tasks;
+
+namespace System.Threading.Algorithms
+{
+    /// <summary>
+    /// Provides parallelized algorithms for common operations.
+    /// </summary>
+    public static partial class ParallelAlgorithms
+    {
+        // Default, shared instance of the ParallelOptions class.  This should not be modified.
+        private static ParallelOptions s_defaultParallelOptions = new ParallelOptions();
+    }
+}
diff --git a/trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_Filter.cs b/trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_Filter.cs
new file mode 100644 (file)
index 0000000..a50bc63
--- /dev/null
@@ -0,0 +1,49 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: ParallelAlgorithms_Filter.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace System.Threading.Algorithms
+{
+    public static partial class ParallelAlgorithms
+    {
+        /// <summary>Filters an input list, running a predicate over each element of the input.</summary>
+        /// <typeparam name="T">Specifies the type of data in the list.</typeparam>
+        /// <param name="input">The list to be filtered.</param>
+        /// <param name="predicate">The predicate to use to determine which elements pass.</param>
+        /// <returns>A new list containing all those elements from the input that passed the filter.</returns>
+        public static IList<T> Filter<T>(IList<T> input, Func<T, Boolean> predicate)
+        {
+            return Filter(input, s_defaultParallelOptions, predicate);
+        }
+
+        /// <summary>Filters an input list, running a predicate over each element of the input.</summary>
+        /// <typeparam name="T">Specifies the type of data in the list.</typeparam>
+        /// <param name="input">The list to be filtered.</param>
+        /// <param name="parallelOptions">Options to use for the execution of this filter.</param>
+        /// <param name="predicate">The predicate to use to determine which elements pass.</param>
+        /// <returns>A new list containing all those elements from the input that passed the filter.</returns>
+        public static IList<T> Filter<T>(IList<T> input, ParallelOptions parallelOptions, Func<T, Boolean> predicate)
+        {
+            if (input == null) throw new ArgumentNullException("input");
+            if (parallelOptions == null) throw new ArgumentNullException("parallelOptions");
+            if (predicate == null) throw new ArgumentNullException("predicate");
+
+            var results = new List<T>(input.Count);
+            Parallel.For(0, input.Count, parallelOptions, () => new List<T>(input.Count), (i, loop, localList) =>
+            {
+                var item = input[i];
+                if (predicate(item)) localList.Add(item);
+                return localList;
+            },
+            localList => { lock (results) results.AddRange(localList); });
+            return results;
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_For.cs b/trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_For.cs
new file mode 100644 (file)
index 0000000..4351520
--- /dev/null
@@ -0,0 +1,68 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: ParallelAlgorithms_For.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Numerics;
+using System.Threading.Tasks;
+
+namespace System.Threading.Algorithms
+{
+    public static partial class ParallelAlgorithms
+    {
+        /// <summary>Executes a for loop in which iterations may run in parallel.</summary>
+        /// <param name="fromInclusive">The start index, inclusive.</param>
+        /// <param name="toExclusive">The end index, exclusive.</param>
+        /// <param name="body">The delegate that is invoked once per iteration.</param>
+        public static void For(BigInteger fromInclusive, BigInteger toExclusive, Action<BigInteger> body)
+        {
+            For(fromInclusive, toExclusive, s_defaultParallelOptions, body);
+        }
+
+        /// <summary>Executes a for loop in which iterations may run in parallel.</summary>
+        /// <param name="fromInclusive">The start index, inclusive.</param>
+        /// <param name="toExclusive">The end index, exclusive.</param>
+        /// <param name="options">A System.Threading.Tasks.ParallelOptions instance that configures the behavior of this operation.</param>
+        /// <param name="body">The delegate that is invoked once per iteration.</param>
+        public static void For(BigInteger fromInclusive, BigInteger toExclusive, ParallelOptions options, Action<BigInteger> body)
+        {
+            // Determine how many iterations to run...
+            var range = toExclusive - fromInclusive;
+
+            // ... and run them.
+            if (range <= 0)
+            {
+                // If there's nothing to do, bail
+                return;
+            }
+                // Fast path
+            else if (range <= Int64.MaxValue)
+            {
+                // If the range is within the realm of Int64, we'll delegate to Parallel.For's Int64 overloads.
+                // Iterate from 0 to range, and then call the user-provided body with the scaled-back value.
+                Parallel.For(0, (long)range, options, i => body(i + fromInclusive));
+            }
+                // Slower path
+            else
+            {
+                // For a range larger than Int64.MaxValue, we'll rely on an enumerable of BigInteger.
+                // We create a C# iterator that yields all of the BigInteger values in the requested range
+                // and then ForEach over that range.
+                Parallel.ForEach(Range(fromInclusive, toExclusive), options, body);
+            }
+        }
+
+        /// <summary>Creates an enumerable that iterates the range [fromInclusive, toExclusive).</summary>
+        /// <param name="fromInclusive">The lower bound, inclusive.</param>
+        /// <param name="toExclusive">The upper bound, exclusive.</param>
+        /// <returns>The enumerable of the range.</returns>
+        private static IEnumerable<BigInteger> Range(BigInteger fromInclusive, BigInteger toExclusive)
+        {
+            for (var i = fromInclusive; i < toExclusive; i++) yield return i;
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_ForRange.cs b/trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_ForRange.cs
new file mode 100644 (file)
index 0000000..5933a40
--- /dev/null
@@ -0,0 +1,236 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: ParallelAlgorithms_ForRange.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Concurrent;
+using System.Threading.Tasks;
+
+namespace System.Threading.Algorithms
+{
+    public static partial class ParallelAlgorithms
+    {
+        #region Int32, No Options
+        /// <summary>Executes a for loop over ranges in which iterations may run in parallel. </summary>
+        /// <param name="fromInclusive">The start index, inclusive.</param>
+        /// <param name="toExclusive">The end index, exclusive.</param>
+        /// <param name="body">The delegate that is invoked once per range.</param>
+        /// <returns>A ParallelLoopResult structure that contains information on what portion of the loop completed.</returns>
+        public static ParallelLoopResult ForRange(
+            int fromInclusive, int toExclusive, 
+            Action<int, int> body)
+        {
+            return ForRange(fromInclusive, toExclusive, s_defaultParallelOptions, body);
+        }
+
+        /// <summary>Executes a for loop over ranges in which iterations may run in parallel. </summary>
+        /// <param name="fromInclusive">The start index, inclusive.</param>
+        /// <param name="toExclusive">The end index, exclusive.</param>
+        /// <param name="body">The delegate that is invoked once per range.</param>
+        /// <returns>A ParallelLoopResult structure that contains information on what portion of the loop completed.</returns>
+        public static ParallelLoopResult ForRange(
+            int fromInclusive, int toExclusive,
+            Action<int, int, ParallelLoopState> body)
+        {
+            return ForRange(fromInclusive, toExclusive, s_defaultParallelOptions, body);
+        }
+
+        /// <summary>Executes a for loop over ranges in which iterations may run in parallel. </summary>
+        /// <param name="fromInclusive">The start index, inclusive.</param>
+        /// <param name="toExclusive">The end index, exclusive.</param>
+        /// <param name="localInit">The function delegate that returns the initial state of the local data for each thread.</param>
+        /// <param name="body">The delegate that is invoked once per range.</param>
+        /// <param name="localFinally">The delegate that performs a final action on the local state of each thread.</param>
+        /// <returns>A ParallelLoopResult structure that contains information on what portion of the loop completed.</returns>
+        public static ParallelLoopResult ForRange<TLocal>(
+            int fromInclusive, int toExclusive,
+            Func<TLocal> localInit,
+            Func<int, int, ParallelLoopState, TLocal, TLocal> body,
+            Action<TLocal> localFinally)
+        {
+            return ForRange(fromInclusive, toExclusive, s_defaultParallelOptions,
+                localInit, body, localFinally);
+        }
+        #endregion
+
+        #region Int64, No Options
+        /// <summary>Executes a for loop over ranges in which iterations may run in parallel. </summary>
+        /// <param name="fromInclusive">The start index, inclusive.</param>
+        /// <param name="toExclusive">The end index, exclusive.</param>
+        /// <param name="body">The delegate that is invoked once per range.</param>
+        /// <returns>A ParallelLoopResult structure that contains information on what portion of the loop completed.</returns>
+        public static ParallelLoopResult ForRange(
+            long fromInclusive, long toExclusive,
+            Action<long, long> body)
+        {
+            return ForRange(fromInclusive, toExclusive, s_defaultParallelOptions, body);
+        }
+
+        /// <summary>Executes a for loop over ranges in which iterations may run in parallel. </summary>
+        /// <param name="fromInclusive">The start index, inclusive.</param>
+        /// <param name="toExclusive">The end index, exclusive.</param>
+        /// <param name="body">The delegate that is invoked once per range.</param>
+        /// <returns>A ParallelLoopResult structure that contains information on what portion of the loop completed.</returns>
+        public static ParallelLoopResult ForRange(
+            long fromInclusive, long toExclusive,
+            Action<long, long, ParallelLoopState> body)
+        {
+            return ForRange(fromInclusive, toExclusive, s_defaultParallelOptions, body);
+        }
+
+        /// <summary>Executes a for loop over ranges in which iterations may run in parallel. </summary>
+        /// <param name="fromInclusive">The start index, inclusive.</param>
+        /// <param name="toExclusive">The end index, exclusive.</param>
+        /// <param name="localInit">The function delegate that returns the initial state of the local data for each thread.</param>
+        /// <param name="body">The delegate that is invoked once per range.</param>
+        /// <param name="localFinally">The delegate that performs a final action on the local state of each thread.</param>
+        /// <returns>A ParallelLoopResult structure that contains information on what portion of the loop completed.</returns>
+        public static ParallelLoopResult ForRange<TLocal>(
+            long fromInclusive, long toExclusive,
+            Func<TLocal> localInit,
+            Func<long, long, ParallelLoopState, TLocal, TLocal> body,
+            Action<TLocal> localFinally)
+        {
+            return ForRange(fromInclusive, toExclusive, s_defaultParallelOptions,
+                localInit, body, localFinally);
+        }
+        #endregion
+
+        #region Int32, Parallel Options
+        /// <summary>Executes a for loop over ranges in which iterations may run in parallel. </summary>
+        /// <param name="fromInclusive">The start index, inclusive.</param>
+        /// <param name="toExclusive">The end index, exclusive.</param>
+        /// <param name="parallelOptions">A ParallelOptions instance that configures the behavior of this operation.</param>
+        /// <param name="body">The delegate that is invoked once per range.</param>
+        /// <returns>A ParallelLoopResult structure that contains information on what portion of the loop completed.</returns>
+        public static ParallelLoopResult ForRange(
+            int fromInclusive, int toExclusive,
+            ParallelOptions parallelOptions,
+            Action<int, int> body)
+        {
+            if (parallelOptions == null) throw new ArgumentNullException("parallelOptions");
+            if (body == null) throw new ArgumentNullException("body");
+
+            return Parallel.ForEach(Partitioner.Create(fromInclusive, toExclusive), parallelOptions, range =>
+            {
+                body(range.Item1, range.Item2);
+            });
+        }
+
+        /// <summary>Executes a for loop over ranges in which iterations may run in parallel. </summary>
+        /// <param name="fromInclusive">The start index, inclusive.</param>
+        /// <param name="toExclusive">The end index, exclusive.</param>
+        /// <param name="parallelOptions">A ParallelOptions instance that configures the behavior of this operation.</param>
+        /// <param name="body">The delegate that is invoked once per range.</param>
+        /// <returns>A ParallelLoopResult structure that contains information on what portion of the loop completed.</returns>
+        public static ParallelLoopResult ForRange(
+            int fromInclusive, int toExclusive,
+            ParallelOptions parallelOptions,
+            Action<int, int, ParallelLoopState> body)
+        {
+            if (parallelOptions == null) throw new ArgumentNullException("parallelOptions");
+            if (body == null) throw new ArgumentNullException("body");
+
+            return Parallel.ForEach(Partitioner.Create(fromInclusive, toExclusive), parallelOptions, (range, loopState) =>
+            {
+                body(range.Item1, range.Item2, loopState);
+            });
+        }
+
+        /// <summary>Executes a for loop over ranges in which iterations may run in parallel. </summary>
+        /// <param name="fromInclusive">The start index, inclusive.</param>
+        /// <param name="toExclusive">The end index, exclusive.</param>
+        /// <param name="localInit">The function delegate that returns the initial state of the local data for each thread.</param>
+        /// <param name="body">The delegate that is invoked once per range.</param>
+        /// <param name="localFinally">The delegate that performs a final action on the local state of each thread.</param>
+        /// <returns>A ParallelLoopResult structure that contains information on what portion of the loop completed.</returns>
+        public static ParallelLoopResult ForRange<TLocal>(
+            int fromInclusive, int toExclusive,
+            ParallelOptions parallelOptions,
+            Func<TLocal> localInit,
+            Func<int, int, ParallelLoopState, TLocal, TLocal> body,
+            Action<TLocal> localFinally)
+        {
+            if (parallelOptions == null) throw new ArgumentNullException("parallelOptions");
+            if (localInit == null) throw new ArgumentNullException("localInit");
+            if (body == null) throw new ArgumentNullException("body");
+            if (localFinally == null) throw new ArgumentNullException("localFinally");
+
+            return Parallel.ForEach(Partitioner.Create(fromInclusive, toExclusive), parallelOptions, localInit, (range, loopState, x) =>
+            {
+                return body(range.Item1, range.Item2, loopState, x);
+            }, localFinally);
+        }
+        #endregion
+
+        #region Int64, Parallel Options
+        /// <summary>Executes a for loop over ranges in which iterations may run in parallel. </summary>
+        /// <param name="fromInclusive">The start index, inclusive.</param>
+        /// <param name="toExclusive">The end index, exclusive.</param>
+        /// <param name="parallelOptions">A ParallelOptions instance that configures the behavior of this operation.</param>
+        /// <param name="body">The delegate that is invoked once per range.</param>
+        /// <returns>A ParallelLoopResult structure that contains information on what portion of the loop completed.</returns>
+        public static ParallelLoopResult ForRange(
+            long fromInclusive, long toExclusive,
+            ParallelOptions parallelOptions,
+            Action<long, long> body)
+        {
+            if (parallelOptions == null) throw new ArgumentNullException("parallelOptions");
+            if (body == null) throw new ArgumentNullException("body");
+
+            return Parallel.ForEach(Partitioner.Create(fromInclusive, toExclusive), parallelOptions, range =>
+            {
+                body(range.Item1, range.Item2);
+            });
+        }
+
+        /// <summary>Executes a for loop over ranges in which iterations may run in parallel. </summary>
+        /// <param name="fromInclusive">The start index, inclusive.</param>
+        /// <param name="toExclusive">The end index, exclusive.</param>
+        /// <param name="parallelOptions">A ParallelOptions instance that configures the behavior of this operation.</param>
+        /// <param name="body">The delegate that is invoked once per range.</param>
+        /// <returns>A ParallelLoopResult structure that contains information on what portion of the loop completed.</returns>
+        public static ParallelLoopResult ForRange(
+            long fromInclusive, long toExclusive,
+            ParallelOptions parallelOptions,
+            Action<long, long, ParallelLoopState> body)
+        {
+            if (parallelOptions == null) throw new ArgumentNullException("parallelOptions");
+            if (body == null) throw new ArgumentNullException("body");
+
+            return Parallel.ForEach(Partitioner.Create(fromInclusive, toExclusive), parallelOptions, (range, loopState) =>
+            {
+                body(range.Item1, range.Item2, loopState);
+            });
+        }
+
+        /// <summary>Executes a for loop over ranges in which iterations may run in parallel. </summary>
+        /// <param name="fromInclusive">The start index, inclusive.</param>
+        /// <param name="toExclusive">The end index, exclusive.</param>
+        /// <param name="localInit">The function delegate that returns the initial state of the local data for each thread.</param>
+        /// <param name="body">The delegate that is invoked once per range.</param>
+        /// <param name="localFinally">The delegate that performs a final action on the local state of each thread.</param>
+        /// <returns>A ParallelLoopResult structure that contains information on what portion of the loop completed.</returns>
+        public static ParallelLoopResult ForRange<TLocal>(
+            long fromInclusive, long toExclusive,
+            ParallelOptions parallelOptions,
+            Func<TLocal> localInit,
+            Func<long, long, ParallelLoopState, TLocal, TLocal> body,
+            Action<TLocal> localFinally)
+        {
+            if (parallelOptions == null) throw new ArgumentNullException("parallelOptions");
+            if (localInit == null) throw new ArgumentNullException("localInit");
+            if (body == null) throw new ArgumentNullException("body");
+            if (localFinally == null) throw new ArgumentNullException("localFinally");
+
+            return Parallel.ForEach(Partitioner.Create(fromInclusive, toExclusive), parallelOptions, localInit, (range, loopState, x) =>
+            {
+                return body(range.Item1, range.Item2, loopState, x);
+            }, localFinally);
+        }
+        #endregion
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_Map.cs b/trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_Map.cs
new file mode 100644 (file)
index 0000000..722d95b
--- /dev/null
@@ -0,0 +1,45 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: ParallelAlgorithms_Map.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace System.Threading.Algorithms
+{
+    public static partial class ParallelAlgorithms
+    {
+        /// <summary>Executes a map operation, converting an input list into an output list, in parallel.</summary>
+        /// <typeparam name="TInput">Specifies the type of the input data.</typeparam>
+        /// <typeparam name="TOutput">Specifies the type of the output data.</typeparam>
+        /// <param name="input">The input list to be mapped used the transform function.</param>
+        /// <param name="transform">The transform function to use to map the input data to the output data.</param>
+        /// <returns>The output data, transformed using the transform function.</returns>
+        public static TOutput[] Map<TInput, TOutput>(IList<TInput> input, Func<TInput, TOutput> transform)
+        {
+            return Map(input, s_defaultParallelOptions, transform);
+        }
+
+        /// <summary>Executes a map operation, converting an input list into an output list, in parallel.</summary>
+        /// <typeparam name="TInput">Specifies the type of the input data.</typeparam>
+        /// <typeparam name="TOutput">Specifies the type of the output data.</typeparam>
+        /// <param name="input">The input list to be mapped used the transform function.</param>
+        /// <param name="parallelOptions">A ParallelOptions instance that configures the behavior of this operation.</param>
+        /// <param name="transform">The transform function to use to map the input data to the output data.</param>
+        /// <returns>The output data, transformed using the transform function.</returns>
+        public static TOutput[] Map<TInput, TOutput>(IList<TInput> input, ParallelOptions parallelOptions, Func<TInput, TOutput> transform)
+        {
+            if (input == null) throw new ArgumentNullException("input");
+            if (parallelOptions == null) throw new ArgumentNullException("parallelOptions");
+            if (transform == null) throw new ArgumentNullException("transform");
+
+            var output = new TOutput[input.Count];
+            Parallel.For(0, input.Count, parallelOptions, i => output[i] = transform(input[i]));
+            return output;
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_Reduce.cs b/trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_Reduce.cs
new file mode 100644 (file)
index 0000000..649a99f
--- /dev/null
@@ -0,0 +1,93 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: ParallelAlgorithms_Reduce.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace System.Threading.Algorithms
+{
+    public static partial class ParallelAlgorithms
+    {
+        /// <summary>Reduces the input data using the specified aggregation operation.</summary>
+        /// <typeparam name="T">Specifies the type of data being aggregated.</typeparam>
+        /// <param name="input">The input data to be reduced.</param>
+        /// <param name="seed">The seed to use to initialize the operation; this seed may be used multiple times.</param>
+        /// <param name="associativeCommutativeOperation">The reduction operation.</param>
+        /// <returns>The reduced value.</returns>
+        public static T Reduce<T>(
+            IList<T> input, T seed, 
+            Func<T, T, T> associativeCommutativeOperation)
+        {
+            return Reduce(input, s_defaultParallelOptions, seed, associativeCommutativeOperation);
+        }
+
+        /// <summary>Reduces the input data using the specified aggregation operation.</summary>
+        /// <typeparam name="T">Specifies the type of data being aggregated.</typeparam>
+        /// <param name="input">The input data to be reduced.</param>
+        /// <param name="parallelOptions">A ParallelOptions instance that configures the behavior of this operation.</param>
+        /// <param name="seed">The seed to use to initialize the operation; this seed may be used multiple times.</param>
+        /// <param name="associativeCommutativeOperation">The reduction operation.</param>
+        /// <returns>The reduced value.</returns>
+        public static T Reduce<T>(
+            IList<T> input, ParallelOptions parallelOptions,
+            T seed, Func<T, T, T> associativeCommutativeOperation)
+        {
+            if (input == null) throw new ArgumentNullException("input");
+            return Reduce(0, input.Count, parallelOptions, i => input[i], seed, associativeCommutativeOperation);
+        }
+
+        /// <summary>Reduces the input range using the specified aggregation operation.</summary>
+        /// <typeparam name="T">Specifies the type of data being aggregated.</typeparam>
+        /// <param name="fromInclusive">The start index, inclusive.</param>
+        /// <param name="toExclusive">The end index, exclusive.</param>
+        /// <param name="mapOperation">The function used to retrieve the data to be reduced for a given index.</param>
+        /// <param name="seed">The seed to use to initialize the operation; this seed may be used multiple times.</param>
+        /// <param name="associativeCommutativeOperation">The reduction operation.</param>
+        /// <returns>The reduced value.</returns>
+        public static T Reduce<T>(
+            int fromInclusive, int toExclusive, 
+            Func<int, T> mapOperation, T seed, Func<T, T, T> associativeCommutativeOperation)
+        {
+            return Reduce(fromInclusive, toExclusive, s_defaultParallelOptions, mapOperation, seed, associativeCommutativeOperation);
+        }
+
+        /// <summary>Reduces the input range using the specified aggregation operation.</summary>
+        /// <typeparam name="T">Specifies the type of data being aggregated.</typeparam>
+        /// <param name="fromInclusive">The start index, inclusive.</param>
+        /// <param name="toExclusive">The end index, exclusive.</param>
+        /// <param name="parallelOptions">A ParallelOptions instance that configures the behavior of this operation.</param>
+        /// <param name="mapOperation">The function used to retrieve the data to be reduced for a given index.</param>
+        /// <param name="seed">The seed to use to initialize the operation; this seed may be used multiple times.</param>
+        /// <param name="associativeCommutativeOperation">The reduction operation.</param>
+        /// <returns>The reduced value.</returns>
+        public static T Reduce<T>(
+            int fromInclusive, int toExclusive, ParallelOptions parallelOptions, 
+            Func<int, T> mapOperation, T seed, Func<T, T, T> associativeCommutativeOperation)
+        {
+            if (parallelOptions == null) throw new ArgumentNullException("parallelOptions");
+            if (mapOperation == null) throw new ArgumentNullException("mapOperation");
+            if (associativeCommutativeOperation == null) throw new ArgumentNullException("associativeCommutativeOperation");
+            if (toExclusive < fromInclusive) throw new ArgumentOutOfRangeException("toExclusive");
+
+            object obj = new object(); // used as a monitor for the final reduction
+            T result = seed; // accumulator for final reduction
+
+            // Reduce in parallel
+            Parallel.For(fromInclusive, toExclusive, parallelOptions,
+                // Initialize each thread with the user-specified seed
+                () => seed,
+                // Map the current index to a value and aggregate that value into the local reduction
+                (i, loop, localResult) => associativeCommutativeOperation(mapOperation(i), localResult),
+                // Combine all of the local reductions
+                localResult => { lock (obj) result = associativeCommutativeOperation(localResult, result); });
+
+            // Return the final result
+            return result;
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_Scan.cs b/trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_Scan.cs
new file mode 100644 (file)
index 0000000..caf908d
--- /dev/null
@@ -0,0 +1,219 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: ParallelAlgorithms_Scan.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace System.Threading.Algorithms
+{
+    public static partial class ParallelAlgorithms
+    {
+        /// <summary>Computes a parallel prefix scan over the source enumerable using the specified function.</summary>
+        /// <typeparam name="T">The type of the data in the source.</typeparam>
+        /// <param name="source">The source data over which a prefix scan should be computed.</param>
+        /// <param name="function">The function to use for the scan.</param>
+        /// <returns>The results of the scan operation.</returns>
+        /// <remarks>
+        /// For very small functions, such as additions, an implementation targeted
+        /// at the relevant type and operation will perform significantly better than
+        /// this generalized implementation.
+        /// </remarks>
+        public static T[] Scan<T>(IEnumerable<T> source, Func<T, T, T> function)
+        {
+            return Scan(source, function, loadBalance: false);
+        }
+
+        /// <summary>Computes a parallel prefix scan over the source enumerable using the specified function.</summary>
+        /// <typeparam name="T">The type of the data in the source.</typeparam>
+        /// <param name="source">The source data over which a prefix scan should be computed.</param>
+        /// <param name="function">The function to use for the scan.</param>
+        /// <param name="loadBalance">Whether to load-balance during process.</param>
+        /// <returns>The results of the scan operation.</returns>
+        /// <remarks>
+        /// For very small functions, such as additions, an implementation targeted
+        /// at the relevant type and operation will perform significantly better than
+        /// this generalized implementation.
+        /// </remarks>
+        public static T[] Scan<T>(IEnumerable<T> source, Func<T, T, T> function, bool loadBalance)
+        {
+            // Validate arguments
+            if (source == null) throw new ArgumentNullException("source");
+
+            // Create output copy
+            var output = source.ToArray();
+
+            // Do the prefix scan in-place on the copy and return the results
+            ScanInPlace(output, function, loadBalance);
+            return output;
+        }
+
+        /// <summary>Computes a parallel prefix scan in-place on an array using the specified function.</summary>
+        /// <typeparam name="T">The type of the data in the source.</typeparam>
+        /// <param name="data">The data over which a prefix scan should be computed. Upon exit, stores the results.</param>
+        /// <param name="function">The function to use for the scan.</param>
+        /// <returns>The results of the scan operation.</returns>
+        /// <remarks>
+        /// For very small functions, such as additions, an implementation targeted
+        /// at the relevant type and operation will perform significantly better than
+        /// this generalized implementation.
+        /// </remarks>
+        public static void ScanInPlace<T>(T[] data, Func<T, T, T> function)
+        {
+            ScanInPlace(data, function, loadBalance:false);
+        }
+
+        /// <summary>Computes a parallel prefix scan in-place on an array using the specified function.</summary>
+        /// <typeparam name="T">The type of the data in the source.</typeparam>
+        /// <param name="data">The data over which a prefix scan should be computed. Upon exit, stores the results.</param>
+        /// <param name="function">The function to use for the scan.</param>
+        /// <param name="loadBalance">Whether to load-balance during process.</param>
+        /// <returns>The results of the scan operation.</returns>
+        /// <remarks>
+        /// For very small functions, such as additions, an implementation targeted
+        /// at the relevant type and operation will perform significantly better than
+        /// this generalized implementation.
+        /// </remarks>
+        public static void ScanInPlace<T>(T [] data, Func<T, T, T> function, bool loadBalance)
+        {
+            // Validate arguments
+            if (data == null) throw new ArgumentNullException("data");
+            if (function == null) throw new ArgumentNullException("function");
+
+            // Do the prefix scan in-place and return the results.  This implementation
+            // of parallel prefix scan ends up executing the function twice as many
+            // times as the sequential implementation.  Thus, only if we have more than 2 cores
+            // will the parallel version have a chance of running faster than sequential.
+            if (Environment.ProcessorCount <= 2)
+            {
+                InclusiveScanInPlaceSerial(data, function, 0, data.Length, 1);
+            }
+            else if (loadBalance)
+            {
+                InclusiveScanInPlaceWithLoadBalancingParallel(data, function, 0, data.Length, 1);
+            }
+            else // parallel, non-loadbalance
+            {
+                InclusiveScanInPlaceParallel(data, function);
+            }
+        }
+
+        /// <summary>Computes a sequential prefix scan over the array using the specified function.</summary>
+        /// <typeparam name="T">The type of the data in the array.</typeparam>
+        /// <param name="arr">The data, which will be overwritten with the computed prefix scan.</param>
+        /// <param name="function">The function to use for the scan.</param>
+        /// <param name="arrStart">The start of the data in arr over which the scan is being computed.</param>
+        /// <param name="arrLength">The length of the data in arr over which the scan is being computed.</param>
+        /// <param name="skip">The inclusive distance between elements over which the scan is being computed.</param>
+        /// <remarks>No parameter validation is performed.</remarks>
+        private static void InclusiveScanInPlaceSerial<T>(T[] arr, Func<T, T, T> function, int arrStart, int arrLength, int skip)
+        {
+            for (int i = arrStart; i + skip < arrLength; i += skip)
+            {
+                arr[i + skip] = function(arr[i], arr[i + skip]);
+            }
+        }
+
+        /// <summary>Computes a sequential exclusive prefix scan over the array using the specified function.</summary>
+        /// <param name="arr">The data, which will be overwritten with the computed prefix scan.</param>
+        /// <param name="function">The function to use for the scan.</param>
+        /// <param name="lowerBoundInclusive">The inclusive lower bound of the array at which to start the scan.</param>
+        /// <param name="upperBoundExclusive">The exclusive upper bound of the array at which to end the scan.</param>
+        public static void ExclusiveScanInPlaceSerial<T>(T[] arr, Func<T, T, T> function, int lowerBoundInclusive, int upperBoundExclusive)
+        {
+            T total = arr[lowerBoundInclusive];
+            arr[lowerBoundInclusive] = default(T);
+            for (int i = lowerBoundInclusive + 1; i < upperBoundExclusive; i++)
+            {
+                T prevTotal = total;
+                total = function(total, arr[i]);
+                arr[i] = prevTotal;
+            }
+        }
+
+        /// <summary>Computes a parallel prefix scan over the array using the specified function.</summary>
+        /// <typeparam name="T">The type of the data in the array.</typeparam>
+        /// <param name="arr">The data, which will be overwritten with the computed prefix scan.</param>
+        /// <param name="function">The function to use for the scan.</param>
+        /// <param name="arrStart">The start of the data in arr over which the scan is being computed.</param>
+        /// <param name="arrLength">The length of the data in arr over which the scan is being computed.</param>
+        /// <param name="skip">The inclusive distance between elements over which the scan is being computed.</param>
+        /// <remarks>No parameter validation is performed.</remarks>
+        private static void InclusiveScanInPlaceWithLoadBalancingParallel<T>(T[] arr, Func<T, T, T> function, 
+            int arrStart, int arrLength, int skip)
+        {
+            // If the length is 0 or 1, just return a copy of the original array.
+            if (arrLength <= 1) return;
+            int halfInputLength = arrLength / 2;
+
+            // Pairwise combine. Use static partitioning, as the function
+            // is likely to be very small.
+            Parallel.For(0, halfInputLength, i =>
+            {
+                int loc = arrStart + (i * 2 * skip);
+                arr[loc + skip] = function(arr[loc], arr[loc + skip]);
+            });
+
+            // Recursively prefix scan the pairwise computations.
+            InclusiveScanInPlaceWithLoadBalancingParallel(arr, function, arrStart + skip, halfInputLength, skip * 2);
+
+            // Generate output. As before, use static partitioning.
+            Parallel.For(0, (arrLength % 2) == 0 ? halfInputLength - 1 : halfInputLength, i =>
+            {
+                int loc = arrStart + (i * 2 * skip) + skip;
+                arr[loc + skip] = function(arr[loc], arr[loc + skip]);
+            });
+        }
+
+        /// <summary>Computes a parallel inclusive prefix scan over the array using the specified function.</summary>
+        public static void InclusiveScanInPlaceParallel<T>(T[] arr, Func<T, T, T> function)
+        {
+            int procCount = Environment.ProcessorCount;
+            T[] intermediatePartials = new T[procCount];
+            using (var phaseBarrier = new Barrier(procCount, 
+                _ => ExclusiveScanInPlaceSerial(intermediatePartials, function, 0, intermediatePartials.Length)))
+            {
+                // Compute the size of each range
+                int rangeSize = arr.Length / procCount;
+                int nextRangeStart = 0;
+
+                // Create, store, and wait on all of the tasks
+                var tasks = new Task[procCount];
+                for (int i = 0; i < procCount; i++, nextRangeStart += rangeSize)
+                {
+                    // Get the range for each task, then start it
+                    int rangeNum = i;
+                    int lowerRangeInclusive = nextRangeStart;
+                    int upperRangeExclusive = i < procCount - 1 ? nextRangeStart + rangeSize : arr.Length;
+                    tasks[rangeNum] = Task.Factory.StartNew(() =>
+                    {
+                        // Phase 1: Prefix scan assigned range, and copy upper bound to intermediate partials
+                        InclusiveScanInPlaceSerial(arr, function, lowerRangeInclusive, upperRangeExclusive, 1);
+                        intermediatePartials[rangeNum] = arr[upperRangeExclusive - 1];
+
+                        // Phase 2: One thread only should prefix scan the intermediaries... done implicitly by the barrier
+                        phaseBarrier.SignalAndWait();
+
+                        // Phase 3: Incorporate partials
+                        if (rangeNum != 0)
+                        {
+                            for (int j = lowerRangeInclusive; j < upperRangeExclusive; j++)
+                            {
+                                arr[j] = function(intermediatePartials[rangeNum], arr[j]);
+                            }
+                        }
+                    });
+                }
+
+                // Wait for all of the tasks to complete
+                Task.WaitAll(tasks);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_Sort.cs b/trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_Sort.cs
new file mode 100644 (file)
index 0000000..123bbc8
--- /dev/null
@@ -0,0 +1,240 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: ParallelAlgorithms_Sort.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace System.Threading.Algorithms
+{
+    public static partial class ParallelAlgorithms
+    {
+        /// <summary>Sorts an array in parallel.</summary>
+        /// <typeparam name="T">Specifies the type of data in the array.</typeparam>
+        /// <param name="array">The array to be sorted.</param>
+        public static void Sort<T>(T [] array)
+        {
+            Sort(array, (IComparer<T>)null);
+        }
+
+        /// <summary>Sorts an array in parallel.</summary>
+        /// <typeparam name="T">Specifies the type of data in the array.</typeparam>
+        /// <param name="array">The array to be sorted.</param>
+        /// <param name="comparer">The comparer used to compare two elements during the sort operation.</param>
+        public static void Sort<T>(T[] array, IComparer<T> comparer)
+        {
+            if (array == null) throw new ArgumentNullException("array");
+            Sort<T, object>(array, null, 0, array.Length, comparer);
+        }
+
+        /// <summary>Sorts an array in parallel.</summary>
+        /// <typeparam name="T">Specifies the type of data in the array.</typeparam>
+        /// <param name="array">The array to be sorted.</param>
+        /// <param name="index">The index at which to start the sort, inclusive.</param>
+        /// <param name="length">The number of elements to be sorted, starting at the start index.</param>
+        public static void Sort<T>(T [] array, Int32 index, Int32 length)
+        {
+            Sort<T, object>(array, null, index, length, (IComparer<T>)null);
+        }
+
+        /// <summary>Sorts an array in parallel.</summary>
+        /// <typeparam name="T">Specifies the type of data in the array.</typeparam>
+        /// <param name="array">The array to be sorted.</param>
+        /// <param name="index">The index at which to start the sort, inclusive.</param>
+        /// <param name="length">The number of elements to be sorted, starting at the start index.</param>
+        /// <param name="comparer">The comparer used to compare two elements during the sort operation.</param>
+        public static void Sort<T>(T[] array, Int32 index, Int32 length, IComparer<T> comparer)
+        {
+            Sort<T,object>(array, null, index, length, comparer);
+        }
+
+        /// <summary>Sorts key/value arrays in parallel.</summary>
+        /// <typeparam name="TKey">Specifies the type of the data in the keys array.</typeparam>
+        /// <typeparam name="TValue">Specifies the type of the data in the items array.</typeparam>
+        /// <param name="keys">The keys to be sorted.</param>
+        /// <param name="items">The items to be sorted based on the corresponding keys.</param>
+        public static void Sort<TKey, TValue>(TKey[] keys, TValue[] items)
+        {
+            Sort(keys, items, 0, keys.Length, (IComparer<TKey>)null);
+        }
+
+        /// <summary>Sorts key/value arrays in parallel.</summary>
+        /// <typeparam name="TKey">Specifies the type of the data in the keys array.</typeparam>
+        /// <typeparam name="TValue">Specifies the type of the data in the items array.</typeparam>
+        /// <param name="keys">The keys to be sorted.</param>
+        /// <param name="items">The items to be sorted based on the corresponding keys.</param>
+        /// <param name="comparer">The comparer used to compare two elements during the sort operation.</param>
+        public static void Sort<TKey, TValue>(TKey[] keys, TValue[] items, IComparer<TKey> comparer)
+        {
+            if (keys == null) throw new ArgumentNullException("keys");
+            Sort(keys, items, 0, keys.Length, comparer);
+        }
+
+        /// <summary>Sorts key/value arrays in parallel.</summary>
+        /// <typeparam name="TKey">Specifies the type of the data in the keys array.</typeparam>
+        /// <typeparam name="TValue">Specifies the type of the data in the items array.</typeparam>
+        /// <param name="keys">The keys to be sorted.</param>
+        /// <param name="items">The items to be sorted based on the corresponding keys.</param>
+        /// <param name="index">The index at which to start the sort, inclusive.</param>
+        /// <param name="length">The number of elements to be sorted, starting at the start index.</param>
+        public static void Sort<TKey, TValue>(TKey[] keys, TValue[] items, Int32 index, Int32 length)
+        {
+            Sort(keys, items, index, length, (IComparer<TKey>)null);
+        }
+
+        /// <summary>Sorts key/value arrays in parallel.</summary>
+        /// <typeparam name="TKey">Specifies the type of the data in the keys array.</typeparam>
+        /// <typeparam name="TValue">Specifies the type of the data in the items array.</typeparam>
+        /// <param name="keys">The keys to be sorted.</param>
+        /// <param name="items">The items to be sorted based on the corresponding keys.</param>
+        /// <param name="index">The index at which to start the sort, inclusive.</param>
+        /// <param name="length">The number of elements to be sorted, starting at the start index.</param>
+        /// <param name="comparer">The comparer used to compare two elements during the sort operation.</param>
+        public static void Sort<TKey, TValue>(TKey [] keys, TValue [] items, Int32 index, Int32 length, IComparer<TKey> comparer)
+        {
+            if (keys == null) throw new ArgumentNullException("keys");
+            if ((index < 0) || (length < 0)) throw new ArgumentOutOfRangeException(length < 0 ? "length" : "index");
+            if (((keys.Length - index) < length) || ((items != null) && (index > (items.Length - length)))) throw new ArgumentException("index");
+
+            // Run the core sort operation
+            new Sorter<TKey, TValue>(keys, items, comparer).QuickSort(index, index + length - 1);
+        }
+
+        // Stores the data necessary for the sort, and provides the core sorting method
+        private sealed class Sorter<TKey, TItem>
+        {
+            private TKey[] _keys;
+            private TItem[] _items;
+            private IComparer<TKey> _comparer;
+
+            public Sorter(TKey[] keys, TItem[] items, IComparer<TKey> comparer)
+            {
+                if (comparer == null) comparer = Comparer<TKey>.Default;
+                _keys = keys;
+                _items = items;
+                _comparer = comparer;
+            }
+
+            // Gets a recommended depth for recursion.  This assumes that every level will
+            // spawn two child tasks, which isn't actually the case with the algorithm, but
+            // it's a "good enough" approximation.
+            private static int GetMaxDepth()
+            {
+                return (int)Math.Log(Environment.ProcessorCount, 2);
+            }
+
+            // Swaps the items at the two specified indexes if they need to be swapped
+            internal void SwapIfGreaterWithItems(int a, int b)
+            {
+                if (a != b)
+                {
+                    if (_comparer.Compare(_keys[a], _keys[b]) > 0)
+                    {
+                        TKey temp = _keys[a];
+                        _keys[a] = _keys[b];
+                        _keys[b] = temp;
+                        if (_items != null)
+                        {
+                            TItem item = _items[a];
+                            _items[a] = _items[b];
+                            _items[b] = item;
+                        }
+                    }
+                }
+            }
+
+            // Gets the middle value between the provided low and high
+            private static int GetMiddle(int low, int high) { return low + ((high - low) >> 1); }
+
+            // Does a quicksort of the stored data, between the positions (inclusive specified by left and right)
+            internal void QuickSort(int left, int right)
+            {
+                QuickSort(left, right, 0, GetMaxDepth());
+            }
+
+            // Does a quicksort of the stored data, between the positions (inclusive specified by left and right).
+            // Depth specifies the current recursion depth, while maxDepth specifies the maximum depth
+            // we should recur to until we switch over to sequential.
+            internal void QuickSort(int left, int right, int depth, int maxDepth)
+            {
+                const int SEQUENTIAL_THRESHOLD = 0x1000;
+
+                // If the max depth has been reached or if we've hit the sequential
+                // threshold for the input array size, run sequential.
+                if (depth >= maxDepth || (right - left + 1) <= SEQUENTIAL_THRESHOLD)
+                {
+                    Array.Sort(_keys, _items, left, right - left + 1, _comparer);
+                    return;
+                }
+
+                // Store all tasks generated to process subarrays
+                List<Task> tasks = new List<Task>();
+
+                // Run the same basic algorithm used by Array.Sort, but spawning Tasks for all recursive calls
+                do
+                {
+                    int i = left;
+                    int j = right;
+
+                    // Pre-sort the low, middle (pivot), and high values in place.
+                    int middle = GetMiddle(i, j);
+                    SwapIfGreaterWithItems(i, middle); // swap the low with the mid point
+                    SwapIfGreaterWithItems(i, j);      // swap the low with the high
+                    SwapIfGreaterWithItems(middle, j); // swap the middle with the high
+
+                    // Get the pivot
+                    TKey x = _keys[middle];
+
+                    // Move all data around the pivot value
+                    do
+                    {
+                        while (_comparer.Compare(_keys[i], x) < 0) i++;
+                        while (_comparer.Compare(x, _keys[j]) < 0) j--;
+
+                        if (i > j) break;
+                        if (i < j)
+                        {
+                            TKey key = _keys[i];
+                            _keys[i] = _keys[j];
+                            _keys[j] = key;
+                            if (_items != null)
+                            {
+                                TItem item = _items[i];
+                                _items[i] = _items[j];
+                                _items[j] = item;
+                            }
+                        }
+                        i++;
+                        j--;
+                    } while (i <= j);
+
+                    if (j - left <= right - i)
+                    {
+                        if (left < j)
+                        {
+                            int leftcopy = left, jcopy = j;
+                            tasks.Add(Task.Factory.StartNew(() => QuickSort(leftcopy, jcopy, depth + 1, maxDepth)));
+                        }
+                        left = i;
+                    }
+                    else
+                    {
+                        if (i < right)
+                        {
+                            int icopy = i, rightcopy = right;
+                            tasks.Add(Task.Factory.StartNew(() => QuickSort(icopy, rightcopy, depth + 1, maxDepth)));
+                        }
+                        right = j;
+                    }
+                } while (left < right);
+
+                // Wait for all of this level's tasks to complete
+                Task.WaitAll(tasks.ToArray());
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_SpeculativeFor.cs b/trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_SpeculativeFor.cs
new file mode 100644 (file)
index 0000000..8beeffc
--- /dev/null
@@ -0,0 +1,59 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: ParallelAlgorithms_SpeculativeFor.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace System.Threading.Algorithms
+{
+    public static partial class ParallelAlgorithms
+    {
+        /// <summary>Executes a function for each value in a range, returning the first result achieved and ceasing execution.</summary>
+        /// <typeparam name="TResult">The type of the data returned.</typeparam>
+        /// <param name="fromInclusive">The start of the range, inclusive.</param>
+        /// <param name="toExclusive">The end of the range, exclusive.</param>
+        /// <param name="options">The options to use for processing the loop.</param>
+        /// <param name="body">The function to execute for each element.</param>
+        /// <returns>The result computed.</returns>
+        public static TResult SpeculativeFor<TResult>(
+            int fromInclusive, int toExclusive, Func<int, TResult> body)
+        {
+            return SpeculativeFor(fromInclusive, toExclusive, s_defaultParallelOptions, body);
+        }
+
+        /// <summary>Executes a function for each value in a range, returning the first result achieved and ceasing execution.</summary>
+        /// <typeparam name="TResult">The type of the data returned.</typeparam>
+        /// <param name="fromInclusive">The start of the range, inclusive.</param>
+        /// <param name="toExclusive">The end of the range, exclusive.</param>
+        /// <param name="options">The options to use for processing the loop.</param>
+        /// <param name="body">The function to execute for each element.</param>
+        /// <returns>The result computed.</returns>
+        public static TResult SpeculativeFor<TResult>(
+            int fromInclusive, int toExclusive, ParallelOptions options, Func<int, TResult> body)
+        {
+            // Validate parameters; the Parallel.For we delegate to will validate the rest
+            if (body == null) throw new ArgumentNullException("body");
+
+            // Store one result.  We box it if it's a value type to avoid torn writes and enable
+            // CompareExchange even for value types.
+            object result = null;
+
+            // Run all bodies in parallel, stopping as soon as one has completed.
+            Parallel.For(fromInclusive, toExclusive, options, (i, loopState) =>
+            {
+                // Run an iteration.  When it completes, store (box) 
+                // the result, and cancel the rest
+                Interlocked.CompareExchange(ref result, (object)body(i), null);
+                loopState.Stop();
+            });
+
+            // Return the computed result
+            return (TResult)result;
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_SpeculativeForEach.cs b/trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_SpeculativeForEach.cs
new file mode 100644 (file)
index 0000000..2c6cc54
--- /dev/null
@@ -0,0 +1,58 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: ParallelAlgorithms_SpeculativeForEach.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace System.Threading.Algorithms
+{
+    public static partial class ParallelAlgorithms
+    {
+        /// <summary>Executes a function for each element in a source, returning the first result achieved and ceasing execution.</summary>
+        /// <typeparam name="TSource">The type of the data in the source.</typeparam>
+        /// <typeparam name="TResult">The type of the data returned.</typeparam>
+        /// <param name="source">The input elements to be processed.</param>
+        /// <param name="body">The function to execute for each element.</param>
+        /// <returns>The result computed.</returns>
+        public static TResult SpeculativeForEach<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, TResult> body)
+        {
+            // Run with default options
+            return SpeculativeForEach(source, s_defaultParallelOptions, body);
+        }
+
+        /// <summary>Executes a function for each element in a source, returning the first result achieved and ceasing execution.</summary>
+        /// <typeparam name="TSource">The type of the data in the source.</typeparam>
+        /// <typeparam name="TResult">The type of the data returned.</typeparam>
+        /// <param name="source">The input elements to be processed.</param>
+        /// <param name="options">The options to use for processing the loop.</param>
+        /// <param name="body">The function to execute for each element.</param>
+        /// <returns>The result computed.</returns>
+        public static TResult SpeculativeForEach<TSource, TResult>(
+            IEnumerable<TSource> source, ParallelOptions options, Func<TSource, TResult> body)
+        {
+            // Validate parameters; the Parallel.ForEach we delegate to will validate the rest
+            if (body == null) throw new ArgumentNullException("body");
+
+            // Store one result.  We box it if it's a value type to avoid torn writes and enable
+            // CompareExchange even for value types.
+            object result = null;
+
+            // Run all bodies in parallel, stopping as soon as one has completed.
+            Parallel.ForEach(source, options, (item, loopState) =>
+            {
+                // Run an iteration.  When it completes, store (box) 
+                // the result, and cancel the rest
+                Interlocked.CompareExchange(ref result, (object)body(item), null);
+                loopState.Stop();
+            });
+
+            // Return the computed result
+            return (TResult)result;
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_SpeculativeInvoke.cs b/trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_SpeculativeInvoke.cs
new file mode 100644 (file)
index 0000000..f8e1a8e
--- /dev/null
@@ -0,0 +1,41 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: ParallelAlgorithms_SpeculativeInvoke.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Concurrent.Partitioners;
+using System.Threading.Tasks;
+
+namespace System.Threading.Algorithms
+{
+    public static partial class ParallelAlgorithms
+    {
+        /// <summary>Invokes the specified functions, potentially in parallel, canceling outstanding invocations once one completes.</summary>
+        /// <typeparam name="T">Specifies the type of data returned by the functions.</typeparam>
+        /// <param name="functions">The functions to be executed.</param>
+        /// <returns>A result from executing one of the functions.</returns>
+        public static T SpeculativeInvoke<T>(params Func<T>[] functions)
+        {
+            // Run with default options
+            return SpeculativeInvoke(s_defaultParallelOptions, functions);
+        }
+
+        /// <summary>Invokes the specified functions, potentially in parallel, canceling outstanding invocations once one completes.</summary>
+        /// <typeparam name="T">Specifies the type of data returned by the functions.</typeparam>
+        /// <param name="options">The options to use for the execution.</param>
+        /// <param name="functions">The functions to be executed.</param>
+        /// <returns>A result from executing one of the functions.</returns>
+        public static T SpeculativeInvoke<T>(ParallelOptions options, params Func<T>[] functions)
+        {
+            // Validate parameters
+            if (options == null) throw new ArgumentNullException("options");
+            if (functions == null) throw new ArgumentNullException("functions");
+
+            // Speculatively invoke each function
+            return ParallelAlgorithms.SpeculativeForEach(functions, options, function => function());
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_Wavefront.cs b/trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_Wavefront.cs
new file mode 100644 (file)
index 0000000..1870465
--- /dev/null
@@ -0,0 +1,119 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: ParallelAlgorithms_Wavefront.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace System.Threading.Algorithms
+{
+    public static partial class ParallelAlgorithms
+    {
+        /// <summary>Process in parallel a matrix where every cell has a dependency on the cell above it and to its left.</summary>
+        /// <param name="numRows">The number of rows in the matrix.</param>
+        /// <param name="numColumns">The number of columns in the matrix.</param>
+        /// <param name="numBlocksPerRow">Partition the matrix into this number of blocks along the rows.</param>
+        /// <param name="numBlocksPerColumn">Partition the matrix into this number of blocks along the columns.</param>
+        /// <param name="processBlock">The action to invoke for every block, supplied with the start and end indices of the rows and columns.</param>
+        public static void Wavefront(
+            int numRows, int numColumns,
+            int numBlocksPerRow, int numBlocksPerColumn,
+            Action<int, int, int, int> processBlock)
+        {
+            // Validate parameters
+            if (numRows <= 0) throw new ArgumentOutOfRangeException("numRows");
+            if (numColumns <= 0) throw new ArgumentOutOfRangeException("numColumns");
+            if (numBlocksPerRow <= 0 || numBlocksPerRow > numRows)
+                throw new ArgumentOutOfRangeException("numBlocksPerRow");
+            if (numBlocksPerColumn <= 0 || numBlocksPerColumn > numColumns)
+                throw new ArgumentOutOfRangeException("numBlocksPerColumn");
+            if (processBlock == null)
+                throw new ArgumentNullException("processRowColumnCell");
+
+            // Compute the size of each block
+            int rowBlockSize = numRows / numBlocksPerRow;
+            int columnBlockSize = numColumns / numBlocksPerColumn;
+
+            Wavefront(numBlocksPerRow, numBlocksPerColumn, (row, column) =>
+            {
+                int start_i = row * rowBlockSize;
+                int end_i = row < numBlocksPerRow - 1 ?
+                    start_i + rowBlockSize : numRows;
+
+                int start_j = column * columnBlockSize;
+                int end_j = column < numBlocksPerColumn - 1 ?
+                    start_j + columnBlockSize : numColumns;
+
+                processBlock(start_i, end_i, start_j, end_j);
+            });
+        }
+
+        /// <summary>Process in parallel a matrix where every cell has a dependency on the cell above it and to its left.</summary>
+        /// <param name="numRows">The number of rows in the matrix.</param>
+        /// <param name="numColumns">The number of columns in the matrix.</param>
+        /// <param name="processRowColumnCell">The action to invoke for every cell, supplied with the row and column indices.</param>
+        public static void Wavefront(int numRows, int numColumns, Action<int, int> processRowColumnCell)
+        {
+            // Validate parameters
+            if (numRows <= 0) throw new ArgumentOutOfRangeException("numRows");
+            if (numColumns <= 0) throw new ArgumentOutOfRangeException("numColumns");
+            if (processRowColumnCell == null) throw new ArgumentNullException("processRowColumnCell");
+
+            // Store the previous row of tasks as well as the previous task in the current row
+            Task[] prevTaskRow = new Task[numColumns];
+            Task prevTaskInCurrentRow = null;
+            var dependencies = new Task[2];
+
+            // Create a task for each cell
+            for (int row = 0; row < numRows; row++)
+            {
+                prevTaskInCurrentRow = null;
+                for (int column = 0; column < numColumns; column++)
+                {
+                    // In-scope locals for being captured in the task closures
+                    int j = row, i = column;
+
+                    // Create a task with the appropriate dependencies.
+                    Task curTask;
+                    if (row == 0 && column == 0)
+                    {
+                        // Upper-left task kicks everything off, having no dependencies
+                        curTask = Task.Factory.StartNew(() => processRowColumnCell(j, i));
+                    }
+                    else if (row == 0 || column == 0)
+                    {
+                        // Tasks in the left-most column depend only on the task above them, and
+                        // tasks in the top row depend only on the task to their left
+                        var antecedent = column == 0 ? prevTaskRow[0] : prevTaskInCurrentRow;
+                        curTask = antecedent.ContinueWith(p =>
+                        {
+                            p.Wait(); // Necessary only to propagate exceptions
+                            processRowColumnCell(j, i);
+                        });
+                    }
+                    else // row > 0 && column > 0
+                    {
+                        // All other tasks depend on both the tasks above and to the left
+                        dependencies[0] = prevTaskInCurrentRow;
+                        dependencies[1] = prevTaskRow[column];
+                        curTask = Task.Factory.ContinueWhenAll(dependencies, ps =>
+                        {
+                            Task.WaitAll(ps); // Necessary only to propagate exceptions
+                            processRowColumnCell(j, i);
+                        });
+                    }
+
+                    // Keep track of the task just created for future iterations
+                    prevTaskRow[column] = prevTaskInCurrentRow = curTask;
+                }
+            }
+
+            // Wait for the last task to be done.
+            prevTaskInCurrentRow.Wait();
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_While.cs b/trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_While.cs
new file mode 100644 (file)
index 0000000..c3f8d0f
--- /dev/null
@@ -0,0 +1,46 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: ParallelAlgorithms_While.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Concurrent.Partitioners;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace System.Threading.Algorithms
+{
+    public static partial class ParallelAlgorithms
+    {
+        /// <summary>Repeatedly executes an operation in parallel while the specified condition evaluates to true.</summary>
+        /// <param name="condition">The condition to evaluate.</param>
+        /// <param name="body">The loop body.</param>
+        public static void ParallelWhile(Func<bool> condition, Action body)
+        {
+            // Just delegate to the overload that accepts a ParallelOptions
+            ParallelWhile(s_defaultParallelOptions, condition, body);
+        }
+
+        /// <summary>Repeatedly executes an operation in parallel while the specified condition evaluates to true.</summary>
+        /// <param name="parallelOptions">A ParallelOptions instance that configures the behavior of this operation.</param>
+        /// <param name="condition">The condition to evaluate.</param>
+        /// <param name="body">The loop body.</param>
+        public static void ParallelWhile(
+            ParallelOptions parallelOptions, Func<bool> condition, Action body)
+        {
+            if (parallelOptions == null) throw new ArgumentNullException("parallelOptions");
+            if (condition == null) throw new ArgumentNullException("condition");
+            if (body == null) throw new ArgumentNullException("body");
+
+            Parallel.ForEach(SingleItemPartitioner.Create(IterateUntilFalse(condition)), parallelOptions, ignored => body());
+        }
+
+        // Continually yield values until condition returns false
+        private static IEnumerable<bool> IterateUntilFalse(Func<bool> condition)
+        {
+            while (condition()) yield return true;
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_WhileNotEmpty.cs b/trunk/Libraries/ParallelExtensionsExtras/ParallelAlgorithms/ParallelAlgorithms_WhileNotEmpty.cs
new file mode 100644 (file)
index 0000000..e227543
--- /dev/null
@@ -0,0 +1,64 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: ParallelAlgorithms_WhileNotEmpty.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace System.Threading.Algorithms
+{
+    public static partial class ParallelAlgorithms
+    {
+        /// <summary>Processes data in parallel, allowing the processing function to add more data to be processed.</summary>
+        /// <typeparam name="T">Specifies the type of data being processed.</typeparam>
+        /// <param name="initialValues">The initial set of data to be processed.</param>
+        /// <param name="body">The operation to execute for each value.</param>
+        public static void WhileNotEmpty<T>(IEnumerable<T> initialValues, Action<T, Action<T>> body)
+        {
+            WhileNotEmpty(s_defaultParallelOptions, initialValues, body);
+        }
+
+        /// <summary>Processes data in parallel, allowing the processing function to add more data to be processed.</summary>
+        /// <typeparam name="T">Specifies the type of data being processed.</typeparam>
+        /// <param name="parallelOptions">A ParallelOptions instance that configures the behavior of this operation.</param>
+        /// <param name="initialValues">The initial set of data to be processed.</param>
+        /// <param name="body">The operation to execute for each value.</param>
+        public static void WhileNotEmpty<T>(
+            ParallelOptions parallelOptions,
+            IEnumerable<T> initialValues,
+            Action<T, Action<T>> body)
+        {
+            // Validate arguments
+            if (parallelOptions == null) throw new ArgumentNullException("parallelOptions");
+            if (initialValues == null) throw new ArgumentNullException("initialValues");
+            if (body == null) throw new ArgumentNullException("body");
+
+            // Create two lists to alternate between as source and destination.
+            var lists = new[] { new ConcurrentStack<T>(initialValues), new ConcurrentStack<T>() };
+
+            // Iterate until no more items to be processed
+            for (int i = 0; ; i++)
+            {
+                // Determine which list is the source and which is the destination
+                int fromIndex = i % 2;
+                var from = lists[fromIndex];
+                var to = lists[fromIndex ^ 1];
+
+                // If the source is empty, we're done
+                if (from.IsEmpty) break;
+
+                // Otherwise, process all source items in parallel, adding any new items into the destination
+                Action<T> adder = newItem => to.Push(newItem);
+                Parallel.ForEach(from, parallelOptions, e => body(e, adder));
+
+                // Clear out the source as it's now been fully processed
+                from.Clear();
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/ParallelExtensionsExtras.csproj b/trunk/Libraries/ParallelExtensionsExtras/ParallelExtensionsExtras.csproj
new file mode 100644 (file)
index 0000000..b2bf97d
--- /dev/null
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{C45218F8-09E7-4F57-85BC-5D8D2AC736A3}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>ParallelExtensionsExtras</RootNamespace>
+    <AssemblyName>ParallelExtensionsExtras</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <CodeContractsAssemblyMode>1</CodeContractsAssemblyMode>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <DocumentationFile>
+    </DocumentationFile>
+    <CodeContractsEnableRuntimeChecking>False</CodeContractsEnableRuntimeChecking>
+    <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
+    <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
+    <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
+    <CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers>
+    <CodeContractsRunCodeAnalysis>False</CodeContractsRunCodeAnalysis>
+    <CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
+    <CodeContractsBoundsObligations>False</CodeContractsBoundsObligations>
+    <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
+    <CodeContractsEnumObligations>False</CodeContractsEnumObligations>
+    <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
+    <CodeContractsRunInBackground>True</CodeContractsRunInBackground>
+    <CodeContractsShowSquigglies>False</CodeContractsShowSquigglies>
+    <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
+    <CodeContractsEmitXMLDocs>True</CodeContractsEmitXMLDocs>
+    <CodeContractsCustomRewriterAssembly />
+    <CodeContractsCustomRewriterClass />
+    <CodeContractsLibPaths />
+    <CodeContractsExtraRewriteOptions />
+    <CodeContractsExtraAnalysisOptions />
+    <CodeContractsBaseLineFile />
+    <CodeContractsCacheAnalysisResults>False</CodeContractsCacheAnalysisResults>
+    <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
+    <CodeContractsReferenceAssembly>Build</CodeContractsReferenceAssembly>
+    <CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <DocumentationFile>
+    </DocumentationFile>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Numerics" />
+    <Reference Include="WindowsBase" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="CoordinationDataStructures\AbstractStreamBase.cs" />
+    <Compile Include="CoordinationDataStructures\ActionCountdownEvent.cs" />
+    <Compile Include="CoordinationDataStructures\AsyncCoordination\AsyncCache.cs" />
+    <Compile Include="CoordinationDataStructures\AsyncCoordination\AsyncCall.cs" />
+    <Compile Include="CoordinationDataStructures\AsyncCoordination\AsyncBarrier.cs" />
+    <Compile Include="CoordinationDataStructures\AsyncCoordination\AsyncProducerConsumerCollection.cs" />
+    <Compile Include="CoordinationDataStructures\AsyncCoordination\AsyncReaderWriter.cs" />
+    <Compile Include="CoordinationDataStructures\AsyncCoordination\AsyncSemaphore.cs" />
+    <Compile Include="CoordinationDataStructures\ConcurrentPriorityQueue.cs" />
+    <Compile Include="CoordinationDataStructures\ObjectPool.cs" />
+    <Compile Include="CoordinationDataStructures\ObservableConcurrentCollection.cs" />
+    <Compile Include="CoordinationDataStructures\ObservableConcurrentDictionary.cs" />
+    <Compile Include="CoordinationDataStructures\Pipeline.cs" />
+    <Compile Include="CoordinationDataStructures\ProducerConsumerCollectionBase.cs" />
+    <Compile Include="CoordinationDataStructures\ReductionVariable.cs" />
+    <Compile Include="CoordinationDataStructures\SerialTaskQueue.cs" />
+    <Compile Include="CoordinationDataStructures\SpinLockClass.cs" />
+    <Compile Include="CoordinationDataStructures\ThreadSafeRandom.cs" />
+    <Compile Include="CoordinationDataStructures\TransferStream.cs" />
+    <Compile Include="Drawing\FastBitmap.cs" />
+    <Compile Include="Extensions\AggregateExceptionExtensions.cs" />
+    <Compile Include="Extensions\APM\FileAsync.cs" />
+    <Compile Include="Extensions\APM\StreamExtensions.cs" />
+    <Compile Include="Extensions\APM\WebRequestExtensions.cs" />
+    <Compile Include="Extensions\BlockingCollectionExtensions.cs" />
+    <Compile Include="Extensions\CancellationTokenExtensions.cs" />
+    <Compile Include="Extensions\CompletedTask.cs" />
+    <Compile Include="Extensions\DelegateBasedObserver.cs" />
+    <Compile Include="Extensions\DelegateExtensions.cs" />
+    <Compile Include="Extensions\EAP\EAPCommon.cs" />
+    <Compile Include="Extensions\EAP\PingExtensions.cs" />
+    <Compile Include="Extensions\EAP\SmtpClientExtensions.cs" />
+    <Compile Include="Extensions\EAP\WebClientExtensions.cs" />
+    <Compile Include="Extensions\IProducerConsumerCollectionExtensions.cs" />
+    <Compile Include="Extensions\LazyExtensions.cs" />
+    <Compile Include="Extensions\LinqToTasks.cs" />
+    <Compile Include="Extensions\ParallelLinqOptions.cs" />
+    <Compile Include="Extensions\ParallelOptionsExtensions.cs" />
+    <Compile Include="Extensions\PlinqExtensions.cs" />
+    <Compile Include="Extensions\TaskCompletionSourceExtensions.cs" />
+    <Compile Include="Extensions\TaskExtrasExtensions.cs" />
+    <Compile Include="Extensions\TaskFactoryExtensions\TaskFactoryExtensions_ContinueWhenAllAny.cs" />
+    <Compile Include="Extensions\TaskFactoryExtensions\TaskFactoryExtensions_From.cs" />
+    <Compile Include="Extensions\TaskFactoryExtensions\TaskFactoryExtensions_Common.cs" />
+    <Compile Include="Extensions\TaskFactoryExtensions\TaskFactoryExtensions_Create.cs" />
+    <Compile Include="Extensions\TaskFactoryExtensions\TaskFactoryExtensions_Delayed.cs" />
+    <Compile Include="Extensions\TaskFactoryExtensions\TaskFactoryExtensions_FromAsync.cs" />
+    <Compile Include="Extensions\TaskFactoryExtensions\TaskFactoryExtensions_Iterate.cs" />
+    <Compile Include="Extensions\TaskFactoryExtensions\TaskFactoryExtensions_TrackedSequence.cs" />
+    <Compile Include="Extensions\TaskSchedulerExtensions.cs" />
+    <Compile Include="ParallelAlgorithms\ParallelAlgorithms_For.cs" />
+    <Compile Include="ParallelAlgorithms\ParallelAlgorithms_Common.cs" />
+    <Compile Include="ParallelAlgorithms\ParallelAlgorithms_Filter.cs" />
+    <Compile Include="ParallelAlgorithms\ParallelAlgorithms_ForRange.cs" />
+    <Compile Include="ParallelAlgorithms\ParallelAlgorithms_Map.cs" />
+    <Compile Include="ParallelAlgorithms\ParallelAlgorithms_Reduce.cs" />
+    <Compile Include="ParallelAlgorithms\ParallelAlgorithms_Scan.cs" />
+    <Compile Include="ParallelAlgorithms\ParallelAlgorithms_Sort.cs" />
+    <Compile Include="ParallelAlgorithms\ParallelAlgorithms_SpeculativeFor.cs" />
+    <Compile Include="ParallelAlgorithms\ParallelAlgorithms_SpeculativeForEach.cs" />
+    <Compile Include="ParallelAlgorithms\ParallelAlgorithms_SpeculativeInvoke.cs" />
+    <Compile Include="ParallelAlgorithms\ParallelAlgorithms_Wavefront.cs" />
+    <Compile Include="ParallelAlgorithms\ParallelAlgorithms_While.cs" />
+    <Compile Include="ParallelAlgorithms\ParallelAlgorithms_WhileNotEmpty.cs" />
+    <Compile Include="Partitioners\ChunkPartitioner.cs" />
+    <Compile Include="Partitioners\SingleItemPartitioner.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="TaskSchedulers\ConcurrentExclusiveInterleave.cs" />
+    <Compile Include="TaskSchedulers\CurrentThreadTaskScheduler.cs" />
+    <Compile Include="TaskSchedulers\IOCompletionPortTaskScheduler.cs" />
+    <Compile Include="TaskSchedulers\QueuedTaskScheduler.cs" />
+    <Compile Include="TaskSchedulers\IOTaskScheduler.cs" />
+    <Compile Include="TaskSchedulers\LimitedConcurrencyLevelTaskScheduler.cs" />
+    <Compile Include="TaskSchedulers\OrderedTaskScheduler.cs" />
+    <Compile Include="TaskSchedulers\ReprioritizableTaskScheduler.cs" />
+    <Compile Include="TaskSchedulers\RoundRobinTaskScheduler.cs" />
+    <Compile Include="TaskSchedulers\StaTaskScheduler.cs" />
+    <Compile Include="TaskSchedulers\SynchronizationContextTaskScheduler.cs" />
+    <Compile Include="TaskSchedulers\ThreadPerTaskkScheduler.cs" />
+    <Compile Include="TaskSchedulers\WorkStealingTaskScheduler.cs" />
+    <Compile Include="Utils\SortedTopN.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. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/ParallelExtensionsExtras.sln b/trunk/Libraries/ParallelExtensionsExtras/ParallelExtensionsExtras.sln
new file mode 100644 (file)
index 0000000..2a3a098
--- /dev/null
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ParallelExtensionsExtras", "ParallelExtensionsExtras.csproj", "{C45218F8-09E7-4F57-85BC-5D8D2AC736A3}"
+EndProject
+Global
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Debug|Any CPU = Debug|Any CPU
+               Release|Any CPU = Release|Any CPU
+       EndGlobalSection
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {C45218F8-09E7-4F57-85BC-5D8D2AC736A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {C45218F8-09E7-4F57-85BC-5D8D2AC736A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {C45218F8-09E7-4F57-85BC-5D8D2AC736A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {C45218F8-09E7-4F57-85BC-5D8D2AC736A3}.Release|Any CPU.Build.0 = Release|Any CPU
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+EndGlobal
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Partitioners/ChunkPartitioner.cs b/trunk/Libraries/ParallelExtensionsExtras/Partitioners/ChunkPartitioner.cs
new file mode 100644 (file)
index 0000000..744f54b
--- /dev/null
@@ -0,0 +1,290 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: ChunkPartitioner.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Threading;
+
+namespace System.Collections.Concurrent.Partitioners
+{
+    /// <summary>
+    /// Partitions an enumerable into chunks based on user-supplied criteria.
+    /// </summary>
+    public static class ChunkPartitioner
+    {
+        /// <summary>Creates a partitioner that chooses the next chunk size based on a user-supplied function.</summary>
+        /// <typeparam name="TSource">The type of the data being partitioned.</typeparam>
+        /// <param name="source">The data being partitioned.</param>
+        /// <param name="nextChunkSizeFunc">A function that determines the next chunk size based on the
+        /// previous chunk size.</param>
+        /// <returns>A partitioner.</returns>
+        public static OrderablePartitioner<TSource> Create<TSource>(
+            IEnumerable<TSource> source, Func<int, int> nextChunkSizeFunc)
+        {
+            return new ChunkPartitioner<TSource>(source, nextChunkSizeFunc);
+        }
+
+        /// <summary>Creates a partitioner that always uses a user-specified chunk size.</summary>
+        /// <typeparam name="TSource">The type of the data being partitioned.</typeparam>
+        /// <param name="source">The data being partitioned.</param>
+        /// <param name="chunkSize">The chunk size to be used.</param>
+        /// <returns>A partitioner.</returns>
+        public static OrderablePartitioner<TSource> Create<TSource>(
+            IEnumerable<TSource> source, int chunkSize)
+        {
+            return new ChunkPartitioner<TSource>(source, chunkSize);
+        }
+
+        /// <summary>Creates a partitioner that chooses chunk sizes between the user-specified min and max.</summary>
+        /// <typeparam name="TSource">The type of the data being partitioned.</typeparam>
+        /// <param name="source">The data being partitioned.</param>
+        /// <param name="minChunkSize">The minimum chunk size to use.</param>
+        /// <param name="maxChunkSize">The maximum chunk size to use.</param>
+        /// <returns>A partitioner.</returns>
+        public static OrderablePartitioner<TSource> Create<TSource>(
+            IEnumerable<TSource> source, int minChunkSize, int maxChunkSize)
+        {
+            return new ChunkPartitioner<TSource>(source, minChunkSize, maxChunkSize);
+        }
+    }
+
+    /// <summary>
+    /// Partitions an enumerable into chunks based on user-supplied criteria.
+    /// </summary>
+    internal sealed class ChunkPartitioner<T> : OrderablePartitioner<T>
+    {
+        private readonly IEnumerable<T> _source;
+        private readonly Func<int, int> _nextChunkSizeFunc;
+
+        public ChunkPartitioner(IEnumerable<T> source, Func<int, int> nextChunkSizeFunc)
+            // The keys will be ordered across both individual partitions and across partitions,
+            // and they will be normalized.
+            : base(true, true, true)
+        {
+            // Validate and store the enumerable and function (used to determine how big
+            // to make the next chunk given the current chunk size)
+            if (source == null) throw new ArgumentNullException("source");
+            if (nextChunkSizeFunc == null) throw new ArgumentNullException("nextChunkSizeFunc");
+            _source = source;
+            _nextChunkSizeFunc = nextChunkSizeFunc;
+        }
+
+        public ChunkPartitioner(IEnumerable<T> source, int chunkSize)
+            : this(source, prev => chunkSize) // uses a function that always returns the specified chunk size
+        {
+            if (chunkSize <= 0) throw new ArgumentOutOfRangeException("chunkSize");
+        }
+
+        public ChunkPartitioner(IEnumerable<T> source, int minChunkSize, int maxChunkSize) :
+            this(source, CreateFuncFromMinAndMax(minChunkSize, maxChunkSize)) // uses a function that grows from min to max
+        {
+            if (minChunkSize <= 0 ||
+                minChunkSize > maxChunkSize) throw new ArgumentOutOfRangeException("minChunkSize");
+        }
+
+        private static Func<int, int> CreateFuncFromMinAndMax(int minChunkSize, int maxChunkSize)
+        {
+            // Create a function that returns exponentially growing chunk sizes between minChunkSize and maxChunkSize
+            return delegate(int prev)
+            {
+                if (prev < minChunkSize) return minChunkSize;
+                if (prev >= maxChunkSize) return maxChunkSize;
+                int next = prev * 2;
+                if (next >= maxChunkSize || next < 0) return maxChunkSize;
+                return next;
+            };
+        }
+
+        /// <summary>
+        /// Partitions the underlying collection into the specified number of orderable partitions.
+        /// </summary>
+        /// <param name="partitionCount">The number of partitions to create.</param>
+        /// <returns>An object that can create partitions over the underlying data source.</returns>
+        public override IList<IEnumerator<KeyValuePair<long, T>>> GetOrderablePartitions(int partitionCount)
+        {
+            // Validate parameters
+            if (partitionCount <= 0) throw new ArgumentOutOfRangeException("partitionCount");
+
+            // Create an array of dynamic partitions and return them
+            var partitions = new IEnumerator<KeyValuePair<long, T>>[partitionCount];
+            var dynamicPartitions = GetOrderableDynamicPartitions(true); 
+            for (int i = 0; i < partitionCount; i++)
+            {
+                partitions[i] = dynamicPartitions.GetEnumerator(); // Create and store the next partition
+            }
+            return partitions;
+        }
+
+        /// <summary>Gets whether additional partitions can be created dynamically.</summary>
+        public override bool SupportsDynamicPartitions { get { return true; } }
+
+        /// <summary>
+        /// Creates an object that can partition the underlying collection into a variable number of
+        /// partitions.
+        /// </summary>
+        /// <returns>
+        /// An object that can create partitions over the underlying data source.
+        /// </returns>
+        public override IEnumerable<KeyValuePair<long, T>> GetOrderableDynamicPartitions()
+        {
+            return new EnumerableOfEnumerators(this, false);
+        }
+
+        private IEnumerable<KeyValuePair<long, T>> GetOrderableDynamicPartitions(bool referenceCountForDisposal)
+        {
+            return new EnumerableOfEnumerators(this, referenceCountForDisposal);
+        }
+
+        // The object used to dynamically create partitions
+        private class EnumerableOfEnumerators : IEnumerable<KeyValuePair<long, T>>, IDisposable
+        {
+            private readonly ChunkPartitioner<T> _parentPartitioner;
+            private readonly object _sharedLock = new object();
+            private readonly IEnumerator<T> _sharedEnumerator;
+            private long _nextSharedIndex;
+            private int _activeEnumerators;
+            private bool _noMoreElements;
+            private bool _disposed;
+            private bool _referenceCountForDisposal;
+
+            public EnumerableOfEnumerators(ChunkPartitioner<T> parentPartitioner, bool referenceCountForDisposal)
+            {
+                // Validate parameters
+                if (parentPartitioner == null) throw new ArgumentNullException("parentPartitioner");
+
+                // Store the data, including creating an enumerator from the underlying data source
+                _parentPartitioner = parentPartitioner;
+                _sharedEnumerator = parentPartitioner._source.GetEnumerator();
+                _nextSharedIndex = -1;
+                _referenceCountForDisposal = referenceCountForDisposal;
+            }
+
+            IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
+            public IEnumerator<KeyValuePair<long, T>> GetEnumerator()
+            {
+                if (_referenceCountForDisposal)
+                {
+                    Interlocked.Increment(ref _activeEnumerators);
+                }
+                return new Enumerator(this);
+            }
+
+            private void DisposeEnumerator(Enumerator enumerator)
+            {
+                if (_referenceCountForDisposal)
+                {
+                    if (Interlocked.Decrement(ref _activeEnumerators) == 0)
+                    {
+                        _sharedEnumerator.Dispose();
+                    }
+                }
+            }
+
+            private class Enumerator : IEnumerator<KeyValuePair<long, T>>
+            {
+                private EnumerableOfEnumerators _parentEnumerable;
+                private List<KeyValuePair<long, T>> _currentChunk = new List<KeyValuePair<long, T>>();
+                private int _currentChunkCurrentIndex;
+                private int _lastRequestedChunkSize;
+                private bool _disposed;
+
+                public Enumerator(EnumerableOfEnumerators parentEnumerable)
+                {
+                    if (parentEnumerable == null) throw new ArgumentNullException("parentEnumerable");
+                    _parentEnumerable = parentEnumerable;
+                }
+
+                public bool MoveNext()
+                {
+                    if (_disposed) throw new ObjectDisposedException(GetType().Name);
+
+                    // Move to the next cached element. If we already retrieved a chunk and if there's still
+                    // data left in it, just use the next item from it.
+                    ++_currentChunkCurrentIndex;
+                    if (_currentChunkCurrentIndex >= 0 &&
+                        _currentChunkCurrentIndex < _currentChunk.Count) return true;
+
+                    // First, figure out how much new data we want. The previous requested chunk size is used
+                    // as input to figure out how much data the user now wants.  The initial chunk size
+                    // supplied is 0 so that the user delegate is made aware that this is the initial request
+                    // such that it can select the initial chunk size on first request.
+                    int nextChunkSize = _parentEnumerable._parentPartitioner._nextChunkSizeFunc(_lastRequestedChunkSize);
+                    if (nextChunkSize <= 0) throw new InvalidOperationException(
+                        "Invalid chunk size requested: chunk sizes must be positive.");
+                    _lastRequestedChunkSize = nextChunkSize;
+
+                    // Reset the list
+                    _currentChunk.Clear();
+                    _currentChunkCurrentIndex = 0;
+                    if (nextChunkSize > _currentChunk.Capacity) _currentChunk.Capacity = nextChunkSize;
+
+                    // Try to grab the next chunk of data
+                    lock (_parentEnumerable._sharedEnumerator)
+                    {
+                        // If we've already discovered that no more elements exist (and we've gotten this
+                        // far, which means we don't have any elements cached), we're done.
+                        if (_parentEnumerable._noMoreElements) return false;
+
+                        // Get another chunk
+                        for (int i = 0; i < nextChunkSize; i++)
+                        {
+                            // If there are no more elements to be retrieved from the shared enumerator, mark
+                            // that so that other partitions don't have to check again. Return whether we
+                            // were able to retrieve any data at all.
+                            if (!_parentEnumerable._sharedEnumerator.MoveNext())
+                            {
+                                _parentEnumerable._noMoreElements = true;
+                                return _currentChunk.Count > 0;
+                            }
+
+                            ++_parentEnumerable._nextSharedIndex;
+                            _currentChunk.Add(new KeyValuePair<long, T>(
+                                _parentEnumerable._nextSharedIndex,
+                                _parentEnumerable._sharedEnumerator.Current));
+                        }
+                    }
+
+                    // We got at least some data
+                    return true;
+                }
+
+                public KeyValuePair<long, T> Current
+                {
+                    get
+                    {
+                        if (_currentChunkCurrentIndex >= _currentChunk.Count)
+                        {
+                            throw new InvalidOperationException("There is no current item.");
+                        }
+                        return _currentChunk[_currentChunkCurrentIndex];
+                    }
+                }
+
+                public void Dispose()
+                {
+                    if (!_disposed)
+                    {
+                        _parentEnumerable.DisposeEnumerator(this);
+                        _disposed = true;
+                    }
+                }
+
+                object IEnumerator.Current { get { return Current; } }
+                public void Reset() { throw new NotSupportedException(); }
+            }
+
+            public void Dispose()
+            {
+                if (!_disposed)
+                {
+                    if (!_referenceCountForDisposal) _sharedEnumerator.Dispose();
+                    _disposed = true;
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Partitioners/SingleItemPartitioner.cs b/trunk/Libraries/ParallelExtensionsExtras/Partitioners/SingleItemPartitioner.cs
new file mode 100644 (file)
index 0000000..48a469d
--- /dev/null
@@ -0,0 +1,173 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: SingleItemPartitioner.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Threading;
+
+namespace System.Collections.Concurrent.Partitioners
+{
+    /// <summary>Partitions a data source one item at a time.</summary>
+    public static class SingleItemPartitioner
+    {
+        /// <summary>Creates a partitioner for an enumerable that partitions it one item at a time.</summary>
+        /// <typeparam name="T">Specifies the type of data contained in the enumerable.</typeparam>
+        /// <param name="source">The source enumerable to be partitioned.</param>
+        /// <returns>The partitioner.</returns>
+        public static OrderablePartitioner<T> Create<T>(IEnumerable<T> source)
+        {
+            if (source == null) throw new ArgumentNullException("source");
+            else if (source is IList<T>) return new SingleItemIListPartitioner<T>((IList<T>)source);
+            else return new SingleItemEnumerablePartitioner<T>(source);
+        }
+
+        /// <summary>Partitions an enumerable one item at a time.</summary>
+        /// <typeparam name="T">Specifies the type of data contained in the list.</typeparam>
+        private sealed class SingleItemEnumerablePartitioner<T> : OrderablePartitioner<T>
+        {
+            /// <summary>The enumerable to be partitioned.</summary>
+            private readonly IEnumerable<T> _source;
+
+            /// <summary>Initializes the partitioner.</summary>
+            /// <param name="source">The enumerable to be partitioned.</param>
+            internal SingleItemEnumerablePartitioner(IEnumerable<T> source) : base(true, false, true) { _source = source; }
+
+            /// <summary>Gets whether this partitioner supports dynamic partitioning (it does).</summary>
+            public override bool SupportsDynamicPartitions { get { return true; } }
+
+            public override IList<IEnumerator<KeyValuePair<long, T>>> GetOrderablePartitions(int partitionCount)
+            {
+                if (partitionCount < 1) throw new ArgumentOutOfRangeException("partitionCount");
+                var dynamicPartitioner = new DynamicGenerator(_source.GetEnumerator(), false);
+                return (from i in Enumerable.Range(0, partitionCount) select dynamicPartitioner.GetEnumerator()).ToList();
+            }
+
+            /// <summary>Gets a list of the specified static number of partitions.</summary>
+            /// <param name="partitionCount">The static number of partitions to create.</param>
+            /// <returns>The list of created partitions ready to be iterated.</returns>
+            public override IEnumerable<KeyValuePair<long, T>> GetOrderableDynamicPartitions()
+            {
+                return new DynamicGenerator(_source.GetEnumerator(), true);
+            }
+
+            /// <summary>Dynamically generates a partitions on a shared enumerator.</summary>
+            private class DynamicGenerator : IEnumerable<KeyValuePair<long, T>>, IDisposable
+            {
+                /// <summary>The source enumerator shared amongst all partitions.</summary>
+                private readonly IEnumerator<T> _sharedEnumerator;
+                /// <summary>The next available position to be yielded.</summary>
+                private long _nextAvailablePosition;
+                /// <summary>The number of partitions remaining to be disposed, potentially including this dynamic generator.</summary>
+                private int _remainingPartitions;
+                /// <summary>Whether this dynamic partitioner has been disposed.</summary>
+                private bool _disposed;
+
+                /// <summary>Initializes the dynamic generator.</summary>
+                /// <param name="sharedEnumerator">The enumerator shared by all partitions.</param>
+                /// <param name="requiresDisposal">Whether this generator will be disposed.</param>
+                public DynamicGenerator(IEnumerator<T> sharedEnumerator, bool requiresDisposal)
+                {
+                    _sharedEnumerator = sharedEnumerator;
+                    _nextAvailablePosition = -1;
+                    _remainingPartitions = requiresDisposal ? 1 : 0;
+                }
+
+                /// <summary>Closes the shared enumerator if all other partitions have completed.</summary>
+                void IDisposable.Dispose()
+                {
+                    if (!_disposed && Interlocked.Decrement(ref _remainingPartitions) == 0)
+                    {
+                        _disposed = true;
+                        _sharedEnumerator.Dispose();
+                    }
+                }
+
+                /// <summary>Increments the number of partitions in use and returns a new partition.</summary>
+                /// <returns>The new partition.</returns>
+                public IEnumerator<KeyValuePair<long, T>> GetEnumerator()
+                {
+                    Interlocked.Increment(ref _remainingPartitions);
+                    return GetEnumeratorCore();
+                }
+                IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
+
+                /// <summary>Creates a partition.</summary>
+                /// <returns>The new partition.</returns>
+                private IEnumerator<KeyValuePair<long, T>> GetEnumeratorCore()
+                {
+                    try
+                    {
+                        while (true)
+                        {
+                            T nextItem;
+                            long position;
+                            lock (_sharedEnumerator)
+                            {
+                                if (_sharedEnumerator.MoveNext())
+                                {
+                                    position = _nextAvailablePosition++;
+                                    nextItem = _sharedEnumerator.Current;
+                                }
+                                else yield break;
+                            }
+                            yield return new KeyValuePair<long,T>(position, nextItem);
+                        }
+                    }
+                    finally { if (Interlocked.Decrement(ref _remainingPartitions) == 0) _sharedEnumerator.Dispose(); }
+                }
+            }
+        }
+
+        /// <summary>Partitions a list one item at a time.</summary>
+        /// <typeparam name="T">Specifies the type of data contained in the list.</typeparam>
+        private sealed class SingleItemIListPartitioner<T> : OrderablePartitioner<T>
+        {
+            /// <summary>The list to be partitioned.</summary>
+            private readonly IList<T> _source;
+
+            /// <summary>Initializes the partitioner.</summary>
+            /// <param name="source">The list to be partitioned.</param>
+            internal SingleItemIListPartitioner(IList<T> source) : base(true, false, true) { _source = source; }
+
+            /// <summary>Gets whether this partitioner supports dynamic partitioning (it does).</summary>
+            public override bool SupportsDynamicPartitions { get { return true; } }
+
+            /// <summary>Gets a list of the specified static number of partitions.</summary>
+            /// <param name="partitionCount">The static number of partitions to create.</param>
+            /// <returns>The list of created partitions ready to be iterated.</returns>
+            public override IList<IEnumerator<KeyValuePair<long, T>>> GetOrderablePartitions(int partitionCount)
+            {
+                if (partitionCount < 1) throw new ArgumentOutOfRangeException("partitionCount");
+                var dynamicPartitioner = GetOrderableDynamicPartitions();
+                return (from i in Enumerable.Range(0, partitionCount) select dynamicPartitioner.GetEnumerator()).ToList();
+            }
+
+            /// <summary>Creates a dynamic partitioner for creating a dynamic number of partitions.</summary>
+            /// <returns>The dynamic partitioner.</returns>
+            public override IEnumerable<KeyValuePair<long, T>> GetOrderableDynamicPartitions()
+            {
+                return GetOrderableDynamicPartitionsCore(_source, new StrongBox<int>(0));
+            }
+
+            /// <summary>An enumerable that creates individual enumerators that all work together to partition the list.</summary>
+            /// <param name="source">The list being partitioned.</param>
+            /// <param name="nextIteration">An integer shared between partitions denoting the next available index in the source.</param>
+            /// <returns>An enumerable that generates enumerators which participate in partitioning the list.</returns>
+            private static IEnumerable<KeyValuePair<long, T>> GetOrderableDynamicPartitionsCore(IList<T> source, StrongBox<int> nextIteration)
+            {
+                while (true)
+                {
+                    var iteration = Interlocked.Increment(ref nextIteration.Value) - 1;
+                    if (iteration >= 0 && iteration < source.Count) yield return new KeyValuePair<long, T>(iteration, source[iteration]);
+                    else yield break;
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Properties/AssemblyInfo.cs b/trunk/Libraries/ParallelExtensionsExtras/Properties/AssemblyInfo.cs
new file mode 100644 (file)
index 0000000..c6af0fd
--- /dev/null
@@ -0,0 +1,24 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: AssemblyInfo.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Parallel Extensions Extras")]
+[assembly: AssemblyDescription("Samples and extra functionality for use with Parallel Extensions to the .NET Framework")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Parallel Extensions Extras")]
+[assembly: AssemblyCopyright("Copyright © Microsoft Corporation.  All rights reserved.")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+[assembly: ComVisible(false)]
+[assembly: Guid("ae914514-52ad-4769-a503-654f1a708dcc")]
+[assembly: AssemblyVersion("1.2.0.0")]
+[assembly: AssemblyFileVersion("1.2.0.0")]
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/ConcurrentExclusiveInterleave.cs b/trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/ConcurrentExclusiveInterleave.cs
new file mode 100644 (file)
index 0000000..cafb815
--- /dev/null
@@ -0,0 +1,282 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: ConcurrentExclusiveInterleave.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Diagnostics;
+
+namespace System.Threading.Tasks.Schedulers
+{
+    /// <summary>Provides concurrent and exclusive task schedulers that coordinate.</summary>
+    [DebuggerDisplay("ConcurrentTasksWaiting={ConcurrentTaskCount}, ExclusiveTasksWaiting={ExclusiveTaskCount}")]
+    [DebuggerTypeProxy(typeof(ConcurrentExclusiveInterleaveDebugView))]
+    public sealed class ConcurrentExclusiveInterleave
+    {
+        /// <summary>Provides a debug view for ConcurrentExclusiveInterleave.</summary>
+        internal class ConcurrentExclusiveInterleaveDebugView
+        {
+            /// <summary>The interleave being debugged.</summary>
+            private ConcurrentExclusiveInterleave _interleave;
+
+            /// <summary>Initializes the debug view.</summary>
+            /// <param name="interleave">The interleave being debugged.</param>
+            public ConcurrentExclusiveInterleaveDebugView(ConcurrentExclusiveInterleave interleave)
+            {
+                if (interleave == null) throw new ArgumentNullException("interleave");
+                _interleave = interleave;
+            }
+
+            public IEnumerable<Task> ExclusiveTasksWaiting { get { return _interleave._exclusiveTaskScheduler.Tasks; } }
+            /// <summary>Gets the number of tasks waiting to run concurrently.</summary>
+            public IEnumerable<Task> ConcurrentTasksWaiting { get { return _interleave._concurrentTaskScheduler.Tasks; } }
+            /// <summary>Gets a description of the processing task for debugging purposes.</summary>
+            public Task InterleaveTask { get { return _interleave._taskExecuting; } }
+        }
+
+        /// <summary>Synchronizes all activity in this type and its generated schedulers.</summary>
+        private readonly object _internalLock;
+        /// <summary>The parallel options used by the asynchronous task and parallel loops.</summary>
+        private ParallelOptions _parallelOptions;
+        /// <summary>The scheduler used to queue and execute "reader" tasks that may run concurrently with other readers.</summary>
+        private ConcurrentExclusiveTaskScheduler _concurrentTaskScheduler;
+        /// <summary>The scheduler used to queue and execute "writer" tasks that must run exclusively while no other tasks for this interleave are running.</summary>
+        private ConcurrentExclusiveTaskScheduler _exclusiveTaskScheduler;
+        /// <summary>Whether this interleave has queued its processing task.</summary>
+        private Task _taskExecuting;
+        /// <summary>Whether the exclusive processing of a task should include all of its children as well.</summary>
+        private bool _exclusiveProcessingIncludesChildren;
+
+        /// <summary>Initialies the ConcurrentExclusiveInterleave.</summary>
+        public ConcurrentExclusiveInterleave() : 
+            this(TaskScheduler.Current, false) {}
+
+        /// <summary>Initialies the ConcurrentExclusiveInterleave.</summary>
+        /// <param name="exclusiveProcessingIncludesChildren">Whether the exclusive processing of a task should include all of its children as well.</param>
+        public ConcurrentExclusiveInterleave(bool exclusiveProcessingIncludesChildren) : 
+            this(TaskScheduler.Current, exclusiveProcessingIncludesChildren) {}
+
+        /// <summary>Initialies the ConcurrentExclusiveInterleave.</summary>
+        /// <param name="targetScheduler">The target scheduler on which this interleave should execute.</param>
+        public ConcurrentExclusiveInterleave(TaskScheduler targetScheduler) :
+            this(targetScheduler, false) {}
+
+        /// <summary>Initialies the ConcurrentExclusiveInterleave.</summary>
+        /// <param name="targetScheduler">The target scheduler on which this interleave should execute.</param>
+        /// <param name="exclusiveProcessingIncludesChildren">Whether the exclusive processing of a task should include all of its children as well.</param>
+        public ConcurrentExclusiveInterleave(TaskScheduler targetScheduler, bool exclusiveProcessingIncludesChildren)
+        {
+            // A scheduler must be provided
+            if (targetScheduler == null) throw new ArgumentNullException("targetScheduler");
+
+            // Create the state for this interleave
+            _internalLock = new object();
+            _exclusiveProcessingIncludesChildren = exclusiveProcessingIncludesChildren;
+            _parallelOptions = new ParallelOptions() { TaskScheduler = targetScheduler };
+            _concurrentTaskScheduler = new ConcurrentExclusiveTaskScheduler(this, new Queue<Task>(), targetScheduler.MaximumConcurrencyLevel);
+            _exclusiveTaskScheduler = new ConcurrentExclusiveTaskScheduler(this, new Queue<Task>(), 1);
+        }
+
+        /// <summary>
+        /// Gets a TaskScheduler that can be used to schedule tasks to this interleave
+        /// that may run concurrently with other tasks on this interleave.
+        /// </summary>
+        public TaskScheduler ConcurrentTaskScheduler { get { return _concurrentTaskScheduler; } }
+        /// <summary>
+        /// Gets a TaskScheduler that can be used to schedule tasks to this interleave
+        /// that must run exclusively with regards to other tasks on this interleave.
+        /// </summary>
+        public TaskScheduler ExclusiveTaskScheduler { get { return _exclusiveTaskScheduler; } }
+
+        /// <summary>Gets the number of tasks waiting to run exclusively.</summary>
+        private int ExclusiveTaskCount { get { lock (_internalLock) return _exclusiveTaskScheduler.Tasks.Count; } }
+        /// <summary>Gets the number of tasks waiting to run concurrently.</summary>
+        private int ConcurrentTaskCount { get { lock (_internalLock) return _concurrentTaskScheduler.Tasks.Count; } }
+
+        /// <summary>Notifies the interleave that new work has arrived to be processed.</summary>
+        /// <remarks>Must only be called while holding the lock.</remarks>
+        internal void NotifyOfNewWork()
+        {
+            // If a task is already running, bail.  
+            if (_taskExecuting != null) return;
+
+            // Otherwise, run the processor. Store the task and then start it to ensure that 
+            // the assignment happens before the body of the task runs.
+            _taskExecuting = new Task(ConcurrentExclusiveInterleaveProcessor, CancellationToken.None, TaskCreationOptions.None);
+            _taskExecuting.Start(_parallelOptions.TaskScheduler);
+        }
+
+        /// <summary>The body of the async processor to be run in a Task.  Only one should be running at a time.</summary>
+        /// <remarks>This has been separated out into its own method to improve the Parallel Tasks window experience.</remarks>
+        private void ConcurrentExclusiveInterleaveProcessor()
+        {
+            // Run while there are more tasks to be processed.  We assume that the first time through,
+            // there are tasks.  If they aren't, worst case is we try to process and find none.
+            bool runTasks = true;
+            bool cleanupOnExit = true;
+            while (runTasks)
+            {
+                try
+                {
+                    // Process all waiting exclusive tasks
+                    foreach (var task in GetExclusiveTasks())
+                    {
+                        _exclusiveTaskScheduler.ExecuteTask(task);
+
+                        // Just because we executed the task doesn't mean it's "complete",
+                        // if it has child tasks that have not yet completed
+                        // and will complete later asynchronously.  To account for this, 
+                        // if a task isn't yet completed, leave the interleave processor 
+                        // but leave it still in a running state.  When the task completes,
+                        // we'll come back in and keep going.  Note that the children
+                        // must not be scheduled to this interleave, or this will deadlock.
+                        if (_exclusiveProcessingIncludesChildren && !task.IsCompleted)
+                        {
+                            cleanupOnExit = false;
+                            task.ContinueWith(_ => ConcurrentExclusiveInterleaveProcessor(), _parallelOptions.TaskScheduler);
+                            return;
+                        }
+                    }
+
+                    // Process all waiting concurrent tasks *until* any exclusive tasks show up, in which
+                    // case we want to switch over to processing those (by looping around again).
+                    Parallel.ForEach(GetConcurrentTasksUntilExclusiveExists(), _parallelOptions,
+                        ExecuteConcurrentTask);
+                }
+                finally
+                {
+                    if (cleanupOnExit)
+                    {
+                        lock (_internalLock)
+                        {
+                            // If there are no tasks remaining, we're done. If there are, loop around and go again.
+                            if (_concurrentTaskScheduler.Tasks.Count == 0 && _exclusiveTaskScheduler.Tasks.Count == 0)
+                            {
+                                _taskExecuting = null;
+                                runTasks = false;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        /// <summary>Runs a concurrent task.</summary>
+        /// <param name="task">The task to execute.</param>
+        /// <remarks>This has been separated out into its own method to improve the Parallel Tasks window experience.</remarks>
+        private void ExecuteConcurrentTask(Task task) { _concurrentTaskScheduler.ExecuteTask(task); }
+
+        /// <summary>
+        /// Gets an enumerable that yields waiting concurrent tasks one at a time until
+        /// either there are no more concurrent tasks or there are any exclusive tasks.
+        /// </summary>
+        private IEnumerable<Task> GetConcurrentTasksUntilExclusiveExists()
+        {
+            while (true)
+            {
+                Task foundTask = null;
+                lock (_internalLock)
+                {
+                    if (_exclusiveTaskScheduler.Tasks.Count == 0 &&
+                        _concurrentTaskScheduler.Tasks.Count > 0)
+                    {
+                        foundTask = _concurrentTaskScheduler.Tasks.Dequeue();
+                    }
+                }
+                if (foundTask != null) yield return foundTask;
+                else yield break;
+            }
+        }
+
+        /// <summary>
+        /// Gets an enumerable that yields all of the exclusive tasks one at a time.
+        /// </summary>
+        private IEnumerable<Task> GetExclusiveTasks()
+        {
+            while (true)
+            {
+                Task foundTask = null;
+                lock (_internalLock)
+                {
+                    if (_exclusiveTaskScheduler.Tasks.Count > 0) foundTask = _exclusiveTaskScheduler.Tasks.Dequeue();
+                }
+                if (foundTask != null) yield return foundTask;
+                else yield break;
+            }
+        }
+
+        /// <summary>
+        /// A scheduler shim used to queue tasks to the interleave and execute those tasks on request of the interleave.
+        /// </summary>
+        private class ConcurrentExclusiveTaskScheduler : TaskScheduler
+        {
+            /// <summary>The parent interleave.</summary>
+            private readonly ConcurrentExclusiveInterleave _interleave;
+            /// <summary>The maximum concurrency level for the scheduler.</summary>
+            private readonly int _maximumConcurrencyLevel;
+            /// <summary>Whether a Task is currently being processed on this thread.</summary>
+            private ThreadLocal<bool> _processingTaskOnCurrentThread = new ThreadLocal<bool>();
+
+            /// <summary>Initializes the scheduler.</summary>
+            /// <param name="interleave">The parent interleave.</param>
+            /// <param name="tasks">The queue to store queued tasks into.</param>
+            internal ConcurrentExclusiveTaskScheduler(ConcurrentExclusiveInterleave interleave, Queue<Task> tasks, int maximumConcurrencyLevel)
+            {
+                if (interleave == null) throw new ArgumentNullException("interleave");
+                if (tasks == null) throw new ArgumentNullException("tasks");
+                _interleave = interleave;
+                _maximumConcurrencyLevel = maximumConcurrencyLevel;
+                Tasks = tasks;
+            }
+
+            /// <summary>Gets the maximum concurrency level this scheduler is able to support.</summary>
+            public override int MaximumConcurrencyLevel { get { return _maximumConcurrencyLevel; } }
+
+            /// <summary>Gets the queue of tasks for this scheduler.</summary>
+            internal Queue<Task> Tasks { get; private set; }
+
+            /// <summary>Queues a task to the scheduler.</summary>
+            /// <param name="task">The task to be queued.</param>
+            protected override void QueueTask(Task task)
+            {
+                lock (_interleave._internalLock)
+                {
+                    Tasks.Enqueue(task);
+                    _interleave.NotifyOfNewWork();
+                }
+            }
+
+            /// <summary>Executes a task on this scheduler.</summary>
+            /// <param name="task">The task to be executed.</param>
+            internal void ExecuteTask(Task task) 
+            {
+                var processingTaskOnCurrentThread = _processingTaskOnCurrentThread.Value;
+                if (!processingTaskOnCurrentThread) _processingTaskOnCurrentThread.Value = true;
+                base.TryExecuteTask(task);
+                if (!processingTaskOnCurrentThread) _processingTaskOnCurrentThread.Value = false;
+            }
+
+            /// <summary>Tries to execute the task synchronously on this scheduler.</summary>
+            /// <param name="task">The task to execute.</param>
+            /// <param name="taskWasPreviouslyQueued">Whether the task was previously queued to the scheduler.</param>
+            /// <returns>true if the task could be executed; otherwise, false.</returns>
+            protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
+            {
+                if (_processingTaskOnCurrentThread.Value)
+                {
+                    var t = new Task<bool>(state => TryExecuteTask((Task)state), task);
+                    t.RunSynchronously(_interleave._parallelOptions.TaskScheduler);
+                    return t.Result;
+                }
+                return false;
+            }
+
+            /// <summary>Gets for debugging purposes the tasks scheduled to this scheduler.</summary>
+            /// <returns>An enumerable of the tasks queued.</returns>
+            protected override IEnumerable<Task> GetScheduledTasks() { return Tasks; }
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/CurrentThreadTaskScheduler.cs b/trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/CurrentThreadTaskScheduler.cs
new file mode 100644 (file)
index 0000000..e773afa
--- /dev/null
@@ -0,0 +1,43 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: CurrentThreadTaskScheduler.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Linq;
+
+namespace System.Threading.Tasks.Schedulers
+{
+    /// <summary>Provides a task scheduler that runs tasks on the current thread.</summary>
+    public sealed class CurrentThreadTaskScheduler : TaskScheduler
+    {
+        /// <summary>Runs the provided Task synchronously on the current thread.</summary>
+        /// <param name="task">The task to be executed.</param>
+        protected override void QueueTask(Task task)
+        {
+            TryExecuteTask(task);
+        }
+
+        /// <summary>Runs the provided Task synchronously on the current thread.</summary>
+        /// <param name="task">The task to be executed.</param>
+        /// <param name="taskWasPreviouslyQueued">Whether the Task was previously queued to the scheduler.</param>
+        /// <returns>True if the Task was successfully executed; otherwise, false.</returns>
+        protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
+        {
+            return TryExecuteTask(task);
+        }
+
+        /// <summary>Gets the Tasks currently scheduled to this scheduler.</summary>
+        /// <returns>An empty enumerable, as Tasks are never queued, only executed.</returns>
+        protected override IEnumerable<Task> GetScheduledTasks()
+        {
+            return Enumerable.Empty<Task>();
+        }
+
+        /// <summary>Gets the maximum degree of parallelism for this scheduler.</summary>
+        public override int MaximumConcurrencyLevel { get { return 1; } }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/IOCompletionPortTaskScheduler.cs b/trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/IOCompletionPortTaskScheduler.cs
new file mode 100644 (file)
index 0000000..f3aa6f9
--- /dev/null
@@ -0,0 +1,192 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: IOCompletionPortTaskScheduler.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
+using Microsoft.Win32.SafeHandles;
+
+namespace System.Threading.Tasks.Schedulers
+{
+    /// <summary>Provides a TaskScheduler that uses an I/O completion port for concurrency control.</summary>
+    public sealed class IOCompletionPortTaskScheduler : TaskScheduler, IDisposable
+    {
+        /// <summary>The queue of tasks to be scheduled.</summary>
+        private readonly ConcurrentQueue<Task> m_tasks;
+        /// <summary>The I/O completion port to use for concurrency control.</summary>
+        private readonly IOCompletionPort m_iocp;
+        /// <summary>Whether the current thread is a scheduler thread.</summary>
+        private ThreadLocal<bool> m_schedulerThread;
+        /// <summary>Event used to wait for all threads to shutdown.</summary>
+        private CountdownEvent m_remainingThreadsToShutdown;
+
+        /// <summary>Initializes the IOCompletionPortTaskScheduler.</summary>
+        /// <param name="maxConcurrencyLevel">The maximum number of threads in the scheduler to be executing concurrently.</param>
+        /// <param name="numAvailableThreads">The number of threads to have available in the scheduler for executing tasks.</param>
+        public IOCompletionPortTaskScheduler(int maxConcurrencyLevel, int numAvailableThreads)
+        {
+            // Validate arguments
+            if (maxConcurrencyLevel < 1) throw new ArgumentNullException("maxConcurrencyLevel");
+            if (numAvailableThreads < 1) throw new ArgumentNullException("numAvailableThreads");
+
+            m_tasks = new ConcurrentQueue<Task>();
+            m_iocp = new IOCompletionPort(maxConcurrencyLevel);
+            m_schedulerThread = new ThreadLocal<bool>();
+            m_remainingThreadsToShutdown = new CountdownEvent(numAvailableThreads);
+
+            // Create and start the threads
+            for (int i = 0; i < numAvailableThreads; i++)
+            {
+                new Thread(() =>
+                {
+                    try
+                    {
+                        // Note that this is a scheduler thread.  Used for inlining checks.
+                        m_schedulerThread.Value = true;
+
+                        // Continually wait on the I/O completion port until 
+                        // there's a work item, then process it.
+                        while (m_iocp.WaitOne())
+                        {
+                            Task next;
+                            if (m_tasks.TryDequeue(out next)) TryExecuteTask(next);
+                        }
+                    }
+                    finally { m_remainingThreadsToShutdown.Signal(); }
+                }) { IsBackground = true }.Start();
+            }
+        }
+
+        /// <summary>Dispose of the scheduler.</summary>
+        public void Dispose()
+        {
+            // Close the I/O completion port.  This will cause any threads blocked
+            // waiting for items to wake up.
+            m_iocp.Dispose();
+
+            // Wait for all threads to shutdown.  This could cause deadlock
+            // if the current thread is calling Dispose or is part of such a cycle.
+            m_remainingThreadsToShutdown.Wait();
+            m_remainingThreadsToShutdown.Dispose();
+
+            // Clean up remaining state
+            m_schedulerThread.Dispose();
+        }
+
+        /// <summary>Gets a list of all tasks scheduled to this scheduler.</summary>
+        /// <returns>An enumerable of all scheduled tasks.</returns>
+        protected override IEnumerable<Task> GetScheduledTasks() { return m_tasks.ToArray(); }
+
+        /// <summary>Queues a task to this scheduler for execution.</summary>
+        /// <param name="task">The task to be executed.</param>
+        protected override void QueueTask(Task task)
+        {
+            // Store the task and let the I/O completion port know that more work has arrived.
+            m_tasks.Enqueue(task);
+            m_iocp.NotifyOne();
+        }
+
+        /// <summary>Try to execute a task on the current thread.</summary>
+        /// <param name="task">The task to execute.</param>
+        /// <param name="taskWasPreviouslyQueued">Whether the task was previously queued to this scheduler.</param>
+        /// <returns>Whether the task was executed.</returns>
+        protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
+        {
+            // Only inline from scheduler threads.  This is to ensure concurrency control 
+            // is able to handle inlining as well.
+            return m_schedulerThread.Value && TryExecuteTask(task);
+        }
+
+        /// <summary>Provides a simple managed wrapper for an I/O completion port.</summary>
+        private sealed class IOCompletionPort : IDisposable
+        {
+            /// <summary>Infinite timeout value to use for GetQueuedCompletedStatus.</summary>
+            private UInt32 INFINITE_TIMEOUT = unchecked((UInt32)Timeout.Infinite);
+            /// <summary>An invalid file handle value.</summary>
+            private IntPtr INVALID_FILE_HANDLE = unchecked((IntPtr)(-1));
+            /// <summary>An invalid I/O completion port handle value.</summary>
+            private IntPtr INVALID_IOCP_HANDLE = IntPtr.Zero;
+
+            /// <summary>The I/O completion porth handle.</summary>
+            private SafeFileHandle m_handle;
+
+            /// <summary>Initializes the I/O completion port.</summary>
+            /// <param name="maxConcurrencyLevel">The maximum concurrency level allowed by the I/O completion port.</param>
+            public IOCompletionPort(Int32 maxConcurrencyLevel)
+            {
+                // Validate the argument and create the port.
+                if (maxConcurrencyLevel < 1) throw new ArgumentOutOfRangeException("maxConcurrencyLevel");
+                m_handle = CreateIoCompletionPort(INVALID_FILE_HANDLE, INVALID_IOCP_HANDLE, UIntPtr.Zero, (UInt32)maxConcurrencyLevel);
+            }
+
+            /// <summary>Clean up.</summary>
+            public void Dispose() { m_handle.Dispose(); }
+
+            /// <summary>Notify that I/O completion port that new work is available.</summary>
+            public void NotifyOne()
+            {
+                if (!PostQueuedCompletionStatus(m_handle, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero)) 
+                    throw new Win32Exception();
+            }
+
+            /// <summary>Waits for an item on the I/O completion port.</summary>
+            /// <returns>true if an item was available; false if the completion port closed before an item could be retrieved.</returns>
+            public bool WaitOne()
+            {
+                // Wait for an item to be posted.
+                // DangerousGetHandle is used so that the safe handle can be closed even while blocked in the call to GetQueuedCompletionStatus.
+                UInt32 lpNumberOfBytes;
+                IntPtr lpCompletionKey, lpOverlapped;
+                if (!GetQueuedCompletionStatus(m_handle.DangerousGetHandle(), out lpNumberOfBytes, out lpCompletionKey, out lpOverlapped, INFINITE_TIMEOUT))
+                {
+                    int errorCode = Marshal.GetLastWin32Error();
+                    if (errorCode == 735 /*ERROR_ABANDONED_WAIT_0*/ || errorCode == 6 /*INVALID_HANDLE*/)
+                        return false;
+                    else
+                        throw new Win32Exception(errorCode);
+                }
+                return true;
+            }
+
+            /// <summary>
+            /// Creates an input/output (I/O) completion port and associates it with a specified file handle, 
+            /// or creates an I/O completion port that is not yet associated with a file handle, allowing association at a later time.
+            /// </summary>
+            /// <param name="fileHandle">An open file handle or INVALID_HANDLE_VALUE.</param>
+            /// <param name="existingCompletionPort">A handle to an existing I/O completion port or NULL.</param>
+            /// <param name="completionKey">The per-handle user-defined completion key that is included in every I/O completion packet for the specified file handle.</param>
+            /// <param name="numberOfConcurrentThreads">The maximum number of threads that the operating system can allow to concurrently process I/O completion packets for the I/O completion port.</param>
+            /// <returns>If the function succeeds, the return value is the handle to an I/O completion port.  If the function fails, the return value is NULL.</returns>
+            [DllImport("kernel32.dll", SetLastError = true)]
+            private static extern SafeFileHandle CreateIoCompletionPort(
+                  IntPtr fileHandle, IntPtr existingCompletionPort, UIntPtr completionKey, UInt32 numberOfConcurrentThreads);
+
+            /// <summary>Attempts to dequeue an I/O completion packet from the specified I/O completion port.</summary>
+            /// <param name="completionPort">A handle to the completion port.</param>
+            /// <param name="lpNumberOfBytes">A pointer to a variable that receives the number of bytes transferred during an I/O operation that has completed.</param>
+            /// <param name="lpCompletionKey">A pointer to a variable that receives the completion key value associated with the file handle whose I/O operation has completed.</param>
+            /// <param name="lpOverlapped">A pointer to a variable that receives the address of the OVERLAPPED structure that was specified when the completed I/O operation was started.</param>
+            /// <param name="dwMilliseconds">The number of milliseconds that the caller is willing to wait for a completion packet to appear at the completion port. </param>
+            /// <returns>Returns nonzero (TRUE) if successful or zero (FALSE) otherwise.</returns>
+            [DllImport("kernel32.dll", SetLastError = true)]
+            private static extern Boolean GetQueuedCompletionStatus(
+                IntPtr completionPort, out UInt32 lpNumberOfBytes, out IntPtr lpCompletionKey, out IntPtr lpOverlapped, UInt32 dwMilliseconds);
+
+            /// <summary>Posts an I/O completion packet to an I/O completion port.</summary>
+            /// <param name="completionPort">A handle to the completion port.</param>
+            /// <param name="dwNumberOfBytesTransferred">The value to be returned through the lpNumberOfBytesTransferred parameter of the GetQueuedCompletionStatus function.</param>
+            /// <param name="dwCompletionKey">The value to be returned through the lpCompletionKey parameter of the GetQueuedCompletionStatus function.</param>
+            /// <param name="lpOverlapped">The value to be returned through the lpOverlapped parameter of the GetQueuedCompletionStatus function.</param>
+            /// <returns>If the function succeeds, the return value is nonzero. If the function fails, the return value is zero.</returns>
+            [DllImport("kernel32.dll", SetLastError = true)]
+            private static extern Boolean PostQueuedCompletionStatus(
+                SafeFileHandle completionPort, IntPtr dwNumberOfBytesTransferred, IntPtr dwCompletionKey, IntPtr lpOverlapped);
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/IOTaskScheduler.cs b/trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/IOTaskScheduler.cs
new file mode 100644 (file)
index 0000000..0667e01
--- /dev/null
@@ -0,0 +1,88 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: IOTaskScheduler.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace System.Threading.Tasks.Schedulers
+{
+    /// <summary>Provides a task scheduler that targets the I/O ThreadPool.</summary>
+    public sealed class IOTaskScheduler : TaskScheduler, IDisposable
+    {
+        /// <summary>Represents a task queued to the I/O pool.</summary>
+        private unsafe class WorkItem
+        {
+            internal IOTaskScheduler _scheduler;
+            internal NativeOverlapped* _pNOlap;
+            internal Task _task;
+
+            internal void Callback(uint errorCode, uint numBytes, NativeOverlapped* pNOlap)
+            {
+                // Execute the task
+                _scheduler.TryExecuteTask(_task);
+
+                // Put this item back into the pool for someone else to use
+                var pool = _scheduler._availableWorkItems;
+                if (pool != null) pool.PutObject(this);
+                else Overlapped.Free(pNOlap);
+            }
+        }
+
+        // A pool of available WorkItem instances that can be used to schedule tasks
+        private ObjectPool<WorkItem> _availableWorkItems;
+
+        /// <summary>Initializes a new instance of the IOTaskScheduler class.</summary>
+        public unsafe IOTaskScheduler()
+        {
+            // Configure the object pool of work items
+            _availableWorkItems = new ObjectPool<WorkItem>(() =>
+            {
+                var wi = new WorkItem { _scheduler = this };
+                wi._pNOlap = new Overlapped().UnsafePack(wi.Callback, null);
+                return wi;
+            }, new ConcurrentStack<WorkItem>());
+        }
+
+        /// <summary>Queues a task to the scheduler for execution on the I/O ThreadPool.</summary>
+        /// <param name="task">The Task to queue.</param>
+        protected override unsafe void QueueTask(Task task)
+        {
+            var pool = _availableWorkItems;
+            if (pool == null) throw new ObjectDisposedException(GetType().Name);
+            var wi = pool.GetObject();
+            wi._task = task;
+            ThreadPool.UnsafeQueueNativeOverlapped(wi._pNOlap);
+        }
+
+        /// <summary>Executes a task on the current thread.</summary>
+        /// <param name="task">The task to be executed.</param>
+        /// <param name="taskWasPreviouslyQueued">Ignored.</param>
+        /// <returns>Whether the task could be executed.</returns>
+        protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
+        {
+            return TryExecuteTask(task);
+        }
+
+        /// <summary>Disposes of resources used by the scheduler.</summary>
+        public unsafe void Dispose()
+        {
+            var pool = _availableWorkItems;
+            _availableWorkItems = null;
+            var workItems = pool.ToArrayAndClear();
+            foreach (WorkItem wi in workItems) Overlapped.Free(wi._pNOlap);
+            // NOTE: A window exists where some number of NativeOverlapped ptrs could
+            // be leaked, if the call to Dispose races with work items completing.
+        }
+
+        /// <summary>Gets an enumerable of tasks queued to the scheduler.</summary>
+        /// <returns>An enumerable of tasks queued to the scheduler.</returns>
+        /// <remarks>This implementation will always return an empty enumerable.</remarks>
+        protected override IEnumerable<Task> GetScheduledTasks() { return Enumerable.Empty<Task>(); }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/LimitedConcurrencyLevelTaskScheduler.cs b/trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/LimitedConcurrencyLevelTaskScheduler.cs
new file mode 100644 (file)
index 0000000..757e204
--- /dev/null
@@ -0,0 +1,142 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: LimitedConcurrencyTaskScheduler.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Linq;
+
+namespace System.Threading.Tasks.Schedulers
+{
+    /// <summary>
+    /// Provides a task scheduler that ensures a maximum concurrency level while
+    /// running on top of the ThreadPool.
+    /// </summary>
+    public class LimitedConcurrencyLevelTaskScheduler : TaskScheduler
+    {
+        /// <summary>Whether the current thread is processing work items.</summary>
+        [ThreadStatic]
+        private static bool _currentThreadIsProcessingItems;
+        /// <summary>The list of tasks to be executed.</summary>
+        private readonly LinkedList<Task> _tasks = new LinkedList<Task>(); // protected by lock(_tasks)
+        /// <summary>The maximum concurrency level allowed by this scheduler.</summary>
+        private readonly int _maxDegreeOfParallelism;
+        /// <summary>Whether the scheduler is currently processing work items.</summary>
+        private int _delegatesQueuedOrRunning = 0; // protected by lock(_tasks)
+
+        /// <summary>
+        /// Initializes an instance of the LimitedConcurrencyLevelTaskScheduler class with the
+        /// specified degree of parallelism.
+        /// </summary>
+        /// <param name="maxDegreeOfParallelism">The maximum degree of parallelism provided by this scheduler.</param>
+        public LimitedConcurrencyLevelTaskScheduler(int maxDegreeOfParallelism)
+        {
+            if (maxDegreeOfParallelism < 1) throw new ArgumentOutOfRangeException("maxDegreeOfParallelism");
+            _maxDegreeOfParallelism = maxDegreeOfParallelism;
+        }
+
+        /// <summary>Queues a task to the scheduler.</summary>
+        /// <param name="task">The task to be queued.</param>
+        protected sealed override void QueueTask(Task task)
+        {
+            // Add the task to the list of tasks to be processed.  If there aren't enough
+            // delegates currently queued or running to process tasks, schedule another.
+            lock (_tasks)
+            {
+                _tasks.AddLast(task);
+                if (_delegatesQueuedOrRunning < _maxDegreeOfParallelism)
+                {
+                    ++_delegatesQueuedOrRunning;
+                    NotifyThreadPoolOfPendingWork();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Informs the ThreadPool that there's work to be executed for this scheduler.
+        /// </summary>
+        private void NotifyThreadPoolOfPendingWork()
+        {
+            ThreadPool.UnsafeQueueUserWorkItem(_ =>
+            {
+                // Note that the current thread is now processing work items.
+                // This is necessary to enable inlining of tasks into this thread.
+                _currentThreadIsProcessingItems = true;
+                try
+                {
+                    // Process all available items in the queue.
+                    while (true)
+                    {
+                        Task item;
+                        lock (_tasks)
+                        {
+                            // When there are no more items to be processed,
+                            // note that we're done processing, and get out.
+                            if (_tasks.Count == 0)
+                            {
+                                --_delegatesQueuedOrRunning;
+                                break;
+                            }
+
+                            // Get the next item from the queue
+                            item = _tasks.First.Value;
+                            _tasks.RemoveFirst();
+                        }
+
+                        // Execute the task we pulled out of the queue
+                        base.TryExecuteTask(item);
+                    }
+                }
+                // We're done processing items on the current thread
+                finally { _currentThreadIsProcessingItems = false; }
+            }, null);
+        }
+
+        /// <summary>Attempts to execute the specified task on the current thread.</summary>
+        /// <param name="task">The task to be executed.</param>
+        /// <param name="taskWasPreviouslyQueued"></param>
+        /// <returns>Whether the task could be executed on the current thread.</returns>
+        protected sealed override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
+        {
+            // If this thread isn't already processing a task, we don't support inlining
+            if (!_currentThreadIsProcessingItems) return false;
+
+            // If the task was previously queued, remove it from the queue
+            if (taskWasPreviouslyQueued) TryDequeue(task);
+
+            // Try to run the task.
+            return base.TryExecuteTask(task);
+        }
+
+        /// <summary>Attempts to remove a previously scheduled task from the scheduler.</summary>
+        /// <param name="task">The task to be removed.</param>
+        /// <returns>Whether the task could be found and removed.</returns>
+        protected sealed override bool TryDequeue(Task task)
+        {
+            lock (_tasks) return _tasks.Remove(task);
+        }
+
+        /// <summary>Gets the maximum concurrency level supported by this scheduler.</summary>
+        public sealed override int MaximumConcurrencyLevel { get { return _maxDegreeOfParallelism; } }
+
+        /// <summary>Gets an enumerable of the tasks currently scheduled on this scheduler.</summary>
+        /// <returns>An enumerable of the tasks currently scheduled.</returns>
+        protected sealed override IEnumerable<Task> GetScheduledTasks()
+        {
+            bool lockTaken = false;
+            try
+            {
+                Monitor.TryEnter(_tasks, ref lockTaken);
+                if (lockTaken) return _tasks.ToArray();
+                else throw new NotSupportedException();
+            }
+            finally
+            {
+                if (lockTaken) Monitor.Exit(_tasks);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/OrderedTaskScheduler.cs b/trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/OrderedTaskScheduler.cs
new file mode 100644 (file)
index 0000000..44ea908
--- /dev/null
@@ -0,0 +1,20 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: OrderedTaskScheduler.cs
+//
+//--------------------------------------------------------------------------
+
+namespace System.Threading.Tasks.Schedulers
+{
+    /// <summary>
+    /// Provides a task scheduler that ensures only one task is executing at a time, and that tasks
+    /// execute in the order that they were queued.
+    /// </summary>
+    public sealed class OrderedTaskScheduler : LimitedConcurrencyLevelTaskScheduler
+    {
+        /// <summary>Initializes an instance of the OrderedTaskScheduler class.</summary>
+        public OrderedTaskScheduler() : base(1) { }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/QueuedTaskScheduler.cs b/trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/QueuedTaskScheduler.cs
new file mode 100644 (file)
index 0000000..8701955
--- /dev/null
@@ -0,0 +1,612 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: QueuedTaskScheduler.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+
+namespace System.Threading.Tasks.Schedulers
+{
+    /// <summary>
+    /// Provides a TaskScheduler that provides control over priorities, fairness, and the underlying threads utilized.
+    /// </summary>
+    [DebuggerTypeProxy(typeof(QueuedTaskSchedulerDebugView))]
+    [DebuggerDisplay("Id={Id}, Queues={DebugQueueCount}, ScheduledTasks = {DebugTaskCount}")]
+    public sealed class QueuedTaskScheduler : TaskScheduler, IDisposable
+    {
+        /// <summary>Debug view for the QueuedTaskScheduler.</summary>
+        private class QueuedTaskSchedulerDebugView
+        {
+            /// <summary>The scheduler.</summary>
+            private QueuedTaskScheduler _scheduler;
+
+            /// <summary>Initializes the debug view.</summary>
+            /// <param name="scheduler">The scheduler.</param>
+            public QueuedTaskSchedulerDebugView(QueuedTaskScheduler scheduler)
+            {
+                if (scheduler == null) throw new ArgumentNullException("scheduler");
+                _scheduler = scheduler;
+            }
+
+            /// <summary>Gets all of the Tasks queued to the scheduler directly.</summary>
+            public IEnumerable<Task> ScheduledTasks
+            {
+                get
+                {
+                    var tasks = (_scheduler._targetScheduler != null) ?
+                        (IEnumerable<Task>)_scheduler._nonthreadsafeTaskQueue :
+                        (IEnumerable<Task>)_scheduler._blockingTaskQueue;
+                    return tasks.Where(t => t != null).ToList();
+                }
+            }
+
+            /// <summary>Gets the prioritized and fair queues.</summary>
+            public IEnumerable<TaskScheduler> Queues
+            {
+                get
+                {
+                    List<TaskScheduler> queues = new List<TaskScheduler>();
+                    foreach (var group in _scheduler._queueGroups) queues.AddRange(group.Value);
+                    return queues;
+                }
+            }
+        }
+
+        /// <summary>
+        /// A sorted list of round-robin queue lists.  Tasks with the smallest priority value
+        /// are preferred.  Priority groups are round-robin'd through in order of priority.
+        /// </summary>
+        private readonly SortedList<int, QueueGroup> _queueGroups = new SortedList<int, QueueGroup>();
+        /// <summary>Cancellation token used for disposal.</summary>
+        private readonly CancellationTokenSource _disposeCancellation = new CancellationTokenSource();
+        /// <summary>
+        /// The maximum allowed concurrency level of this scheduler.  If custom threads are
+        /// used, this represents the number of created threads.
+        /// </summary>
+        private readonly int _concurrencyLevel;
+        /// <summary>Whether we're processing tasks on the current thread.</summary>
+        private static ThreadLocal<bool> _taskProcessingThread = new ThreadLocal<bool>();
+
+        // ***
+        // *** For when using a target scheduler
+        // ***
+
+        /// <summary>The scheduler onto which actual work is scheduled.</summary>
+        private readonly TaskScheduler _targetScheduler;
+        /// <summary>The queue of tasks to process when using an underlying target scheduler.</summary>
+        private readonly Queue<Task> _nonthreadsafeTaskQueue;
+        /// <summary>The number of Tasks that have been queued or that are running whiel using an underlying scheduler.</summary>
+        private int _delegatesQueuedOrRunning = 0;
+
+        // ***
+        // *** For when using our own threads
+        // ***
+
+        /// <summary>The threads used by the scheduler to process work.</summary>
+        private readonly Thread[] _threads;
+        /// <summary>The collection of tasks to be executed on our custom threads.</summary>
+        private readonly BlockingCollection<Task> _blockingTaskQueue;
+
+        // ***
+
+        /// <summary>Initializes the scheduler.</summary>
+        public QueuedTaskScheduler() : this(TaskScheduler.Default, 0) { }
+
+        /// <summary>Initializes the scheduler.</summary>
+        /// <param name="targetScheduler">The target underlying scheduler onto which this sceduler's work is queued.</param>
+        public QueuedTaskScheduler(TaskScheduler targetScheduler) : this(targetScheduler, 0) { }
+
+        /// <summary>Initializes the scheduler.</summary>
+        /// <param name="targetScheduler">The target underlying scheduler onto which this sceduler's work is queued.</param>
+        /// <param name="maxConcurrencyLevel">The maximum degree of concurrency allowed for this scheduler's work.</param>
+        public QueuedTaskScheduler(
+            TaskScheduler targetScheduler,
+            int maxConcurrencyLevel)
+        {
+            // Validate arguments
+            if (targetScheduler == null) throw new ArgumentNullException("underlyingScheduler");
+            if (maxConcurrencyLevel < 0) throw new ArgumentOutOfRangeException("concurrencyLevel");
+
+            // Initialize only those fields relevant to use an underlying scheduler.  We don't
+            // initialize the fields relevant to using our own custom threads.
+            _targetScheduler = targetScheduler;
+            _nonthreadsafeTaskQueue = new Queue<Task>();
+
+            // If 0, use the number of logical processors.  But make sure whatever value we pick
+            // is not greater than the degree of parallelism allowed by the underlying scheduler.
+            _concurrencyLevel = maxConcurrencyLevel != 0 ? maxConcurrencyLevel : Environment.ProcessorCount;
+            if (targetScheduler.MaximumConcurrencyLevel > 0 && 
+                targetScheduler.MaximumConcurrencyLevel < _concurrencyLevel)
+            {
+                _concurrencyLevel = targetScheduler.MaximumConcurrencyLevel;
+            }
+        }
+
+        /// <summary>Initializes the scheduler.</summary>
+        /// <param name="threadCount">The number of threads to create and use for processing work items.</param>
+        public QueuedTaskScheduler(int threadCount) : this(threadCount, string.Empty, false, ThreadPriority.Normal, ApartmentState.MTA, 0, null, null) { }
+
+        /// <summary>Initializes the scheduler.</summary>
+        /// <param name="threadCount">The number of threads to create and use for processing work items.</param>
+        /// <param name="threadName">The name to use for each of the created threads.</param>
+        /// <param name="useForegroundThreads">A Boolean value that indicates whether to use foreground threads instead of background.</param>
+        /// <param name="threadPriority">The priority to assign to each thread.</param>
+        /// <param name="threadApartmentState">The apartment state to use for each thread.</param>
+        /// <param name="threadMaxStackSize">The stack size to use for each thread.</param>
+        /// <param name="threadInit">An initialization routine to run on each thread.</param>
+        /// <param name="threadFinally">A finalization routine to run on each thread.</param>
+        public QueuedTaskScheduler(
+            int threadCount,
+            string threadName = "",
+            bool useForegroundThreads = false,
+            ThreadPriority threadPriority = ThreadPriority.Normal,
+            ApartmentState threadApartmentState = ApartmentState.MTA,
+            int threadMaxStackSize = 0,
+            Action threadInit = null,
+            Action threadFinally = null)
+        {
+            // Validates arguments (some validation is left up to the Thread type itself).
+            // If the thread count is 0, default to the number of logical processors.
+            if (threadCount < 0) throw new ArgumentOutOfRangeException("concurrencyLevel");
+            else if (threadCount == 0) _concurrencyLevel = Environment.ProcessorCount;
+            else _concurrencyLevel = threadCount;
+
+            // Initialize the queue used for storing tasks
+            _blockingTaskQueue = new BlockingCollection<Task>();
+
+            // Create all of the threads
+            _threads = new Thread[threadCount];
+            for (int i = 0; i < threadCount; i++)
+            {
+                _threads[i] = new Thread(() => ThreadBasedDispatchLoop(threadInit, threadFinally), threadMaxStackSize)
+                {
+                    Priority = threadPriority,
+                    IsBackground = !useForegroundThreads,
+                };
+                if (threadName != null) _threads[i].Name = threadName + " (" + i + ")";
+                _threads[i].SetApartmentState(threadApartmentState);
+            }
+
+            // Start all of the threads
+            foreach (var thread in _threads) thread.Start();
+        }
+
+        /// <summary>The dispatch loop run by all threads in this scheduler.</summary>
+        /// <param name="threadInit">An initialization routine to run when the thread begins.</param>
+        /// <param name="threadFinally">A finalization routine to run before the thread ends.</param>
+        private void ThreadBasedDispatchLoop(Action threadInit, Action threadFinally)
+        {
+            _taskProcessingThread.Value = true;
+            if (threadInit != null) threadInit();
+            try
+            {
+                // If the scheduler is disposed, the cancellation token will be set and
+                // we'll receive an OperationCanceledException.  That OCE should not crash the process.
+                try
+                {
+                    // If a thread abort occurs, we'll try to reset it and continue running.
+                    while (true)
+                    {
+                        try
+                        {
+                            // For each task queued to the scheduler, try to execute it.
+                            foreach (var task in _blockingTaskQueue.GetConsumingEnumerable(_disposeCancellation.Token))
+                            {
+                                // If the task is not null, that means it was queued to this scheduler directly.
+                                // Run it.
+                                if (task != null)
+                                {
+                                    TryExecuteTask(task);
+                                }
+                                // If the task is null, that means it's just a placeholder for a task
+                                // queued to one of the subschedulers.  Find the next task based on
+                                // priority and fairness and run it.
+                                else
+                                {
+                                    // Find the next task based on our ordering rules...
+                                    Task targetTask;
+                                    QueuedTaskSchedulerQueue queueForTargetTask;
+                                    lock (_queueGroups) FindNextTask_NeedsLock(out targetTask, out queueForTargetTask);
+
+                                    // ... and if we found one, run it
+                                    if (targetTask != null) queueForTargetTask.ExecuteTask(targetTask);
+                                }
+                            }
+                        }
+                        catch (ThreadAbortException)
+                        {
+                            // If we received a thread abort, and that thread abort was due to shutting down
+                            // or unloading, let it pass through.  Otherwise, reset the abort so we can
+                            // continue processing work items.
+                            if (!Environment.HasShutdownStarted && !AppDomain.CurrentDomain.IsFinalizingForUnload())
+                            {
+                                Thread.ResetAbort();
+                            }
+                        }
+                    }
+                }
+                catch (OperationCanceledException) { }
+            }
+            finally
+            {
+                // Run a cleanup routine if there was one
+                if (threadFinally != null) threadFinally();
+                _taskProcessingThread.Value = false;
+            }
+        }
+
+        /// <summary>Gets the number of queues currently activated.</summary>
+        private int DebugQueueCount
+        {
+            get
+            {
+                int count = 0;
+                foreach (var group in _queueGroups) count += group.Value.Count;
+                return count;
+            }
+        }
+
+        /// <summary>Gets the number of tasks currently scheduled.</summary>
+        private int DebugTaskCount
+        {
+            get
+            {
+                return (_targetScheduler != null ? 
+                    (IEnumerable<Task>)_nonthreadsafeTaskQueue : (IEnumerable<Task>)_blockingTaskQueue)
+                    .Where(t => t != null).Count();
+            }
+        }
+
+        /// <summary>Find the next task that should be executed, based on priorities and fairness and the like.</summary>
+        /// <param name="targetTask">The found task, or null if none was found.</param>
+        /// <param name="queueForTargetTask">
+        /// The scheduler associated with the found task.  Due to security checks inside of TPL,  
+        /// this scheduler needs to be used to execute that task.
+        /// </param>
+        private void FindNextTask_NeedsLock(out Task targetTask, out QueuedTaskSchedulerQueue queueForTargetTask)
+        {
+            targetTask = null;
+            queueForTargetTask = null;
+
+            // Look through each of our queue groups in sorted order.
+            // This ordering is based on the priority of the queues.
+            foreach (var queueGroup in _queueGroups)
+            {
+                var queues = queueGroup.Value;
+
+                // Within each group, iterate through the queues in a round-robin
+                // fashion.  Every time we iterate again and successfully find a task, 
+                // we'll start in the next location in the group.
+                foreach (int i in queues.CreateSearchOrder())
+                {
+                    queueForTargetTask = queues[i];
+                    var items = queueForTargetTask._workItems;
+                    if (items.Count > 0)
+                    {
+                        targetTask = items.Dequeue();
+                        if (queueForTargetTask._disposed && items.Count == 0)
+                        {
+                            RemoveQueue_NeedsLock(queueForTargetTask);
+                        }
+                        queues.NextQueueIndex = (queues.NextQueueIndex + 1) % queueGroup.Value.Count;
+                        return;
+                    }
+                }
+            }
+        }
+
+        /// <summary>Queues a task to the scheduler.</summary>
+        /// <param name="task">The task to be queued.</param>
+        protected override void QueueTask(Task task)
+        {
+            // If we've been disposed, no one should be queueing
+            if (_disposeCancellation.IsCancellationRequested) throw new ObjectDisposedException(GetType().Name);
+
+            // If the target scheduler is null (meaning we're using our own threads),
+            // add the task to the blocking queue
+            if (_targetScheduler == null)
+            {
+                _blockingTaskQueue.Add(task);
+            }
+            // Otherwise, add the task to the non-blocking queue,
+            // and if there isn't already an executing processing task,
+            // start one up
+            else
+            {
+                // Queue the task and check whether we should launch a processing
+                // task (noting it if we do, so that other threads don't result
+                // in queueing up too many).
+                bool launchTask = false;
+                lock (_nonthreadsafeTaskQueue)
+                {
+                    _nonthreadsafeTaskQueue.Enqueue(task);
+                    if (_delegatesQueuedOrRunning < _concurrencyLevel)
+                    {
+                        ++_delegatesQueuedOrRunning;
+                        launchTask = true;
+                    }
+                }
+
+                // If necessary, start processing asynchronously
+                if (launchTask)
+                {
+                    Task.Factory.StartNew(ProcessPrioritizedAndBatchedTasks,
+                        CancellationToken.None, TaskCreationOptions.None, _targetScheduler);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Process tasks one at a time in the best order.  
+        /// This should be run in a Task generated by QueueTask.
+        /// It's been separated out into its own method to show up better in Parallel Tasks.
+        /// </summary>
+        private void ProcessPrioritizedAndBatchedTasks()
+        {
+            bool continueProcessing = true;
+            while (!_disposeCancellation.IsCancellationRequested && continueProcessing)
+            {
+                try
+                {
+                    // Note that we're processing tasks on this thread
+                    _taskProcessingThread.Value = true;
+
+                    // Until there are no more tasks to process
+                    while (!_disposeCancellation.IsCancellationRequested)
+                    {
+                        // Try to get the next task.  If there aren't any more, we're done.
+                        Task targetTask;
+                        lock (_nonthreadsafeTaskQueue)
+                        {
+                            if (_nonthreadsafeTaskQueue.Count == 0) return;
+                            targetTask = _nonthreadsafeTaskQueue.Dequeue();
+                        }
+
+                        // If the task is null, it's a placeholder for a task in the round-robin queues.
+                        // Find the next one that should be processed.
+                        QueuedTaskSchedulerQueue queueForTargetTask = null;
+                        if (targetTask == null)
+                        {
+                            lock (_queueGroups) FindNextTask_NeedsLock(out targetTask, out queueForTargetTask);
+                        }
+
+                        // Now if we finally have a task, run it.  If the task
+                        // was associated with one of the round-robin schedulers, we need to use it
+                        // as a thunk to execute its task.
+                        if (targetTask != null)
+                        {
+                            if (queueForTargetTask != null) queueForTargetTask.ExecuteTask(targetTask);
+                            else TryExecuteTask(targetTask);
+                        }
+                    }
+                }
+                finally
+                {
+                    // Now that we think we're done, verify that there really is
+                    // no more work to do.  If there's not, highlight
+                    // that we're now less parallel than we were a moment ago.
+                    lock (_nonthreadsafeTaskQueue)
+                    {
+                        if (_nonthreadsafeTaskQueue.Count == 0)
+                        {
+                            _delegatesQueuedOrRunning--;
+                            continueProcessing = false;
+                            _taskProcessingThread.Value = false;
+                        }
+                    }
+                }
+            }
+        }
+
+        /// <summary>Notifies the pool that there's a new item to be executed in one of the round-robin queues.</summary>
+        private void NotifyNewWorkItem() { QueueTask(null); }
+
+        /// <summary>Tries to execute a task synchronously on the current thread.</summary>
+        /// <param name="task">The task to execute.</param>
+        /// <param name="taskWasPreviouslyQueued">Whether the task was previously queued.</param>
+        /// <returns>true if the task was executed; otherwise, false.</returns>
+        protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
+        {
+            // If we're already running tasks on this threads, enable inlining
+            return _taskProcessingThread.Value && TryExecuteTask(task);
+        }
+
+        /// <summary>Gets the tasks scheduled to this scheduler.</summary>
+        /// <returns>An enumerable of all tasks queued to this scheduler.</returns>
+        /// <remarks>This does not include the tasks on sub-schedulers.  Those will be retrieved by the debugger separately.</remarks>
+        protected override IEnumerable<Task> GetScheduledTasks()
+        {
+            // If we're running on our own threads, get the tasks from the blocking queue...
+            if (_targetScheduler == null)
+            {
+                // Get all of the tasks, filtering out nulls, which are just placeholders
+                // for tasks in other sub-schedulers
+                return _blockingTaskQueue.Where(t => t != null).ToList();
+            }
+            // otherwise get them from the non-blocking queue...
+            else
+            {
+                return _nonthreadsafeTaskQueue.Where(t => t != null).ToList();
+            }
+        }
+
+        /// <summary>Gets the maximum concurrency level to use when processing tasks.</summary>
+        public override int MaximumConcurrencyLevel { get { return _concurrencyLevel; } }
+
+        /// <summary>Initiates shutdown of the scheduler.</summary>
+        public void Dispose()
+        {
+            _disposeCancellation.Cancel();
+        }
+
+        /// <summary>Creates and activates a new scheduling queue for this scheduler.</summary>
+        /// <returns>The newly created and activated queue at priority 0.</returns>
+        public TaskScheduler ActivateNewQueue() { return ActivateNewQueue(0); }
+
+        /// <summary>Creates and activates a new scheduling queue for this scheduler.</summary>
+        /// <param name="priority">The priority level for the new queue.</param>
+        /// <returns>The newly created and activated queue at the specified priority.</returns>
+        public TaskScheduler ActivateNewQueue(int priority)
+        {
+            // Create the queue
+            var createdQueue = new QueuedTaskSchedulerQueue(priority, this);
+
+            // Add the queue to the appropriate queue group based on priority
+            lock (_queueGroups)
+            {
+                QueueGroup list;
+                if (!_queueGroups.TryGetValue(priority, out list))
+                {
+                    list = new QueueGroup();
+                    _queueGroups.Add(priority, list);
+                }
+                list.Add(createdQueue);
+            }
+
+            // Hand the new queue back
+            return createdQueue;
+        }
+
+        /// <summary>Removes a scheduler from the group.</summary>
+        /// <param name="queue">The scheduler to be removed.</param>
+        private void RemoveQueue_NeedsLock(QueuedTaskSchedulerQueue queue)
+        {
+            // Find the group that contains the queue and the queue's index within the group
+            var queueGroup = _queueGroups[queue._priority];
+            int index = queueGroup.IndexOf(queue);
+
+            // We're about to remove the queue, so adjust the index of the next
+            // round-robin starting location if it'll be affected by the removal
+            if (queueGroup.NextQueueIndex >= index) queueGroup.NextQueueIndex--;
+
+            // Remove it
+            queueGroup.RemoveAt(index);
+        }
+
+        /// <summary>A group of queues a the same priority level.</summary>
+        private class QueueGroup : List<QueuedTaskSchedulerQueue>
+        {
+            /// <summary>The starting index for the next round-robin traversal.</summary>
+            public int NextQueueIndex = 0;
+
+            /// <summary>Creates a search order through this group.</summary>
+            /// <returns>An enumerable of indices for this group.</returns>
+            public IEnumerable<int> CreateSearchOrder()
+            {
+                for (int i = NextQueueIndex; i < Count; i++) yield return i;
+                for (int i = 0; i < NextQueueIndex; i++) yield return i;
+            }
+        }
+
+        /// <summary>Provides a scheduling queue associatd with a QueuedTaskScheduler.</summary>
+        [DebuggerDisplay("QueuePriority = {_priority}, WaitingTasks = {WaitingTasks}")]
+        [DebuggerTypeProxy(typeof(QueuedTaskSchedulerQueueDebugView))]
+        private sealed class QueuedTaskSchedulerQueue : TaskScheduler, IDisposable
+        {
+            /// <summary>A debug view for the queue.</summary>
+            private sealed class QueuedTaskSchedulerQueueDebugView
+            {
+                /// <summary>The queue.</summary>
+                private readonly QueuedTaskSchedulerQueue _queue;
+
+                /// <summary>Initializes the debug view.</summary>
+                /// <param name="queue">The queue to be debugged.</param>
+                public QueuedTaskSchedulerQueueDebugView(QueuedTaskSchedulerQueue queue)
+                {
+                    if (queue == null) throw new ArgumentNullException("queue");
+                    _queue = queue;
+                }
+
+                /// <summary>Gets the priority of this queue in its associated scheduler.</summary>
+                public int Priority { get { return _queue._priority; } }
+                /// <summary>Gets the ID of this scheduler.</summary>
+                public int Id { get { return _queue.Id; } }
+                /// <summary>Gets all of the tasks scheduled to this queue.</summary>
+                public IEnumerable<Task> ScheduledTasks { get { return _queue.GetScheduledTasks(); } }
+                /// <summary>Gets the QueuedTaskScheduler with which this queue is associated.</summary>
+                public QueuedTaskScheduler AssociatedScheduler { get { return _queue._pool; } }
+            }
+
+            /// <summary>The scheduler with which this pool is associated.</summary>
+            private readonly QueuedTaskScheduler _pool;
+            /// <summary>The work items stored in this queue.</summary>
+            internal readonly Queue<Task> _workItems;
+            /// <summary>Whether this queue has been disposed.</summary>
+            internal bool _disposed;
+            /// <summary>Gets the priority for this queue.</summary>
+            internal int _priority;
+
+            /// <summary>Initializes the queue.</summary>
+            /// <param name="priority">The priority associated with this queue.</param>
+            /// <param name="pool">The scheduler with which this queue is associated.</param>
+            internal QueuedTaskSchedulerQueue(int priority, QueuedTaskScheduler pool)
+            {
+                _priority = priority;
+                _pool = pool;
+                _workItems = new Queue<Task>();
+            }
+
+            /// <summary>Gets the number of tasks waiting in this scheduler.</summary>
+            internal int WaitingTasks { get { return _workItems.Count; } }
+
+            /// <summary>Gets the tasks scheduled to this scheduler.</summary>
+            /// <returns>An enumerable of all tasks queued to this scheduler.</returns>
+            protected override IEnumerable<Task> GetScheduledTasks() { return _workItems.ToList(); }
+
+            /// <summary>Queues a task to the scheduler.</summary>
+            /// <param name="task">The task to be queued.</param>
+            protected override void QueueTask(Task task)
+            {
+                if (_disposed) throw new ObjectDisposedException(GetType().Name);
+
+                // Queue up the task locally to this queue, and then notify
+                // the parent scheduler that there's work available
+                lock (_pool._queueGroups) _workItems.Enqueue(task);
+                _pool.NotifyNewWorkItem();
+            }
+
+            /// <summary>Tries to execute a task synchronously on the current thread.</summary>
+            /// <param name="task">The task to execute.</param>
+            /// <param name="taskWasPreviouslyQueued">Whether the task was previously queued.</param>
+            /// <returns>true if the task was executed; otherwise, false.</returns>
+            protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
+            {
+                // If we're using our own threads and if this is being called from one of them,
+                // or if we're currently processing another task on this thread, try running it inline.
+                return _taskProcessingThread.Value && TryExecuteTask(task);
+            }
+
+            /// <summary>Runs the specified ask.</summary>
+            /// <param name="task">The task to execute.</param>
+            internal void ExecuteTask(Task task) { TryExecuteTask(task); }
+
+            /// <summary>Gets the maximum concurrency level to use when processing tasks.</summary>
+            public override int MaximumConcurrencyLevel { get { return _pool.MaximumConcurrencyLevel; } }
+
+            /// <summary>Signals that the queue should be removed from the scheduler as soon as the queue is empty.</summary>
+            public void Dispose()
+            {
+                if (!_disposed)
+                {
+                    lock (_pool._queueGroups)
+                    {
+                        // We only remove the queue if it's empty.  If it's not empty,
+                        // we still mark it as disposed, and the associated QueuedTaskScheduler
+                        // will remove the queue when its count hits 0 and its _disposed is true.
+                        if (_workItems.Count == 0)
+                        {
+                            _pool.RemoveQueue_NeedsLock(this);
+                        }
+                    }
+                    _disposed = true;
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/ReprioritizableTaskScheduler.cs b/trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/ReprioritizableTaskScheduler.cs
new file mode 100644 (file)
index 0000000..3ca161b
--- /dev/null
@@ -0,0 +1,115 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: PrioritizingTaskScheduler.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Linq;
+
+namespace System.Threading.Tasks.Schedulers
+{
+    /// <summary>Provides a task scheduler that supports reprioritizing previously queued tasks.</summary>
+    public sealed class ReprioritizableTaskScheduler : TaskScheduler
+    {
+        private readonly LinkedList<Task> _tasks = new LinkedList<Task>(); // protected by lock(_tasks)
+
+        /// <summary>Queues a task to the scheduler.</summary>
+        /// <param name="task">The task to be queued.</param>
+        protected override void QueueTask(Task task)
+        {
+            // Store the task, and notify the ThreadPool of work to be processed
+            lock (_tasks) _tasks.AddLast(task);
+            ThreadPool.UnsafeQueueUserWorkItem(ProcessNextQueuedItem, null);
+        }
+
+        /// <summary>Reprioritizes a previously queued task to the front of the queue.</summary>
+        /// <param name="task">The task to be reprioritized.</param>
+        /// <returns>Whether the task could be found and moved to the front of the queue.</returns>
+        public bool Prioritize(Task task)
+        {
+            lock (_tasks)
+            {
+                var node = _tasks.Find(task);
+                if (node != null)
+                {
+                    _tasks.Remove(node);
+                    _tasks.AddFirst(node);
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        /// <summary>Reprioritizes a previously queued task to the back of the queue.</summary>
+        /// <param name="task">The task to be reprioritized.</param>
+        /// <returns>Whether the task could be found and moved to the back of the queue.</returns>
+        public bool Deprioritize(Task task)
+        {
+            lock (_tasks)
+            {
+                var node = _tasks.Find(task);
+                if (node != null)
+                {
+                    _tasks.Remove(node);
+                    _tasks.AddLast(node);
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        /// <summary>Removes a previously queued item from the scheduler.</summary>
+        /// <param name="task">The task to be removed.</param>
+        /// <returns>Whether the task could be removed from the scheduler.</returns>
+        protected override bool TryDequeue(Task task)
+        {
+            lock (_tasks) return _tasks.Remove(task);
+        }
+
+        /// <summary>Picks up and executes the next item in the queue.</summary>
+        /// <param name="ignored">Ignored.</param>
+        private void ProcessNextQueuedItem(object ignored)
+        {
+            Task t;
+            lock (_tasks)
+            {
+                if (_tasks.Count > 0)
+                {
+                    t = _tasks.First.Value;
+                    _tasks.RemoveFirst();
+                }
+                else return;
+            }
+            base.TryExecuteTask(t);
+        }
+
+        /// <summary>Executes the specified task inline.</summary>
+        /// <param name="task">The task to be executed.</param>
+        /// <param name="taskWasPreviouslyQueued">Whether the task was previously queued.</param>
+        /// <returns>Whether the task could be executed inline.</returns>
+        protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
+        {
+            return TryExecuteTask(task);
+        }
+
+        /// <summary>Gets all of the tasks currently queued to the scheduler.</summary>
+        /// <returns>An enumerable of the tasks currently queued to the scheduler.</returns>
+        protected override IEnumerable<Task> GetScheduledTasks()
+        {
+            bool lockTaken = false;
+            try
+            {
+                Monitor.TryEnter(_tasks, ref lockTaken);
+                if (lockTaken) return _tasks.ToArray();
+                else throw new NotSupportedException();
+            }
+            finally
+            {
+                if (lockTaken) Monitor.Exit(_tasks);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/RoundRobinTaskScheduler.cs b/trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/RoundRobinTaskScheduler.cs
new file mode 100644 (file)
index 0000000..ff1c443
--- /dev/null
@@ -0,0 +1,134 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: RoundRobinTaskScheduler.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+
+namespace System.Threading.Tasks.Schedulers
+{
+    /// <summary>Enables the creation of a group of schedulers that support round-robin scheduling for fairness.</summary>
+    public sealed class RoundRobinSchedulerGroup
+    {
+        private readonly List<RoundRobinTaskSchedulerQueue> _queues = new List<RoundRobinTaskSchedulerQueue>();
+        private int _nextQueue = 0;
+
+        /// <summary>Creates a new scheduler as part of this group.</summary>
+        /// <returns>The new scheduler.</returns>
+        public TaskScheduler CreateScheduler()
+        {
+            var createdQueue = new RoundRobinTaskSchedulerQueue(this);
+            lock (_queues) _queues.Add(createdQueue);
+            return createdQueue;
+        }
+
+        /// <summary>Gets a collection of all schedulers in this group.</summary>
+        public ReadOnlyCollection<TaskScheduler> Schedulers
+        {
+            get { lock(_queues) return new ReadOnlyCollection<TaskScheduler>(_queues.Cast<TaskScheduler>().ToArray()); }
+        }
+
+        /// <summary>Removes a scheduler from the group.</summary>
+        /// <param name="queue">The scheduler to be removed.</param>
+        private void RemoveQueue_NeedsLock(RoundRobinTaskSchedulerQueue queue)
+        {
+            int index = _queues.IndexOf(queue);
+            if (_nextQueue >= index) _nextQueue--;
+            _queues.RemoveAt(index);
+        }
+
+        /// <summary>Notifies the ThreadPool that there's a new item to be executed.</summary>
+        private void NotifyNewWorkItem()
+        {
+            // Queue a processing delegate to the ThreadPool
+            ThreadPool.UnsafeQueueUserWorkItem(_ =>
+            {
+                Task targetTask = null;
+                RoundRobinTaskSchedulerQueue queueForTargetTask = null;
+                lock (_queues)
+                {
+                    // Determine the order in which we'll search the schedulers for work
+                    var searchOrder = Enumerable.Range(_nextQueue, _queues.Count - _nextQueue).Concat(Enumerable.Range(0, _nextQueue));
+
+                    // Look for the next item to process
+                    foreach (int i in searchOrder)
+                    {
+                        queueForTargetTask = _queues[i];
+                        var items = queueForTargetTask._workItems;
+                        if (items.Count > 0)
+                        {
+                            targetTask = items.Dequeue();
+                            _nextQueue = i;
+                            if (queueForTargetTask._disposed && items.Count == 0)
+                            {
+                                RemoveQueue_NeedsLock(queueForTargetTask);
+                            }
+                            break;
+                        }
+                    }
+                    _nextQueue = (_nextQueue + 1) % _queues.Count;
+                }
+
+                // If we found an item, run it
+                if (targetTask != null) queueForTargetTask.RunQueuedTask(targetTask);
+            }, null);
+        }
+
+        /// <summary>A scheduler that participates in round-robin scheduling.</summary>
+        private sealed class RoundRobinTaskSchedulerQueue : TaskScheduler, IDisposable
+        {
+            internal RoundRobinTaskSchedulerQueue(RoundRobinSchedulerGroup pool) { _pool = pool; }
+
+            private RoundRobinSchedulerGroup _pool;
+            internal Queue<Task> _workItems = new Queue<Task>();
+            internal bool _disposed;
+
+            protected override IEnumerable<Task> GetScheduledTasks() 
+            { 
+                object obj = _pool._queues;
+                bool lockTaken = false;
+                try
+                {
+                    Monitor.TryEnter(obj, ref lockTaken);
+                    if (lockTaken) return _workItems.ToArray();
+                    else throw new NotSupportedException();
+                }
+                finally
+                {
+                    if (lockTaken) Monitor.Exit(obj);
+                }
+            }
+
+            protected override void QueueTask(Task task)
+            {
+                if (_disposed) throw new ObjectDisposedException(GetType().Name);
+                lock (_pool._queues) _workItems.Enqueue(task);
+                _pool.NotifyNewWorkItem();
+            }
+
+            protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
+            {
+                return base.TryExecuteTask(task);
+            }
+
+            internal void RunQueuedTask(Task task) { TryExecuteTask(task); }
+
+            void IDisposable.Dispose()
+            {
+                if (!_disposed)
+                {
+                    lock (_pool._queues)
+                    {
+                        if (_workItems.Count == 0) _pool.RemoveQueue_NeedsLock(this);
+                        _disposed = true;
+                    }
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/StaTaskScheduler.cs b/trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/StaTaskScheduler.cs
new file mode 100644 (file)
index 0000000..8bfdf20
--- /dev/null
@@ -0,0 +1,108 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: StaTaskScheduler.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace System.Threading.Tasks.Schedulers
+{
+    /// <summary>Provides a scheduler that uses STA threads.</summary>
+    public sealed class StaTaskScheduler : TaskScheduler, IDisposable
+    {
+        /// <summary>Stores the queued tasks to be executed by our pool of STA threads.</summary>
+        private BlockingCollection<Task> _tasks;
+        /// <summary>The STA threads used by the scheduler.</summary>
+        private readonly List<Thread> _threads;
+
+        /// <summary>Initializes a new instance of the StaTaskScheduler class with the specified concurrency level.</summary>
+        /// <param name="numberOfThreads">The number of threads that should be created and used by this scheduler.</param>
+        public StaTaskScheduler(int numberOfThreads)
+        {
+            // Validate arguments
+            if (numberOfThreads < 1) throw new ArgumentOutOfRangeException("concurrencyLevel");
+
+            // Initialize the tasks collection
+            _tasks = new BlockingCollection<Task>();
+
+            // Create the threads to be used by this scheduler
+            _threads = Enumerable.Range(0, numberOfThreads).Select(i =>
+                       {
+                           var thread = new Thread(() =>
+                           {
+                               // Continually get the next task and try to execute it.
+                               // This will continue until the scheduler is disposed and no more tasks remain.
+                               foreach (var t in _tasks.GetConsumingEnumerable())
+                               {
+                                   TryExecuteTask(t);
+                               }
+                           });
+                           thread.IsBackground = true;
+                           thread.SetApartmentState(ApartmentState.STA);
+                           return thread;
+                       }).ToList();
+
+            // Start all of the threads
+            _threads.ForEach(t => t.Start());
+        }
+
+        /// <summary>Queues a Task to be executed by this scheduler.</summary>
+        /// <param name="task">The task to be executed.</param>
+        protected override void QueueTask(Task task)
+        {
+            // Push it into the blocking collection of tasks
+            _tasks.Add(task);
+        }
+
+        /// <summary>Provides a list of the scheduled tasks for the debugger to consume.</summary>
+        /// <returns>An enumerable of all tasks currently scheduled.</returns>
+        protected override IEnumerable<Task> GetScheduledTasks()
+        {
+            // Serialize the contents of the blocking collection of tasks for the debugger
+            return _tasks.ToArray();
+        }
+
+        /// <summary>Determines whether a Task may be inlined.</summary>
+        /// <param name="task">The task to be executed.</param>
+        /// <param name="taskWasPreviouslyQueued">Whether the task was previously queued.</param>
+        /// <returns>true if the task was successfully inlined; otherwise, false.</returns>
+        protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
+        {
+            // Try to inline if the current thread is STA
+            return
+                Thread.CurrentThread.GetApartmentState() == ApartmentState.STA &&
+                TryExecuteTask(task);
+        }
+
+        /// <summary>Gets the maximum concurrency level supported by this scheduler.</summary>
+        public override int MaximumConcurrencyLevel
+        {
+            get { return _threads.Count; }
+        }
+
+        /// <summary>
+        /// Cleans up the scheduler by indicating that no more tasks will be queued.
+        /// This method blocks until all threads successfully shutdown.
+        /// </summary>
+        public void Dispose()
+        {
+            if (_tasks != null)
+            {
+                // Indicate that no new tasks will be coming in
+                _tasks.CompleteAdding();
+
+                // Wait for all threads to finish processing tasks
+                foreach (var thread in _threads) thread.Join();
+
+                // Cleanup
+                _tasks.Dispose();
+                _tasks = null;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/SynchronizationContextTaskScheduler.cs b/trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/SynchronizationContextTaskScheduler.cs
new file mode 100644 (file)
index 0000000..7e9d7a9
--- /dev/null
@@ -0,0 +1,73 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: SynchronizationContextTaskScheduler.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.ComponentModel;
+
+namespace System.Threading.Tasks.Schedulers
+{
+    /// <summary>Provides a task scheduler that targets a specific SynchronizationContext.</summary>
+    public sealed class SynchronizationContextTaskScheduler : TaskScheduler
+    {
+        /// <summary>The queue of tasks to execute, maintained for debugging purposes.</summary>
+        private readonly ConcurrentQueue<Task> _tasks;
+        /// <summary>The target context under which to execute the queued tasks.</summary>
+        private readonly SynchronizationContext _context;
+
+        /// <summary>Initializes an instance of the SynchronizationContextTaskScheduler class.</summary>
+        public SynchronizationContextTaskScheduler() :
+            this(SynchronizationContext.Current)
+        {
+        }
+
+        /// <summary>
+        /// Initializes an instance of the SynchronizationContextTaskScheduler class
+        /// with the specified SynchronizationContext.
+        /// </summary>
+        /// <param name="context">The SynchronizationContext under which to execute tasks.</param>
+        public SynchronizationContextTaskScheduler(SynchronizationContext context)
+        {
+            if (context == null) throw new ArgumentNullException("context");
+            _context = context;
+            _tasks = new ConcurrentQueue<Task>();
+        }
+
+        /// <summary>Queues a task to the scheduler for execution on the I/O ThreadPool.</summary>
+        /// <param name="task">The Task to queue.</param>
+        protected override void QueueTask(Task task)
+        {
+            _tasks.Enqueue(task);
+            _context.Post(delegate
+            {
+                Task nextTask;
+                if (_tasks.TryDequeue(out nextTask)) TryExecuteTask(nextTask);
+            }, null);
+        }
+
+        /// <summary>Tries to execute a task on the current thread.</summary>
+        /// <param name="task">The task to be executed.</param>
+        /// <param name="taskWasPreviouslyQueued">Ignored.</param>
+        /// <returns>Whether the task could be executed.</returns>
+        protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
+        {
+            return _context != SynchronizationContext.Current && TryExecuteTask(task);
+        }
+
+        /// <summary>Gets an enumerable of tasks queued to the scheduler.</summary>
+        /// <returns>An enumerable of tasks queued to the scheduler.</returns>
+        protected override IEnumerable<Task> GetScheduledTasks()
+        {
+            return _tasks.ToArray();
+        }
+
+        /// <summary>Gets the maximum concurrency level supported by this scheduler.</summary>
+        public override int MaximumConcurrencyLevel { get { return 1; } }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/ThreadPerTaskkScheduler.cs b/trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/ThreadPerTaskkScheduler.cs
new file mode 100644 (file)
index 0000000..83df527
--- /dev/null
@@ -0,0 +1,37 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: ThreadPerTaskScheduler.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Generic;
+using System.Linq;
+
+namespace System.Threading.Tasks.Schedulers
+{
+    /// <summary>Provides a task scheduler that dedicates a thread per task.</summary>
+    public class ThreadPerTaskScheduler : TaskScheduler
+    {
+        /// <summary>Gets the tasks currently scheduled to this scheduler.</summary>
+        /// <remarks>This will always return an empty enumerable, as tasks are launched as soon as they're queued.</remarks>
+        protected override IEnumerable<Task> GetScheduledTasks() { return Enumerable.Empty<Task>(); }
+
+        /// <summary>Starts a new thread to process the provided task.</summary>
+        /// <param name="task">The task to be executed.</param>
+        protected override void QueueTask(Task task)
+        {
+            new Thread(() => TryExecuteTask(task)) { IsBackground = true }.Start();
+        }
+
+        /// <summary>Runs the provided task on the current thread.</summary>
+        /// <param name="task">The task to be executed.</param>
+        /// <param name="taskWasPreviouslyQueued">Ignored.</param>
+        /// <returns>Whether the task could be executed on the current thread.</returns>
+        protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
+        {
+            return TryExecuteTask(task);
+        }
+    }
+}
diff --git a/trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/WorkStealingTaskScheduler.cs b/trunk/Libraries/ParallelExtensionsExtras/TaskSchedulers/WorkStealingTaskScheduler.cs
new file mode 100644 (file)
index 0000000..c172892
--- /dev/null
@@ -0,0 +1,488 @@
+//--------------------------------------------------------------------------
+// 
+//  Copyright (c) Microsoft Corporation.  All rights reserved. 
+// 
+//  File: WorkStealingTaskScheduler.cs
+//
+//--------------------------------------------------------------------------
+
+using System.Collections.Generic;
+
+namespace System.Threading.Tasks.Schedulers
+{
+    /// <summary>Provides a work-stealing scheduler.</summary>
+    public class WorkStealingTaskScheduler : TaskScheduler, IDisposable
+    {
+        private readonly int m_concurrencyLevel;
+        private readonly Queue<Task> m_queue = new Queue<Task>();
+        private WorkStealingQueue<Task>[] m_wsQueues = new WorkStealingQueue<Task>[Environment.ProcessorCount];
+        private Lazy<Thread[]> m_threads;
+        private int m_threadsWaiting;
+        private bool m_shutdown;
+        [ThreadStatic]
+        private static WorkStealingQueue<Task> m_wsq;
+
+        /// <summary>Initializes a new instance of the WorkStealingTaskScheduler class.</summary>
+        /// <remarks>This constructors defaults to using twice as many threads as there are processors.</remarks>
+        public WorkStealingTaskScheduler() : this(Environment.ProcessorCount * 2) { }
+
+        /// <summary>Initializes a new instance of the WorkStealingTaskScheduler class.</summary>
+        /// <param name="concurrencyLevel">The number of threads to use in the scheduler.</param>
+        public WorkStealingTaskScheduler(int concurrencyLevel)
+        {
+            // Store the concurrency level
+            if (concurrencyLevel <= 0) throw new ArgumentOutOfRangeException("concurrencyLevel");
+            m_concurrencyLevel = concurrencyLevel;
+
+            // Set up threads
+            m_threads = new Lazy<Thread[]>(() =>
+            {
+                var threads = new Thread[m_concurrencyLevel];
+                for (int i = 0; i < threads.Length; i++)
+                {
+                    threads[i] = new Thread(DispatchLoop) { IsBackground = true };
+                    threads[i].Start();
+                }
+                return threads;
+            });
+        }
+
+        /// <summary>Queues a task to the scheduler.</summary>
+        /// <param name="task">The task to be scheduled.</param>
+        protected override void QueueTask(Task task)
+        {
+            // Make sure the pool is started, e.g. that all threads have been created.
+            m_threads.Force();
+
+            // If the task is marked as long-running, give it its own dedicated thread
+            // rather than queueing it.
+            if ((task.CreationOptions & TaskCreationOptions.LongRunning) != 0)
+            {
+                new Thread(state => base.TryExecuteTask((Task)state)) { IsBackground = true }.Start(task);
+            }
+            else
+            {
+                // Otherwise, insert the work item into a queue, possibly waking a thread.
+                // If there's a local queue and the task does not prefer to be in the global queue,
+                // add it to the local queue.
+                WorkStealingQueue<Task> wsq = m_wsq;
+                if (wsq != null && ((task.CreationOptions & TaskCreationOptions.PreferFairness) == 0))
+                {
+                    // Add to the local queue and notify any waiting threads that work is available.
+                    // Races may occur which result in missed event notifications, but they're benign in that
+                    // this thread will eventually pick up the work item anyway, as will other threads when another
+                    // work item notification is received.
+                    wsq.LocalPush(task);
+                    if (m_threadsWaiting > 0) // OK to read lock-free.
+                    {
+                        lock (m_queue) { Monitor.Pulse(m_queue); }
+                    }
+                }
+                // Otherwise, add the work item to the global queue
+                else
+                {
+                    lock (m_queue)
+                    {
+                        m_queue.Enqueue(task);
+                        if (m_threadsWaiting > 0) Monitor.Pulse(m_queue);
+                    }
+                }
+            }
+        }
+
+        /// <summary>Executes a task on the current thread.</summary>
+        /// <param name="task">The task to be executed.</param>
+        /// <param name="taskWasPreviouslyQueued">Ignored.</param>
+        /// <returns>Whether the task could be executed.</returns>
+        protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
+        {
+            return TryExecuteTask(task);
+
+            // // Optional replacement: Instead of always trying to execute the task (which could
+            // // benignly leave a task in the queue that's already been executed), we
+            // // can search the current work-stealing queue and remove the task,
+            // // executing it inline only if it's found.
+            // WorkStealingQueue<Task> wsq = m_wsq;
+            // return wsq != null && wsq.TryFindAndPop(task) && TryExecuteTask(task);
+        }
+
+        /// <summary>Gets the maximum concurrency level supported by this scheduler.</summary>
+        public override int MaximumConcurrencyLevel
+        {
+            get { return m_concurrencyLevel; }
+        }
+
+        /// <summary>Gets all of the tasks currently scheduled to this scheduler.</summary>
+        /// <returns>An enumerable containing all of the scheduled tasks.</returns>
+        protected override IEnumerable<Task> GetScheduledTasks()
+        {
+            // Keep track of all of the tasks we find
+            List<Task> tasks = new List<Task>();
+
+            // Get all of the global tasks.  We use TryEnter so as not to hang
+            // a debugger if the lock is held by a frozen thread.
+            bool lockTaken = false;
+            try
+            {
+                Monitor.TryEnter(m_queue, ref lockTaken);
+                if (lockTaken) tasks.AddRange(m_queue.ToArray());
+                else throw new NotSupportedException();
+            }
+            finally
+            {
+                if (lockTaken) Monitor.Exit(m_queue);
+            }
+
+            // Now get all of the tasks from the work-stealing queues
+            WorkStealingQueue<Task>[] queues = m_wsQueues;
+            for (int i = 0; i < queues.Length; i++)
+            {
+                WorkStealingQueue<Task> wsq = queues[i];
+                if (wsq != null) tasks.AddRange(wsq.ToArray());
+            }
+
+            // Return to the debugger all of the collected task instances
+            return tasks;
+        }
+
+        /// <summary>Adds a work-stealing queue to the set of queues.</summary>
+        /// <param name="wsq">The queue to be added.</param>
+        private void AddWsq(WorkStealingQueue<Task> wsq)
+        {
+            lock (m_wsQueues)
+            {
+                // Find the next open slot in the array. If we find one,
+                // store the queue and we're done.
+                int i;
+                for (i = 0; i < m_wsQueues.Length; i++)
+                {
+                    if (m_wsQueues[i] == null)
+                    {
+                        m_wsQueues[i] = wsq;
+                        return;
+                    }
+                }
+
+                // We couldn't find an open slot, so double the length 
+                // of the array by creating a new one, copying over,
+                // and storing the new one. Here, i == m_wsQueues.Length.
+                WorkStealingQueue<Task>[] queues = new WorkStealingQueue<Task>[i * 2];
+                Array.Copy(m_wsQueues, queues, i);
+                queues[i] = wsq;
+                m_wsQueues = queues;
+            }
+        }
+
+        /// <summary>Remove a work-stealing queue from the set of queues.</summary>
+        /// <param name="wsq">The work-stealing queue to remove.</param>
+        private void RemoveWsq(WorkStealingQueue<Task> wsq)
+        {
+            lock (m_wsQueues)
+            {
+                // Find the queue, and if/when we find it, null out its array slot
+                for (int i = 0; i < m_wsQueues.Length; i++)
+                {
+                    if (m_wsQueues[i] == wsq)
+                    {
+                        m_wsQueues[i] = null;
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// The dispatch loop run by each thread in the scheduler.
+        /// </summary>
+        private void DispatchLoop()
+        {
+            // Create a new queue for this thread, store it in TLS for later retrieval,
+            // and add it to the set of queues for this scheduler.
+            WorkStealingQueue<Task> wsq = new WorkStealingQueue<Task>();
+            m_wsq = wsq;
+            AddWsq(wsq);
+
+            try
+            {
+                // Until there's no more work to do...
+                while (true)
+                {
+                    Task wi = null;
+
+                    // Search order: (1) local WSQ, (2) global Q, (3) steals from other queues.
+                    if (!wsq.LocalPop(ref wi))
+                    {
+                        // We weren't able to get a task from the local WSQ
+                        bool searchedForSteals = false;
+                        while (true)
+                        {
+                            lock (m_queue)
+                            {
+                                // If shutdown was requested, exit the thread.
+                                if (m_shutdown)
+                                    return;
+
+                                // (2) try the global queue.
+                                if (m_queue.Count != 0)
+                                {
+                                    // We found a work item! Grab it ...
+                                    wi = m_queue.Dequeue();
+                                    break;
+                                }
+                                else if (searchedForSteals)
+                                {
+                                    // Note that we're not waiting for work, and then wait
+                                    m_threadsWaiting++;
+                                    try { Monitor.Wait(m_queue); }
+                                    finally { m_threadsWaiting--; }
+
+                                    // If we were signaled due to shutdown, exit the thread.
+                                    if (m_shutdown)
+                                        return;
+
+                                    searchedForSteals = false;
+                                    continue;
+                                }
+                            }
+
+                            // (3) try to steal.
+                            WorkStealingQueue<Task>[] wsQueues = m_wsQueues;
+                            int i;
+                            for (i = 0; i < wsQueues.Length; i++)
+                            {
+                                WorkStealingQueue<Task> q = wsQueues[i];
+                                if (q != null && q != wsq && q.TrySteal(ref wi)) break;
+                            }
+
+                            if (i != wsQueues.Length) break;
+
+                            searchedForSteals = true;
+                        }
+                    }
+
+                    // ...and Invoke it.
+                    TryExecuteTask(wi);
+                }
+            }
+            finally
+            {
+                RemoveWsq(wsq);
+            }
+        }
+
+        /// <summary>Signal the scheduler to shutdown and wait for all threads to finish.</summary>
+        public void Dispose()
+        {
+            m_shutdown = true;
+            if (m_queue != null && m_threads.IsValueCreated)
+            {
+                var threads = m_threads.Value;
+                lock (m_queue) Monitor.PulseAll(m_queue);
+                for (int i = 0; i < threads.Length; i++) threads[i].Join();
+            }
+        }
+    }
+
+    /// <summary>A work-stealing queue.</summary>
+    /// <typeparam name="T">Specifies the type of data stored in the queue.</typeparam>
+    internal class WorkStealingQueue<T> where T : class
+    {
+        private const int INITIAL_SIZE = 32;
+        private T[] m_array = new T[INITIAL_SIZE];
+        private int m_mask = INITIAL_SIZE - 1;
+        private volatile int m_headIndex = 0;
+        private volatile int m_tailIndex = 0;
+
+        private object m_foreignLock = new object();
+
+        internal void LocalPush(T obj)
+        {
+            int tail = m_tailIndex;
+
+            // When there are at least 2 elements' worth of space, we can take the fast path.
+            if (tail < m_headIndex + m_mask)
+            {
+                m_array[tail & m_mask] = obj;
+                m_tailIndex = tail + 1;
+            }
+            else
+            {
+                // We need to contend with foreign pops, so we lock.
+                lock (m_foreignLock)
+                {
+                    int head = m_headIndex;
+                    int count = m_tailIndex - m_headIndex;
+
+                    // If there is still space (one left), just add the element.
+                    if (count >= m_mask)
+                    {
+                        // We're full; expand the queue by doubling its size.
+                        T[] newArray = new T[m_array.Length << 1];
+                        for (int i = 0; i < m_array.Length; i++)
+                            newArray[i] = m_array[(i + head) & m_mask];
+
+                        // Reset the field values, incl. the mask.
+                        m_array = newArray;
+                        m_headIndex = 0;
+                        m_tailIndex = tail = count;
+                        m_mask = (m_mask << 1) | 1;
+                    }
+
+                    m_array[tail & m_mask] = obj;
+                    m_tailIndex = tail + 1;
+                }
+            }
+        }
+
+        internal bool LocalPop(ref T obj)
+        {
+            while (true)
+            {
+                // Decrement the tail using a fence to ensure subsequent read doesn't come before.
+                int tail = m_tailIndex;
+                if (m_headIndex >= tail)
+                {
+                    obj = null;
+                    return false;
+                }
+
+                tail -= 1;
+#pragma warning disable 0420
+                Interlocked.Exchange(ref m_tailIndex, tail);
+#pragma warning restore 0420
+
+                // If there is no interaction with a take, we can head down the fast path.
+                if (m_headIndex <= tail)
+                {
+                    int idx = tail & m_mask;
+                    obj = m_array[idx];
+
+                    // Check for nulls in the array.
+                    if (obj == null) continue;
+
+                    m_array[idx] = null;
+                    return true;
+                }
+                else
+                {
+                    // Interaction with takes: 0 or 1 elements left.
+                    lock (m_foreignLock)
+                    {
+                        if (m_headIndex <= tail)
+                        {
+                            // Element still available. Take it.
+                            int idx = tail & m_mask;
+                            obj = m_array[idx];
+
+                            // Check for nulls in the array.
+                            if (obj == null) continue;
+
+                            m_array[idx] = null;
+                            return true;
+                        }
+                        else
+                        {
+                            // We lost the race, element was stolen, restore the tail.
+                            m_tailIndex = tail + 1;
+                            obj = null;
+                            return false;
+                        }
+                    }
+                }
+            }
+        }
+
+        internal bool TrySteal(ref T obj)
+        {
+            obj = null;
+
+            while (true)
+            {
+                if (m_headIndex >= m_tailIndex)
+                    return false;
+
+                lock (m_foreignLock)
+                {
+                    // Increment head, and ensure read of tail doesn't move before it (fence).
+                    int head = m_headIndex;
+#pragma warning disable 0420
+                    Interlocked.Exchange(ref m_headIndex, head + 1);
+#pragma warning restore 0420
+
+                    if (head < m_tailIndex)
+                    {
+                        int idx = head & m_mask;
+                        obj = m_array[idx];
+
+                        // Check for nulls in the array.
+                        if (obj == null) continue;
+
+                        m_array[idx] = null;
+                        return true;
+                    }
+                    else
+                    {
+                        // Failed, restore head.
+                        m_headIndex = head;
+                        obj = null;
+                    }
+                }
+
+                return false;
+            }
+        }
+
+        internal bool TryFindAndPop(T obj)
+        {
+            // We do an O(N) search for the work item. The theory of work stealing and our
+            // inlining logic is that most waits will happen on recently queued work.  And
+            // since recently queued work will be close to the tail end (which is where we
+            // begin our search), we will likely find it quickly.  In the worst case, we
+            // will traverse the whole local queue; this is typically not going to be a
+            // problem (although degenerate cases are clearly an issue) because local work
+            // queues tend to be somewhat shallow in length, and because if we fail to find
+            // the work item, we are about to block anyway (which is very expensive).
+
+            for (int i = m_tailIndex - 1; i >= m_headIndex; i--)
+            {
+                if (m_array[i & m_mask] == obj)
+                {
+                    // If we found the element, block out steals to avoid interference.
+                    lock (m_foreignLock)
+                    {
+                        // If we lost the race, bail.
+                        if (m_array[i & m_mask] == null)
+                        {
+                            return false;
+                        }
+
+                        // Otherwise, null out the element.
+                        m_array[i & m_mask] = null;
+
+                        // And then check to see if we can fix up the indexes (if we're at
+                        // the edge).  If we can't, we just leave nulls in the array and they'll
+                        // get filtered out eventually (but may lead to superflous resizing).
+                        if (i == m_tailIndex)
+                            m_tailIndex -= 1;
+                        else if (i == m_headIndex)
+                            m_headIndex += 1;
+
+                        return true;
+                    }
+                }
+            }
+
+            return false;
+        }
+
+        internal T[] ToArray()
+        {
+            List<T> list = new List<T>();
+            for (int i = m_tailIndex - 1; i >= m_headIndex; i--)
+            {
+                T obj = m_array[i & m_mask];
+                if (obj != null) list.Add(obj);
+            }
+            return list.ToArray();
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Libraries/ParallelExtensionsExtras/Utils/SortedTopN.cs b/trunk/Libraries/ParallelExtensionsExtras/Utils/SortedTopN.cs
new file mode 100644 (file)
index 0000000..0732769
--- /dev/null
@@ -0,0 +1,84 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Collections;
+
+namespace System.Linq
+{
+    internal class SortedTopN<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
+    {
+        private int _n;
+        private List<TKey> _topNKeys;
+        private List<TValue> _topNValues;
+        private IComparer<TKey> _comparer;
+
+        public SortedTopN(int count, IComparer<TKey> comparer)
+        {
+            if (count < 1) throw new ArgumentOutOfRangeException("count");
+            if (comparer == null) throw new ArgumentNullException("comparer");
+            _n = count;
+            _topNKeys = new List<TKey>(count);
+            _topNValues = new List<TValue>(count);
+            _comparer = comparer;
+        }
+
+        public bool Add(KeyValuePair<TKey,TValue> item)
+        {
+            return Add(item.Key, item.Value);
+        }
+
+        public bool Add(TKey key, TValue value)
+        {
+            int position = _topNKeys.BinarySearch(key, _comparer);
+            if (position < 0) position = ~position;
+            if (_topNKeys.Count < _n || position != 0)
+            {
+                // Empty out an item if we're already full and we need to
+                // add another
+                if (_topNKeys.Count == _n)
+                {
+                    _topNKeys.RemoveAt(0);
+                    _topNValues.RemoveAt(0);
+                    position--;
+                }
+
+                // Insert or add based on where we're adding
+                if (position < _n)
+                {
+                    _topNKeys.Insert(position, key);
+                    _topNValues.Insert(position, value);
+                }
+                else
+                {
+                    _topNKeys.Add(key);
+                    _topNValues.Add(value);
+                }
+                return true;
+            }
+
+            // No room for this item
+            return false;
+        }
+
+        public IEnumerable<TValue> Values
+        {
+            get
+            {
+                for (int i = _topNKeys.Count - 1; i >= 0; i--)
+                {
+                    yield return _topNValues[i];
+                }
+            }
+        }
+
+        public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
+        {
+            for (int i = _topNKeys.Count - 1; i>=0; i--)
+            {
+                yield return new KeyValuePair<TKey, TValue>(_topNKeys[i], _topNValues[i]);
+            }
+        }
+        IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
+    }
+}
diff --git a/trunk/Pithos.Client.Test/Pithos.Client.Test.csproj b/trunk/Pithos.Client.Test/Pithos.Client.Test.csproj
new file mode 100644 (file)
index 0000000..0b64b84
--- /dev/null
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{822F885B-83E8-4A9A-B02E-0FEAE444D960}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Pithos.Client.Test</RootNamespace>
+    <AssemblyName>Pithos.Client.Test</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="nunit.framework, Version=2.5.10.11092, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL" />
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\Pithos.Client\Pithos.Client.csproj">
+      <Project>{5AC90E5E-60C6-4F53-9444-6088BD7BC929}</Project>
+      <Name>Pithos.Client</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\Pithos.Interfaces\Pithos.Interfaces.csproj">
+      <Project>{7EEFF32F-CCF8-436A-9E0B-F40434C09AF4}</Project>
+      <Name>Pithos.Interfaces</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
diff --git a/trunk/Pithos.Client.Test/Properties/AssemblyInfo.cs b/trunk/Pithos.Client.Test/Properties/AssemblyInfo.cs
new file mode 100644 (file)
index 0000000..6054dd6
--- /dev/null
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Pithos.Client.Test")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("Pithos.Client.Test")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("0d5e9779-d13e-4024-b945-71e083b7b3f8")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/trunk/Pithos.Client/AccountSettings.cs b/trunk/Pithos.Client/AccountSettings.cs
new file mode 100644 (file)
index 0000000..258c6bd
--- /dev/null
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Pithos.Client
+{
+    public class AccountSettings
+    {
+        public string AccountName { get; set; }
+        public string ApiKey { get; set; }
+
+        private List<string> _selectiveFolders=new List<string>();
+        public List<string> SelectiveFolders
+        {
+            get { return _selectiveFolders; }
+            set { _selectiveFolders = value; }
+        }
+
+        
+    }
+}
diff --git a/trunk/Pithos.Client/App_Code/LICENSE.txt b/trunk/Pithos.Client/App_Code/LICENSE.txt
new file mode 100644 (file)
index 0000000..f90aa76
--- /dev/null
@@ -0,0 +1,11 @@
+New BSD License
+http://www.opensource.org/licenses/bsd-license.php
+Copyright (c) 2009, Rob Conery (robconery@gmail.com)
+All rights reserved.    
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+Neither the name of the SubSonic nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/trunk/Pithos.Client/App_Code/Massive.cs b/trunk/Pithos.Client/App_Code/Massive.cs
new file mode 100644 (file)
index 0000000..af02d0c
--- /dev/null
@@ -0,0 +1,400 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Configuration;
+using System.Data;
+using System.Data.Common;
+using System.Dynamic;
+using System.Linq;
+using System.Text;
+
+namespace Massive {
+    public static class ObjectExtensions {
+        /// <summary>
+        /// Extension method for adding in a bunch of parameters
+        /// </summary>
+        public static void AddParams(this DbCommand cmd, object[] args) {
+            foreach (var item in args) {
+                AddParam(cmd, item);
+            }
+        }
+        /// <summary>
+        /// Extension for adding single parameter
+        /// </summary>
+        public static void AddParam(this DbCommand cmd, object item) {
+            var p = cmd.CreateParameter();
+            p.ParameterName = string.Format("@{0}", cmd.Parameters.Count);
+            //fix for NULLs as parameter values
+            if (item == null) {
+                p.Value = DBNull.Value;
+            } else {
+                //fix for Guids
+                if (item.GetType() == typeof(Guid)) {
+                    p.Value = item.ToString();
+                    p.DbType = DbType.String;
+                } else {
+                    p.Value = item;
+                }
+            }
+            cmd.Parameters.Add(p);
+        }
+        /// <summary>
+        /// Turns an IDataReader to a Dynamic list of things
+        /// </summary>
+        public static List<dynamic> ToExpandoList(this IDataReader rdr) {
+            var result = new List<dynamic>();
+            //work with the Expando as a Dictionary
+            while (rdr.Read()) {
+                dynamic e = new ExpandoObject();
+                var d = e as IDictionary<string, object>;
+                for (int i = 0; i < rdr.FieldCount; i++)
+                    d.Add(rdr.GetName(i), rdr[i]);
+                result.Add(e);
+            }
+            return result;
+        }
+        /// <summary>
+        /// Turns the object into an ExpandoObject
+        /// </summary>
+        /// <param name="o"></param>
+        /// <returns></returns>
+        public static dynamic ToExpando(this object o) {
+            var result = new ExpandoObject();
+            var d = result as IDictionary<string, object>; //work with the Expando as a Dictionary
+            if (o.GetType() == typeof(ExpandoObject)) return o; //shouldn't have to... but just in case
+            //special for form submissions
+            if (o.GetType() == typeof(NameValueCollection)) {
+                var nv = (NameValueCollection)o;
+                nv.Cast<string>().Select(key => new KeyValuePair<string, object>(key, nv[key])).ToList().ForEach(i => d.Add(i));
+            } else {
+                //assume it's a regular lovely object
+                var props = o.GetType().GetProperties();
+                foreach (var item in props) {
+                    d.Add(item.Name, item.GetValue(o, null));
+                }
+            }
+            return result;
+        }
+        /// <summary>
+        /// Turns the object into a Dictionary
+        /// </summary>
+        /// <param name="thingy"></param>
+        /// <returns></returns>
+        public static IDictionary<string, object> ToDictionary(this object thingy) {
+            return (IDictionary<string, object>)thingy.ToExpando();
+        }
+    }
+    /// <summary>
+    /// A class that wraps your database table in Dynamic Funtime
+    /// </summary>
+    public abstract class DynamicModel : DynamicObject {
+        DbProviderFactory _factory;
+        string _connectionStringName;
+        string _connectionString;
+
+        public IList<dynamic> Query(string sql, params object[] args) {
+            var result = new List<dynamic>();
+            using (var conn = OpenConnection()) {
+                using (var cmd = CreateCommand(sql, args)) {
+                    cmd.Connection = conn;
+                    using (var rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection)) {
+                        result = rdr.ToExpandoList();
+                    }
+                }
+            }
+            return result;
+        }
+        /// <summary>
+        /// Creates a DBCommand that you can use for loving your database.
+        /// </summary>
+        DbCommand CreateCommand(string sql, params object[] args) {
+            DbCommand result = null;
+            result = _factory.CreateCommand();
+            result.CommandText = sql;
+            if (args.Length > 0)
+                result.AddParams(args);
+            return result;
+        }
+        DbConnection GetConnection() {
+            var connection = _factory.CreateConnection();
+            connection.ConnectionString = _connectionString;
+            return connection;
+        }
+        DbConnection OpenConnection() {
+            var conn = GetConnection();
+            conn.Open();
+            return conn;
+        }
+        /// <summary>
+        /// Creates a slick, groovy little wrapper for your action
+        /// </summary>
+        /// <param name="connectionStringName"></param>
+        public DynamicModel(string connectionStringName) {
+            //can be overridden by property setting
+            TableName = this.GetType().Name;
+            _connectionStringName = connectionStringName;
+
+            var providerName = "System.Data.SqlClient";
+            if (ConfigurationManager.ConnectionStrings[_connectionStringName] != null) {
+                providerName = ConfigurationManager.ConnectionStrings[_connectionStringName].ProviderName ?? "System.Data.SqlClient";
+            } else {
+                throw new InvalidOperationException("Can't find a connection string with the name '" + _connectionStringName + "'");
+            }
+            _factory = DbProviderFactories.GetFactory(providerName);
+            _connectionString = ConfigurationManager.ConnectionStrings[_connectionStringName].ConnectionString;
+        }
+        string _primaryKeyField;
+        /// <summary>
+        /// Conventionally returns a PK field. The default is "ID" if you don't set one
+        /// </summary>
+        public string PrimaryKeyField {
+            get { return string.IsNullOrEmpty(_primaryKeyField) ? /*a bit of convention here*/ "ID" : /*oh well - did our best*/ _primaryKeyField; }
+            set { _primaryKeyField = value; }
+        }
+        /// <summary>
+        /// Conventionally introspects the object passed in for a field that 
+        /// looks like a PK. If you've named your PrimaryKeyField, this becomes easy
+        /// </summary>
+        public bool HasPrimaryKey(object o) {
+            var result = o.ToDictionary().ContainsKey(PrimaryKeyField);
+            return result;
+        }
+        /// <summary>
+        /// If the object passed in has a property with the same name as your PrimaryKeyField
+        /// it is returned here.
+        /// </summary>
+        public object GetPrimaryKey(object o) {
+            var d = o.ToDictionary();
+            object result = null;
+            d.TryGetValue(PrimaryKeyField, out result);
+            return result;
+        }
+        /// <summary>
+        /// The name of the Database table we're working with. This defaults to 
+        /// the class name - set this value if it's different
+        /// </summary>
+        public string TableName { get; set; }
+        /// <summary>
+        /// Adds a record to the database. You can pass in an Anonymous object, an ExpandoObject,
+        /// A regular old POCO, or a NameValueColletion from a Request.Form or Request.QueryString
+        /// </summary>
+        public dynamic Insert(object o) {
+            dynamic result = 0;
+            if (BeforeInsert(o)) {
+                using (var conn = OpenConnection()) {
+                    using (var cmd = CreateInsertCommand(o)) {
+                        cmd.Connection = conn;
+                        result = cmd.ExecuteScalar();
+                    }
+                    AfterInsert(o);
+                }
+            }
+            return result;
+        }
+
+        /// <summary>
+        /// Creates a command for use with transactions - internal stuff mostly, but here for you to play with
+        /// </summary>
+        public DbCommand CreateInsertCommand(object o) {
+            DbCommand result = null;
+            //turn this into an expando - we'll need that for the validators
+            var expando = o.ToExpando();
+            var settings = (IDictionary<string, object>)expando;
+            var sbKeys = new StringBuilder();
+            var sbVals = new StringBuilder();
+            var stub = "INSERT INTO {0} ({1}) \r\n VALUES ({2}); \r\nSELECT SCOPE_IDENTITY()";
+            result = CreateCommand(stub);
+
+            int counter = 0;
+            foreach (var item in settings) {
+                sbKeys.AppendFormat("{0},", item.Key);
+                sbVals.AppendFormat("@{0},", counter.ToString());
+                result.AddParam(item.Value);
+                counter++;
+            }
+            if (counter > 0) {
+                //strip off trailing commas
+                var keys = sbKeys.ToString().Substring(0, sbKeys.Length - 1);
+                var vals = sbVals.ToString().Substring(0, sbVals.Length - 1);
+                var sql = string.Format(stub, TableName, keys, vals);
+                result.CommandText = sql;
+            } else throw new InvalidOperationException("Can't parse this object to the database - there are no properties set");
+            return result;
+        }
+
+        /// <summary>
+        /// Creates a command for use with transactions - internal stuff mostly, but here for you to play with
+        /// </summary>
+        public DbCommand CreateUpdateCommand(object o, object key) {
+            var expando = o.ToExpando();
+            var settings = (IDictionary<string, object>)expando;
+            var sbKeys = new StringBuilder();
+            var stub = "UPDATE {0} SET {1} WHERE {2} = @{3}";
+            var args = new List<object>();
+            var result = CreateCommand(stub);
+            int counter = 0;
+            foreach (var item in settings) {
+                var val = item.Value;
+                if (!item.Key.Equals(PrimaryKeyField, StringComparison.CurrentCultureIgnoreCase) && item.Value != null) {
+                    result.AddParam(val);
+                    sbKeys.AppendFormat("{0} = @{1}, \r\n", item.Key, counter.ToString());
+                    counter++;
+                }
+            }
+            if (counter > 0) {
+                //add the key
+                result.AddParam(key);
+                //strip the last commas
+                var keys = sbKeys.ToString().Substring(0, sbKeys.Length - 4);
+                result.CommandText = string.Format(stub, TableName, keys, PrimaryKeyField, counter);
+            } else throw new InvalidOperationException("No parsable object was sent in - could not divine any name/value pairs");
+            return result;
+        }
+        /// <summary>
+        /// Updates a record in the database. You can pass in an Anonymous object, an ExpandoObject,
+        /// A regular old POCO, or a NameValueCollection from a Request.Form or Request.QueryString
+        /// </summary>
+        public int Update(object o, object key) {
+            //turn this into an expando - we'll need that for the validators
+            int result = 0;
+            if (BeforeUpdate(o)) {
+                using (var conn = OpenConnection()) {
+                    using (var cmd = CreateUpdateCommand(o, key)) {
+                        result = cmd.ExecuteNonQuery();
+                        AfterUpdate(o);
+                    }
+                }
+            }
+            return result;
+        }
+        /// <summary>
+        /// Updates a bunch of records in the database within a transaction. You can pass Anonymous objects, ExpandoObjects,
+        /// Regular old POCOs - these all have to have a PK set
+        /// </summary>
+        public int InsertMany(IEnumerable<object> things) {
+            int result = 0;
+            using (var conn = OpenConnection()) {
+                using (var tx = conn.BeginTransaction()) {
+                    foreach (var item in things) {
+                        if (BeforeInsert(item)) {
+                            using (var cmd = CreateInsertCommand(item)) {
+                                cmd.Connection = conn;
+                                cmd.Transaction = tx;
+                                cmd.ExecuteNonQuery();
+                            }
+                            AfterInsert(item);
+                        }
+                        result++;
+                    }
+                    tx.Commit();
+                }
+            }
+            return result;
+        }
+        /// <summary>
+        /// Updates a bunch of records in the database within a transaction. You can pass Anonymous objects, ExpandoObjects,
+        /// Regular old POCOs - these all have to have a PK set
+        /// </summary>
+        public int UpdateMany(IEnumerable<object> things) {
+            int result = 0;
+            using (var conn = OpenConnection()) {
+                using (var tx = conn.BeginTransaction()) {
+                    foreach (var item in things) {
+                        var pk = GetPrimaryKey(item);
+                        if (pk == null)
+                            throw new InvalidOperationException("Please be sure to set a value for the primary key");
+                        if (BeforeUpdate(item)) {
+                            using (var cmd = CreateUpdateCommand(item, pk)) {
+                                cmd.Connection = conn;
+                                cmd.Transaction = tx;
+                                cmd.ExecuteNonQuery();
+                            }
+                            AfterUpdate(item);
+                        }
+                        result++;
+                    }
+                    tx.Commit();
+                }
+            }
+            return result;
+        }
+        /// <summary>
+        /// If you're feeling lazy, or are just unsure about whether to use Update or Insert you can use
+        /// this method. It will look for a PrimaryKeyField with a set value to determine if this should
+        /// be an Insert or Save. You can pass in an Anonymous object, an ExpandoObject,
+        /// A regular old POCO, or a NameValueColletion from a Request.Form or Request.QueryString
+        /// </summary>
+        public dynamic Save(object o) {
+            dynamic result = 0;
+            if (BeforeSave(o)) {
+                var expando = o.ToExpando();
+                //decide insert or update
+                result = HasPrimaryKey(expando) ? Update(expando, GetPrimaryKey(o)) : Insert(expando);
+                AfterSave(o);
+            }
+            return result;
+        }
+        /// <summary>
+        /// Removes a record from the database
+        /// </summary>
+        public int Delete(object key) {
+            //execute
+            var sql = string.Format("DELETE FROM {0} WHERE {1} = @0", TableName, PrimaryKeyField);
+            var result = 0;
+            using (var conn = OpenConnection()) {
+                using (var cmd = CreateCommand(sql, key)) {
+                    cmd.Connection = conn;
+                    result = cmd.ExecuteNonQuery();
+                }
+            }
+            return result;
+        }
+        /// <summary>
+        /// Removes one or more records from the DB according to the passed-in WHERE
+        /// </summary>
+        public dynamic Delete(string where, params object[] args) {
+            //execute
+            var sql = string.Format("DELETE FROM {0} ", TableName);
+            sql += where.Trim().StartsWith("where", StringComparison.CurrentCultureIgnoreCase) ? where : "WHERE " + where;
+            var result = 0;
+            using (var conn = OpenConnection()) {
+                using (var cmd = CreateCommand(sql, args)) {
+                    cmd.Connection = conn;
+                    result = cmd.ExecuteNonQuery();
+                }
+            }
+            return result;
+        }
+        /// <summary>
+        /// Returns all records complying with the passed-in WHERE clause and arguments, 
+        /// ordered as specified, limited (TOP) by limit.
+        /// </summary>
+        public IEnumerable<dynamic> All(string where = "", string orderBy = "", int limit = 0, params object[] args) {
+            string sql = limit > 0 ? "SELECT TOP " + limit + " * FROM {0} " : "SELECT * FROM {0} ";
+            if (!string.IsNullOrEmpty(where))
+                sql += where.Trim().StartsWith("where", StringComparison.CurrentCultureIgnoreCase) ? where : "WHERE " + where;
+            if (!String.IsNullOrEmpty(orderBy))
+                sql += orderBy.Trim().StartsWith("order by", StringComparison.CurrentCultureIgnoreCase) ? orderBy : " ORDER BY " + orderBy;
+            return Query(string.Format(sql, TableName), args);
+        }
+        /// <summary>
+        /// Returns a single row from the database
+        /// </summary>
+        /// <returns>ExpandoObject</returns>
+        public dynamic Single(object key) {
+            var sql = string.Format("SELECT * FROM {0} WHERE {1} = @0", TableName, PrimaryKeyField);
+            return Query(sql, key).FirstOrDefault();
+        }
+        #region hooks
+        //hooks for save routines
+        public virtual bool BeforeInsert(object o) { return true; }
+        public virtual bool BeforeUpdate(object o) { return true; }
+        public virtual bool BeforeSave(object o) { return true; }
+        public virtual bool BeforeDelete(object key) { return true; }
+        public virtual void AfterInsert(object o) { }
+        public virtual void AfterUpdate(object o) { }
+        public virtual void AfterSave(object o) { }
+        public virtual void AfterDelete(object key) { }
+        #endregion
+    }
+}
\ No newline at end of file
diff --git a/trunk/Pithos.Client/IoC.cs b/trunk/Pithos.Client/IoC.cs
new file mode 100644 (file)
index 0000000..97d8eb9
--- /dev/null
@@ -0,0 +1,56 @@
+using System;
+using System.ComponentModel.Composition.Hosting;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.ComponentModel.Composition;
+using Pithos.Core;
+
+namespace Pithos.Client
+{
+    public class IoC
+    {
+        public CompositionContainer Container;
+        
+        static readonly Lazy<IoC> Instance=new Lazy<IoC>();
+
+        public static IoC Current
+        {
+            get { return Instance.Value; }
+        }
+
+        public IoC()
+        {
+            var catalog = new AggregateCatalog();
+            var executingAssembly = Assembly.GetExecutingAssembly();
+            catalog.Catalogs.Add(new AssemblyCatalog(executingAssembly));
+
+            Type[] types = {typeof (PithosMonitor), typeof (Pithos.Network.CloudFilesClient)};
+            foreach (var type in types)
+            {
+                catalog.Catalogs.Add(new AssemblyCatalog(type.Assembly));    
+            }
+
+                                
+            
+            Container=new CompositionContainer(catalog);
+        }
+        
+
+
+        public T Compose<T>(T target)
+        {
+            try
+            {
+                Container.ComposeParts(target);
+                return target;
+            }
+            catch (Exception exc)
+            {
+                Trace.TraceError(exc.ToString());
+                throw;
+            }
+        }
+    }
+}
diff --git a/trunk/Pithos.Client/Pithos.Client.csproj b/trunk/Pithos.Client/Pithos.Client.csproj
new file mode 100644 (file)
index 0000000..20af9f8
--- /dev/null
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{5AC90E5E-60C6-4F53-9444-6088BD7BC929}</ProjectGuid>
+    <OutputType>WinExe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Pithos.Client</RootNamespace>
+    <AssemblyName>Pithos.Client</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
+    <FileAlignment>512</FileAlignment>
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+    <CodeContractsAssemblyMode>1</CodeContractsAssemblyMode>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
+    <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
+    <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
+    <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
+    <CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers>
+    <CodeContractsRunCodeAnalysis>True</CodeContractsRunCodeAnalysis>
+    <CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
+    <CodeContractsBoundsObligations>False</CodeContractsBoundsObligations>
+    <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
+    <CodeContractsEnumObligations>False</CodeContractsEnumObligations>
+    <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
+    <CodeContractsRunInBackground>True</CodeContractsRunInBackground>
+    <CodeContractsShowSquigglies>False</CodeContractsShowSquigglies>
+    <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
+    <CodeContractsEmitXMLDocs>True</CodeContractsEmitXMLDocs>
+    <CodeContractsCustomRewriterAssembly />
+    <CodeContractsCustomRewriterClass />
+    <CodeContractsLibPaths />
+    <CodeContractsExtraRewriteOptions />
+    <CodeContractsExtraAnalysisOptions />
+    <CodeContractsBaseLineFile />
+    <CodeContractsCacheAnalysisResults>False</CodeContractsCacheAnalysisResults>
+    <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
+    <CodeContractsReferenceAssembly>Build</CodeContractsReferenceAssembly>
+    <CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <PlatformTarget>x86</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.ComponentModel.Composition" />
+    <Reference Include="System.Configuration" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Security" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Deployment" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="AccountSettings.cs" />
+    <Compile Include="App_Code\Massive.cs" />
+    <Compile Include="IoC.cs" />
+    <Compile Include="PithosSettings.cs" />
+    <Compile Include="Preferences.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="Preferences.Designer.cs">
+      <DependentUpon>Preferences.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <EmbeddedResource Include="Preferences.resx">
+      <DependentUpon>Preferences.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Resources.resx</DependentUpon>
+      <DesignTime>True</DesignTime>
+    </Compile>
+    <None Include="app.config" />
+    <None Include="packages.config" />
+    <None Include="Properties\Settings.settings">
+      <Generator>SettingsSingleFileGenerator</Generator>
+      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+    </None>
+    <Compile Include="Properties\Settings.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Settings.settings</DependentUpon>
+      <DesignTimeSharedInput>True</DesignTimeSharedInput>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Resources\Tray.ico" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Resources\TraySynching.ico" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Resources\TrayInSynch.ico" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\..\..\ParallelProgrammingSamples\ParallelExtensionsExtras\ParallelExtensionsExtras.csproj">
+      <Project>{C45218F8-09E7-4F57-85BC-5D8D2AC736A3}</Project>
+      <Name>ParallelExtensionsExtras</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\Pithos.Core\Pithos.Core.csproj">
+      <Project>{142AF135-DF30-4563-B0AC-B604235AE874}</Project>
+      <Name>Pithos.Core</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\Pithos.Interfaces\Pithos.Interfaces.csproj">
+      <Project>{7EEFF32F-CCF8-436A-9E0B-F40434C09AF4}</Project>
+      <Name>Pithos.Interfaces</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\Pithos.Network\Pithos.Network.csproj">
+      <Project>{C8E2BC8B-C7F1-4222-855C-4B04A57FFDFD}</Project>
+      <Name>Pithos.Network</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="App_Code\LICENSE.txt" />
+    <Content Include="Filemeta.sdf">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include=".NETFramework,Version=v4.0,Profile=Client">
+      <Visible>False</Visible>
+      <ProductName>Microsoft .NET Framework 4 Client Profile %28x86 and x64%29</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.SQL.Server.Compact.3.5">
+      <Visible>False</Visible>
+      <ProductName>SQL Server Compact 3.5 SP2</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 3.1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
diff --git a/trunk/Pithos.Client/PithosFiles.db b/trunk/Pithos.Client/PithosFiles.db
new file mode 100644 (file)
index 0000000..4ca1146
Binary files /dev/null and b/trunk/Pithos.Client/PithosFiles.db differ
diff --git a/trunk/Pithos.Client/PithosSettings.cs b/trunk/Pithos.Client/PithosSettings.cs
new file mode 100644 (file)
index 0000000..95e3e0c
--- /dev/null
@@ -0,0 +1,48 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition;
+using System.Linq;
+using System.Text;
+using Pithos.Client.Properties;
+using Pithos.Interfaces;
+
+namespace Pithos.Client
+{
+    [Export(typeof(IPithosSettings))]
+    public class PithosSettings:IPithosSettings
+    {
+        public string PithosPath
+        {
+            get { return Settings.Default.PithosPath; }
+            set { Settings.Default.PithosPath=value; }
+        }
+
+        public string IconsPath
+        {
+            get { return Settings.Default.IconPath; }
+            set { Settings.Default.IconPath=value; }
+        }
+
+        public string UserName
+        {
+            get { return Settings.Default.UserName; }
+            set { Settings.Default.UserName=value; }
+        }
+
+        public string ApiKey
+        {
+            get { return Settings.Default.ApiKey; }
+            set { Settings.Default.ApiKey=value; }
+        }
+
+        public void Save()
+        {
+            Settings.Default.Save();
+        }
+
+        public void Reload()
+        {
+            Settings.Default.Reload();
+        }
+    }
+}
diff --git a/trunk/Pithos.Client/Preferences.Designer.cs b/trunk/Pithos.Client/Preferences.Designer.cs
new file mode 100644 (file)
index 0000000..8e2503d
--- /dev/null
@@ -0,0 +1,430 @@
+namespace Pithos.Client
+{
+    partial class Preferences
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.components = new System.ComponentModel.Container();
+            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Preferences));
+            this.tabControl1 = new System.Windows.Forms.TabControl();
+            this.tabAccount = new System.Windows.Forms.TabPage();
+            this.btnAccountVerify = new System.Windows.Forms.Button();
+            this.txtApiKey = new System.Windows.Forms.TextBox();
+            this.label2 = new System.Windows.Forms.Label();
+            this.textBox1 = new System.Windows.Forms.TextBox();
+            this.label1 = new System.Windows.Forms.Label();
+            this.btnRemoveAccount = new System.Windows.Forms.Button();
+            this.btnAddAccount = new System.Windows.Forms.Button();
+            this.listBox1 = new System.Windows.Forms.ListBox();
+            this.tabAdvanced = new System.Windows.Forms.TabPage();
+            this.btnBrowsePithosPath = new System.Windows.Forms.Button();
+            this.label3 = new System.Windows.Forms.Label();
+            this.txtPithosPath = new System.Windows.Forms.TextBox();
+            this.notifyIcon = new System.Windows.Forms.NotifyIcon(this.components);
+            this.systemMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
+            this.openPithosFolderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.launchPithosWebSiteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.recentlyChangedFilesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
+            this.spaceUserToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
+            this.statusToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator();
+            this.pauseSynchingToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.preferencesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator();
+            this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.panel1 = new System.Windows.Forms.Panel();
+            this.btnApply = new System.Windows.Forms.Button();
+            this.btnCancel = new System.Windows.Forms.Button();
+            this.btnOK = new System.Windows.Forms.Button();
+            this.pithosFolderBrowser = new System.Windows.Forms.FolderBrowserDialog();
+            this.tabControl1.SuspendLayout();
+            this.tabAccount.SuspendLayout();
+            this.tabAdvanced.SuspendLayout();
+            this.systemMenuStrip.SuspendLayout();
+            this.panel1.SuspendLayout();
+            this.SuspendLayout();
+            // 
+            // tabControl1
+            // 
+            this.tabControl1.Controls.Add(this.tabAccount);
+            this.tabControl1.Controls.Add(this.tabAdvanced);
+            this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.tabControl1.Location = new System.Drawing.Point(0, 0);
+            this.tabControl1.Name = "tabControl1";
+            this.tabControl1.SelectedIndex = 0;
+            this.tabControl1.Size = new System.Drawing.Size(462, 243);
+            this.tabControl1.TabIndex = 0;
+            // 
+            // tabAccount
+            // 
+            this.tabAccount.Controls.Add(this.btnAccountVerify);
+            this.tabAccount.Controls.Add(this.txtApiKey);
+            this.tabAccount.Controls.Add(this.label2);
+            this.tabAccount.Controls.Add(this.textBox1);
+            this.tabAccount.Controls.Add(this.label1);
+            this.tabAccount.Controls.Add(this.btnRemoveAccount);
+            this.tabAccount.Controls.Add(this.btnAddAccount);
+            this.tabAccount.Controls.Add(this.listBox1);
+            this.tabAccount.Location = new System.Drawing.Point(4, 22);
+            this.tabAccount.Name = "tabAccount";
+            this.tabAccount.Padding = new System.Windows.Forms.Padding(3);
+            this.tabAccount.Size = new System.Drawing.Size(454, 217);
+            this.tabAccount.TabIndex = 0;
+            this.tabAccount.Text = "Accounts";
+            this.tabAccount.UseVisualStyleBackColor = true;
+            this.tabAccount.Click += new System.EventHandler(this.tabAccount_Click);
+            // 
+            // btnAccountVerify
+            // 
+            this.btnAccountVerify.Location = new System.Drawing.Point(367, 89);
+            this.btnAccountVerify.Name = "btnAccountVerify";
+            this.btnAccountVerify.Size = new System.Drawing.Size(75, 23);
+            this.btnAccountVerify.TabIndex = 7;
+            this.btnAccountVerify.Text = "Verify";
+            this.btnAccountVerify.UseVisualStyleBackColor = true;
+            // 
+            // txtApiKey
+            // 
+            this.txtApiKey.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.txtApiKey.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::Pithos.Client.Properties.Settings.Default, "ApiKey", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
+            this.txtApiKey.Location = new System.Drawing.Point(208, 63);
+            this.txtApiKey.Name = "txtApiKey";
+            this.txtApiKey.Size = new System.Drawing.Size(234, 20);
+            this.txtApiKey.TabIndex = 6;
+            this.txtApiKey.Text = global::Pithos.Client.Properties.Settings.Default.ApiKey;
+            // 
+            // label2
+            // 
+            this.label2.AutoSize = true;
+            this.label2.Location = new System.Drawing.Point(205, 47);
+            this.label2.Name = "label2";
+            this.label2.Size = new System.Drawing.Size(45, 13);
+            this.label2.TabIndex = 5;
+            this.label2.Text = "API Key";
+            // 
+            // textBox1
+            // 
+            this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.textBox1.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::Pithos.Client.Properties.Settings.Default, "UserName", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
+            this.textBox1.Location = new System.Drawing.Point(208, 22);
+            this.textBox1.Name = "textBox1";
+            this.textBox1.Size = new System.Drawing.Size(234, 20);
+            this.textBox1.TabIndex = 4;
+            this.textBox1.Text = global::Pithos.Client.Properties.Settings.Default.UserName;
+            // 
+            // label1
+            // 
+            this.label1.AutoSize = true;
+            this.label1.Location = new System.Drawing.Point(205, 6);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(78, 13);
+            this.label1.TabIndex = 3;
+            this.label1.Text = "Account Name";
+            // 
+            // btnRemoveAccount
+            // 
+            this.btnRemoveAccount.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+            this.btnRemoveAccount.Location = new System.Drawing.Point(113, 188);
+            this.btnRemoveAccount.Name = "btnRemoveAccount";
+            this.btnRemoveAccount.Size = new System.Drawing.Size(75, 23);
+            this.btnRemoveAccount.TabIndex = 2;
+            this.btnRemoveAccount.Text = "Remove";
+            this.btnRemoveAccount.UseVisualStyleBackColor = true;
+            // 
+            // btnAddAccount
+            // 
+            this.btnAddAccount.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+            this.btnAddAccount.Location = new System.Drawing.Point(6, 188);
+            this.btnAddAccount.Name = "btnAddAccount";
+            this.btnAddAccount.Size = new System.Drawing.Size(75, 23);
+            this.btnAddAccount.TabIndex = 1;
+            this.btnAddAccount.Text = "Add";
+            this.btnAddAccount.UseVisualStyleBackColor = true;
+            // 
+            // listBox1
+            // 
+            this.listBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left)));
+            this.listBox1.FormattingEnabled = true;
+            this.listBox1.Location = new System.Drawing.Point(6, 6);
+            this.listBox1.Name = "listBox1";
+            this.listBox1.Size = new System.Drawing.Size(184, 173);
+            this.listBox1.TabIndex = 0;
+            // 
+            // tabAdvanced
+            // 
+            this.tabAdvanced.Controls.Add(this.btnBrowsePithosPath);
+            this.tabAdvanced.Controls.Add(this.label3);
+            this.tabAdvanced.Controls.Add(this.txtPithosPath);
+            this.tabAdvanced.Location = new System.Drawing.Point(4, 22);
+            this.tabAdvanced.Name = "tabAdvanced";
+            this.tabAdvanced.Padding = new System.Windows.Forms.Padding(3);
+            this.tabAdvanced.Size = new System.Drawing.Size(454, 217);
+            this.tabAdvanced.TabIndex = 2;
+            this.tabAdvanced.Text = "Advanced";
+            this.tabAdvanced.UseVisualStyleBackColor = true;
+            // 
+            // btnBrowsePithosPath
+            // 
+            this.btnBrowsePithosPath.Location = new System.Drawing.Point(296, 28);
+            this.btnBrowsePithosPath.Name = "btnBrowsePithosPath";
+            this.btnBrowsePithosPath.Size = new System.Drawing.Size(75, 23);
+            this.btnBrowsePithosPath.TabIndex = 2;
+            this.btnBrowsePithosPath.Text = "Browse";
+            this.btnBrowsePithosPath.UseVisualStyleBackColor = true;
+            this.btnBrowsePithosPath.Click += new System.EventHandler(this.btnBrowsePithosPath_Click);
+            // 
+            // label3
+            // 
+            this.label3.AutoSize = true;
+            this.label3.Location = new System.Drawing.Point(8, 12);
+            this.label3.Name = "label3";
+            this.label3.Size = new System.Drawing.Size(68, 13);
+            this.label3.TabIndex = 0;
+            this.label3.Text = "Pithos Folder";
+            // 
+            // txtPithosPath
+            // 
+            this.txtPithosPath.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::Pithos.Client.Properties.Settings.Default, "PithosPath", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
+            this.txtPithosPath.Location = new System.Drawing.Point(11, 28);
+            this.txtPithosPath.Name = "txtPithosPath";
+            this.txtPithosPath.Size = new System.Drawing.Size(279, 20);
+            this.txtPithosPath.TabIndex = 1;
+            this.txtPithosPath.Text = global::Pithos.Client.Properties.Settings.Default.PithosPath;
+            // 
+            // notifyIcon
+            // 
+            this.notifyIcon.BalloonTipText = "All Files Up to Date";
+            this.notifyIcon.BalloonTipTitle = "Pithos 1.0";
+            this.notifyIcon.ContextMenuStrip = this.systemMenuStrip;
+            this.notifyIcon.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyIcon.Icon")));
+            this.notifyIcon.Text = "Pithos 1.0";
+            this.notifyIcon.Visible = true;
+            this.notifyIcon.DoubleClick += new System.EventHandler(this.notifyIcon_DoubleClick);
+            // 
+            // systemMenuStrip
+            // 
+            this.systemMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.openPithosFolderToolStripMenuItem,
+            this.launchPithosWebSiteToolStripMenuItem,
+            this.recentlyChangedFilesToolStripMenuItem,
+            this.toolStripSeparator1,
+            this.spaceUserToolStripMenuItem,
+            this.toolStripSeparator2,
+            this.statusToolStripMenuItem,
+            this.toolStripSeparator3,
+            this.pauseSynchingToolStripMenuItem,
+            this.preferencesToolStripMenuItem,
+            this.toolStripSeparator4,
+            this.exitToolStripMenuItem});
+            this.systemMenuStrip.Name = "systemMenuStrip";
+            this.systemMenuStrip.Size = new System.Drawing.Size(187, 204);
+            // 
+            // openPithosFolderToolStripMenuItem
+            // 
+            this.openPithosFolderToolStripMenuItem.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Bold);
+            this.openPithosFolderToolStripMenuItem.Name = "openPithosFolderToolStripMenuItem";
+            this.openPithosFolderToolStripMenuItem.Size = new System.Drawing.Size(186, 22);
+            this.openPithosFolderToolStripMenuItem.Text = "Open Pithos folder";
+            this.openPithosFolderToolStripMenuItem.Click += new System.EventHandler(this.openPithosFolderToolStripMenuItem_Click);
+            // 
+            // launchPithosWebSiteToolStripMenuItem
+            // 
+            this.launchPithosWebSiteToolStripMenuItem.Name = "launchPithosWebSiteToolStripMenuItem";
+            this.launchPithosWebSiteToolStripMenuItem.Size = new System.Drawing.Size(186, 22);
+            this.launchPithosWebSiteToolStripMenuItem.Text = "Launch Pithos Web Site";
+            // 
+            // recentlyChangedFilesToolStripMenuItem
+            // 
+            this.recentlyChangedFilesToolStripMenuItem.Name = "recentlyChangedFilesToolStripMenuItem";
+            this.recentlyChangedFilesToolStripMenuItem.Size = new System.Drawing.Size(186, 22);
+            this.recentlyChangedFilesToolStripMenuItem.Text = "Recently Changed Files";
+            // 
+            // toolStripSeparator1
+            // 
+            this.toolStripSeparator1.Name = "toolStripSeparator1";
+            this.toolStripSeparator1.Size = new System.Drawing.Size(183, 6);
+            // 
+            // spaceUserToolStripMenuItem
+            // 
+            this.spaceUserToolStripMenuItem.Enabled = false;
+            this.spaceUserToolStripMenuItem.Name = "spaceUserToolStripMenuItem";
+            this.spaceUserToolStripMenuItem.Size = new System.Drawing.Size(186, 22);
+            this.spaceUserToolStripMenuItem.Text = "x % of 5 GB used";
+            // 
+            // toolStripSeparator2
+            // 
+            this.toolStripSeparator2.Name = "toolStripSeparator2";
+            this.toolStripSeparator2.Size = new System.Drawing.Size(183, 6);
+            // 
+            // statusToolStripMenuItem
+            // 
+            this.statusToolStripMenuItem.Enabled = false;
+            this.statusToolStripMenuItem.Name = "statusToolStripMenuItem";
+            this.statusToolStripMenuItem.Size = new System.Drawing.Size(186, 22);
+            this.statusToolStripMenuItem.Text = "All Files Up to Date";
+            // 
+            // toolStripSeparator3
+            // 
+            this.toolStripSeparator3.Name = "toolStripSeparator3";
+            this.toolStripSeparator3.Size = new System.Drawing.Size(183, 6);
+            // 
+            // pauseSynchingToolStripMenuItem
+            // 
+            this.pauseSynchingToolStripMenuItem.Name = "pauseSynchingToolStripMenuItem";
+            this.pauseSynchingToolStripMenuItem.Size = new System.Drawing.Size(186, 22);
+            this.pauseSynchingToolStripMenuItem.Text = "Pause Synching";
+            this.pauseSynchingToolStripMenuItem.Click += new System.EventHandler(this.pauseSynchingToolStripMenuItem_Click);
+            // 
+            // preferencesToolStripMenuItem
+            // 
+            this.preferencesToolStripMenuItem.Name = "preferencesToolStripMenuItem";
+            this.preferencesToolStripMenuItem.Size = new System.Drawing.Size(186, 22);
+            this.preferencesToolStripMenuItem.Text = "Preferences";
+            this.preferencesToolStripMenuItem.Click += new System.EventHandler(this.preferencesToolStripMenuItem_Click);
+            // 
+            // toolStripSeparator4
+            // 
+            this.toolStripSeparator4.Name = "toolStripSeparator4";
+            this.toolStripSeparator4.Size = new System.Drawing.Size(183, 6);
+            // 
+            // exitToolStripMenuItem
+            // 
+            this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
+            this.exitToolStripMenuItem.Size = new System.Drawing.Size(186, 22);
+            this.exitToolStripMenuItem.Text = "Exit";
+            this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click);
+            // 
+            // panel1
+            // 
+            this.panel1.Controls.Add(this.btnApply);
+            this.panel1.Controls.Add(this.btnCancel);
+            this.panel1.Controls.Add(this.btnOK);
+            this.panel1.Dock = System.Windows.Forms.DockStyle.Bottom;
+            this.panel1.Location = new System.Drawing.Point(0, 243);
+            this.panel1.Name = "panel1";
+            this.panel1.Size = new System.Drawing.Size(462, 43);
+            this.panel1.TabIndex = 1;
+            // 
+            // btnApply
+            // 
+            this.btnApply.Location = new System.Drawing.Point(371, 8);
+            this.btnApply.Name = "btnApply";
+            this.btnApply.Size = new System.Drawing.Size(75, 23);
+            this.btnApply.TabIndex = 2;
+            this.btnApply.Text = "Apply";
+            this.btnApply.UseVisualStyleBackColor = true;
+            this.btnApply.Click += new System.EventHandler(this.btnApply_Click);
+            // 
+            // btnCancel
+            // 
+            this.btnCancel.Location = new System.Drawing.Point(261, 8);
+            this.btnCancel.Name = "btnCancel";
+            this.btnCancel.Size = new System.Drawing.Size(75, 23);
+            this.btnCancel.TabIndex = 1;
+            this.btnCancel.Text = "Cancel";
+            this.btnCancel.UseVisualStyleBackColor = true;
+            this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
+            // 
+            // btnOK
+            // 
+            this.btnOK.Location = new System.Drawing.Point(169, 8);
+            this.btnOK.Name = "btnOK";
+            this.btnOK.Size = new System.Drawing.Size(75, 23);
+            this.btnOK.TabIndex = 0;
+            this.btnOK.Text = "OK";
+            this.btnOK.UseVisualStyleBackColor = true;
+            this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
+            // 
+            // pithosFolderBrowser
+            // 
+            this.pithosFolderBrowser.Description = "Select a folder to synchronize with Pithos";
+            this.pithosFolderBrowser.RootFolder = System.Environment.SpecialFolder.Personal;
+            // 
+            // Preferences
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.ClientSize = new System.Drawing.Size(462, 286);
+            this.Controls.Add(this.tabControl1);
+            this.Controls.Add(this.panel1);
+            this.MaximizeBox = false;
+            this.MinimizeBox = false;
+            this.Name = "Preferences";
+            this.Text = "Preferences";
+            this.tabControl1.ResumeLayout(false);
+            this.tabAccount.ResumeLayout(false);
+            this.tabAccount.PerformLayout();
+            this.tabAdvanced.ResumeLayout(false);
+            this.tabAdvanced.PerformLayout();
+            this.systemMenuStrip.ResumeLayout(false);
+            this.panel1.ResumeLayout(false);
+            this.ResumeLayout(false);
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.TabControl tabControl1;
+        private System.Windows.Forms.TabPage tabAccount;
+        private System.Windows.Forms.TabPage tabAdvanced;
+        private System.Windows.Forms.NotifyIcon notifyIcon;
+        private System.Windows.Forms.ContextMenuStrip systemMenuStrip;
+        private System.Windows.Forms.ToolStripMenuItem openPithosFolderToolStripMenuItem;
+        private System.Windows.Forms.ToolStripMenuItem launchPithosWebSiteToolStripMenuItem;
+        private System.Windows.Forms.ToolStripMenuItem recentlyChangedFilesToolStripMenuItem;
+        private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
+        private System.Windows.Forms.ToolStripMenuItem spaceUserToolStripMenuItem;
+        private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
+        private System.Windows.Forms.ToolStripMenuItem statusToolStripMenuItem;
+        private System.Windows.Forms.ToolStripSeparator toolStripSeparator3;
+        private System.Windows.Forms.ToolStripMenuItem pauseSynchingToolStripMenuItem;
+        private System.Windows.Forms.ToolStripMenuItem preferencesToolStripMenuItem;
+        private System.Windows.Forms.ToolStripSeparator toolStripSeparator4;
+        private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem;
+        private System.Windows.Forms.Button btnRemoveAccount;
+        private System.Windows.Forms.Button btnAddAccount;
+        private System.Windows.Forms.ListBox listBox1;
+        private System.Windows.Forms.Panel panel1;
+        private System.Windows.Forms.Button btnApply;
+        private System.Windows.Forms.Button btnCancel;
+        private System.Windows.Forms.Button btnOK;
+        private System.Windows.Forms.Button btnAccountVerify;
+        private System.Windows.Forms.TextBox txtApiKey;
+        private System.Windows.Forms.Label label2;
+        private System.Windows.Forms.TextBox textBox1;
+        private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.Button btnBrowsePithosPath;
+        private System.Windows.Forms.TextBox txtPithosPath;
+        private System.Windows.Forms.Label label3;
+        private System.Windows.Forms.FolderBrowserDialog pithosFolderBrowser;
+    }
+}
\ No newline at end of file
diff --git a/trunk/Pithos.Client/Preferences.cs b/trunk/Pithos.Client/Preferences.cs
new file mode 100644 (file)
index 0000000..be6ce55
--- /dev/null
@@ -0,0 +1,161 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.ComponentModel.Composition;
+using System.Data;
+using System.Diagnostics;
+using System.Drawing;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Windows.Forms;
+using Pithos.Client.Properties;
+using Pithos.Core;
+using Pithos.Interfaces;
+
+namespace Pithos.Client
+{
+    public partial class Preferences : Form
+    {
+        [Import]
+        public IStatusChecker StatusChecker;
+
+        [Import] 
+        public IPithosSettings Settings;
+
+
+        bool _allowVisible;     // ContextMenu's Show command used
+        bool _allowClose;       // ContextMenu's Exit command used
+        bool _loadFired;        // Form was shown once
+
+
+        [Import]
+        public PithosMonitor Monitor;
+
+        public Preferences()
+        {
+            InitializeComponent();            
+        }
+
+        protected override void SetVisibleCore(bool value)
+        {
+            if (!_allowVisible) 
+                value = false;
+            base.SetVisibleCore(value);
+        }
+
+        protected override void OnFormClosing(FormClosingEventArgs e)
+        {
+            if (!_allowClose)
+            {
+                this.Hide();
+                e.Cancel = true;
+            }
+            base.OnFormClosing(e);
+        }
+        private void openPithosFolderToolStripMenuItem_Click(object sender, EventArgs e)
+        {
+            OpenPithosPath();
+        }
+
+        private void notifyIcon_DoubleClick(object sender, EventArgs e)
+        {
+            OpenPithosPath();
+        }
+
+        private void OpenPithosPath()
+        {
+            Process.Start(Settings.PithosPath);
+        }
+
+
+        private Dictionary<PithosStatus, StatusInfo> iconNames =new List<StatusInfo>
+            {
+                new StatusInfo(PithosStatus.InSynch, "All files up to date", "TrayInSynch"),
+                new StatusInfo(PithosStatus.Synching, "Synching Files", "TraySynching")
+            }.ToDictionary(s => s.Status);
+
+        public void UpdateStatus()
+        {
+            var pithosStatus=StatusChecker.GetPithosStatus();
+
+            if (iconNames.ContainsKey(pithosStatus))
+            {
+                var info= iconNames[pithosStatus];
+
+
+                notifyIcon.Icon = (Icon) Resources.ResourceManager.GetObject(info.IconName);
+                notifyIcon.Text = String.Format("Pithos 1.0\r\n{0}", info.StatusText);
+                notifyIcon.BalloonTipText = info.StatusText;
+                statusToolStripMenuItem.Text = info.StatusText;
+            }
+            if (!String.IsNullOrWhiteSpace(Settings.UserName )&&
+                !String.IsNullOrWhiteSpace(Settings.ApiKey))
+                Monitor.Start();
+            
+        }
+
+        private void btnBrowsePithosPath_Click(object sender, EventArgs e)
+        {
+            pithosFolderBrowser.SelectedPath = txtPithosPath.Text;
+            var result = pithosFolderBrowser.ShowDialog();
+            if (result == DialogResult.OK)
+            {
+                var newPath = pithosFolderBrowser.SelectedPath;
+                txtPithosPath.Text = newPath;
+                Settings.PithosPath = newPath;
+                Settings.Save();
+            }
+        }
+
+        private void preferencesToolStripMenuItem_Click(object sender, EventArgs e)
+        {
+            _allowVisible = true;
+            _loadFired = true;
+            Show();
+        }
+
+        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
+        {
+            _allowClose = _allowVisible = true;
+            Monitor.Stop();
+            if (!_loadFired) 
+                Show();
+            Close();
+        }
+
+        private void btnCancel_Click(object sender, EventArgs e)
+        {
+            Settings.Reload();
+            Hide();
+        }
+
+        private void btnOK_Click(object sender, EventArgs e)
+        {
+            DoSave();
+            Hide();
+        }
+
+        private void btnApply_Click(object sender, EventArgs e)
+        {
+            DoSave();
+        }
+
+        private void DoSave()
+        {
+            Settings.Save();
+            Monitor.Start();
+        }
+
+        private void pauseSynchingToolStripMenuItem_Click(object sender, EventArgs e)
+        {
+            Monitor.Pause = !Monitor.Pause;
+            pauseSynchingToolStripMenuItem.Text = Monitor.Pause?"Resume Synching":"Pause Synching";
+        }
+
+        private void tabAccount_Click(object sender, EventArgs e)
+        {
+
+        }
+    }
+}
diff --git a/trunk/Pithos.Client/Preferences.resx b/trunk/Pithos.Client/Preferences.resx
new file mode 100644 (file)
index 0000000..47455af
--- /dev/null
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <metadata name="notifyIcon.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+  <metadata name="systemMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>119, 13</value>
+  </metadata>
+  <assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+  <data name="notifyIcon.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        AAABAAIAEBAQAAAABAAoAQAAJgAAACAgEAAAAAQA6AIAAE4BAAAoAAAAEAAAACAAAAABAAQAAAAAAIAA
+        AAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAICAgADAwMAAAAD/AAD/
+        AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAAAMzMzAAAAAAAAAAAAAAAAMzMzMzMAAAAAAAAAA
+        AAAAzMzMzMzMAAzMzMzMzMzAAAzMzMzMwAAMzMzMzMzMAAAADMzMwAAAAATMzMzMwAAAAAAAAAAAAAAA
+        DMzMwAAAAAAAzMzAAAAAAAAAAAAAAAAMzMzMzMAA//8AAPgfAAD//wAA4AcAAP//AADAAwAAgAEAAOAH
+        AACAAwAA+B8AAOAHAAD//wAA+B8AAPwfAAD//wAA4AcAACgAAAAgAAAAQAAAAAEABAAAAAAAAAIAAAAA
+        AAAAAAAAEAAAABAAAAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAgICAAMDAwAAAAP8AAP8AAAD/
+        /wD/AAAA/wD/AP//AAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzMzMzAAAAAAAAAAAAAAAzMzMzM
+        zAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzMzMzMzMAAAAAAAAAAAMzM
+        zMzMzMzMwAAAAAAAAAzMzMzMzMzMzMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzMzMzMzMzMAAAAAAAA
+        DMzMzMzMzMzMzMzAAAAADMTMzMzMzMzMzMzMzMAAAAzMzMzMzMzMzMzMzMwAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAzMzMzMzMzMzAAAAAAAAMzMzMzMzMzMzMzMAAAAAAzMzMzMzMzMzMzMzAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAMzMzMzMwAAAAAAAAAAADMzMzMzMzMzMAAAAAAAAAMTMzMzMzMzMzAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzMzMzMzAAAAAAAAAAAAADMzMzMzMAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAADMzMzMwAAAAAAAAAAAAAAMzMzMzMwAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAADMzMzMzMzMwAAAAAAAAAAMzMzMzMzMzMAAAAAAAAAAAAAAAAAAAAAAAAAAD///////AH///g
+        A//////////////AAf//AAB//gAAP///////gAD/+AAAH+AAAAfgAAAP//////8AAH/4AAAf8AAAH///
+        ////4AP//wAAf/4AAH/////////////AA///wAf////////wB///4AP///////+AAP//AAD//////w==
+</value>
+  </data>
+  <metadata name="pithosFolderBrowser.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>256, 13</value>
+  </metadata>
+</root>
\ No newline at end of file
diff --git a/trunk/Pithos.Client/Program.cs b/trunk/Pithos.Client/Program.cs
new file mode 100644 (file)
index 0000000..453e014
--- /dev/null
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+
+namespace Pithos.Client
+{
+    static class Program
+    {
+        /// <summary>
+        /// The main entry point for the application.
+        /// </summary>
+        [STAThread]
+        static void Main()
+        {
+            Application.EnableVisualStyles();
+            Application.SetCompatibleTextRenderingDefault(false);
+            var mainForm = new Preferences();
+
+            IoC.Current.Compose(mainForm);
+            mainForm.UpdateStatus();
+            Application.Run(mainForm);
+        }
+    }
+}
diff --git a/trunk/Pithos.Client/Properties/AssemblyInfo.cs b/trunk/Pithos.Client/Properties/AssemblyInfo.cs
new file mode 100644 (file)
index 0000000..df77cb9
--- /dev/null
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Pithos.Client")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("Pithos.Client")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("087876a7-cbbd-4fa9-8930-93cef5841e6c")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/trunk/Pithos.Client/Properties/Resources.Designer.cs b/trunk/Pithos.Client/Properties/Resources.Designer.cs
new file mode 100644 (file)
index 0000000..2aae16b
--- /dev/null
@@ -0,0 +1,84 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.225
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Pithos.Client.Properties {
+    using System;
+    
+    
+    /// <summary>
+    ///   A strongly-typed resource class, for looking up localized strings, etc.
+    /// </summary>
+    // This class was auto-generated by the StronglyTypedResourceBuilder
+    // class via a tool like ResGen or Visual Studio.
+    // To add or remove a member, edit your .ResX file then rerun ResGen
+    // with the /str option, or rebuild your VS project.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources() {
+        }
+        
+        /// <summary>
+        ///   Returns the cached ResourceManager instance used by this class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Pithos.Client.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   Overrides the current thread's CurrentUICulture property for all
+        ///   resource lookups using this strongly typed resource class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+        
+        internal static System.Drawing.Icon Tray {
+            get {
+                object obj = ResourceManager.GetObject("Tray", resourceCulture);
+                return ((System.Drawing.Icon)(obj));
+            }
+        }
+        
+        internal static System.Drawing.Icon TrayInSynch {
+            get {
+                object obj = ResourceManager.GetObject("TrayInSynch", resourceCulture);
+                return ((System.Drawing.Icon)(obj));
+            }
+        }
+        
+        internal static System.Drawing.Icon TraySynching {
+            get {
+                object obj = ResourceManager.GetObject("TraySynching", resourceCulture);
+                return ((System.Drawing.Icon)(obj));
+            }
+        }
+    }
+}
diff --git a/trunk/Pithos.Client/Properties/Resources.resx b/trunk/Pithos.Client/Properties/Resources.resx
new file mode 100644 (file)
index 0000000..a397191
--- /dev/null
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+  <data name="Tray" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>..\Resources\Tray.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  </data>
+  <data name="TrayInSynch" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>..\Resources\TrayInSynch.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  </data>
+  <data name="TraySynching" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>..\Resources\TraySynching.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  </data>
+</root>
\ No newline at end of file
diff --git a/trunk/Pithos.Client/Properties/Settings.Designer.cs b/trunk/Pithos.Client/Properties/Settings.Designer.cs
new file mode 100644 (file)
index 0000000..0ee2936
--- /dev/null
@@ -0,0 +1,158 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.225
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Pithos.Client.Properties {
+    
+    
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
+    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+        
+        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+        
+        public static Settings Default {
+            get {
+                return defaultInstance;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("e:\\Pithos")]
+        public string PithosPath {
+            get {
+                return ((string)(this["PithosPath"]));
+            }
+            set {
+                this["PithosPath"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("C:\\Program Files\\Common Files\\TortoiseOverlays\\icons\\XPStyle")]
+        public string IconPath {
+            get {
+                return ((string)(this["IconPath"]));
+            }
+            set {
+                this["IconPath"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("")]
+        public string ProxyServer {
+            get {
+                return ((string)(this["ProxyServer"]));
+            }
+            set {
+                this["ProxyServer"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("")]
+        public string ProxyPort {
+            get {
+                return ((string)(this["ProxyPort"]));
+            }
+            set {
+                this["ProxyPort"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("")]
+        public string ProxyType {
+            get {
+                return ((string)(this["ProxyType"]));
+            }
+            set {
+                this["ProxyType"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("")]
+        public string ProxyUsername {
+            get {
+                return ((string)(this["ProxyUsername"]));
+            }
+            set {
+                this["ProxyUsername"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("")]
+        public string ProxyPassword {
+            get {
+                return ((string)(this["ProxyPassword"]));
+            }
+            set {
+                this["ProxyPassword"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("False")]
+        public bool ProxyAuthentication {
+            get {
+                return ((bool)(this["ProxyAuthentication"]));
+            }
+            set {
+                this["ProxyAuthentication"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("")]
+        public string Setting {
+            get {
+                return ((string)(this["Setting"]));
+            }
+            set {
+                this["Setting"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("")]
+        public string UserName {
+            get {
+                return ((string)(this["UserName"]));
+            }
+            set {
+                this["UserName"] = value;
+            }
+        }
+        
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("")]
+        public string ApiKey {
+            get {
+                return ((string)(this["ApiKey"]));
+            }
+            set {
+                this["ApiKey"] = value;
+            }
+        }
+    }
+}
diff --git a/trunk/Pithos.Client/Properties/Settings.settings b/trunk/Pithos.Client/Properties/Settings.settings
new file mode 100644 (file)
index 0000000..9962330
--- /dev/null
@@ -0,0 +1,39 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="Pithos.Client.Properties" GeneratedClassName="Settings">
+  <Profiles />
+  <Settings>
+    <Setting Name="PithosPath" Type="System.String" Scope="User">
+      <Value Profile="(Default)">e:\Pithos</Value>
+    </Setting>
+    <Setting Name="IconPath" Type="System.String" Scope="User">
+      <Value Profile="(Default)">C:\Program Files\Common Files\TortoiseOverlays\icons\XPStyle</Value>
+    </Setting>
+    <Setting Name="ProxyServer" Type="System.String" Scope="User">
+      <Value Profile="(Default)" />
+    </Setting>
+    <Setting Name="ProxyPort" Type="System.String" Scope="User">
+      <Value Profile="(Default)" />
+    </Setting>
+    <Setting Name="ProxyType" Type="System.String" Scope="User">
+      <Value Profile="(Default)" />
+    </Setting>
+    <Setting Name="ProxyUsername" Type="System.String" Scope="User">
+      <Value Profile="(Default)" />
+    </Setting>
+    <Setting Name="ProxyPassword" Type="System.String" Scope="User">
+      <Value Profile="(Default)" />
+    </Setting>
+    <Setting Name="ProxyAuthentication" Type="System.Boolean" Scope="User">
+      <Value Profile="(Default)">False</Value>
+    </Setting>
+    <Setting Name="Setting" Type="System.String" Scope="User">
+      <Value Profile="(Default)" />
+    </Setting>
+    <Setting Name="UserName" Type="System.String" Scope="User">
+      <Value Profile="(Default)" />
+    </Setting>
+    <Setting Name="ApiKey" Type="System.String" Scope="User">
+      <Value Profile="(Default)" />
+    </Setting>
+  </Settings>
+</SettingsFile>
\ No newline at end of file
diff --git a/trunk/Pithos.Client/Resources/Tray.ico b/trunk/Pithos.Client/Resources/Tray.ico
new file mode 100644 (file)
index 0000000..19ab02c
Binary files /dev/null and b/trunk/Pithos.Client/Resources/Tray.ico differ
diff --git a/trunk/Pithos.Client/Resources/TrayInSynch.ico b/trunk/Pithos.Client/Resources/TrayInSynch.ico
new file mode 100644 (file)
index 0000000..5bf2b2d
Binary files /dev/null and b/trunk/Pithos.Client/Resources/TrayInSynch.ico differ
diff --git a/trunk/Pithos.Client/Resources/TraySynching.ico b/trunk/Pithos.Client/Resources/TraySynching.ico
new file mode 100644 (file)
index 0000000..d246fbd
Binary files /dev/null and b/trunk/Pithos.Client/Resources/TraySynching.ico differ
diff --git a/trunk/Pithos.Client/app.config b/trunk/Pithos.Client/app.config
new file mode 100644 (file)
index 0000000..c8fcef3
--- /dev/null
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<configuration>
+    <configSections>
+        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+            <section name="Pithos.Client.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
+        </sectionGroup>
+    </configSections>
+    <userSettings>
+        <Pithos.Client.Properties.Settings>
+            <setting name="PithosPath" serializeAs="String">
+                <value>e:\Pithos</value>
+            </setting>
+            <setting name="IconPath" serializeAs="String">
+                <value>C:\Program Files\Common Files\TortoiseOverlays\icons\XPStyle</value>
+            </setting>
+            <setting name="ProxyServer" serializeAs="String">
+                <value/>
+            </setting>
+            <setting name="ProxyPort" serializeAs="String">
+                <value/>
+            </setting>
+            <setting name="ProxyType" serializeAs="String">
+                <value/>
+            </setting>
+            <setting name="ProxyUsername" serializeAs="String">
+                <value/>
+            </setting>
+            <setting name="ProxyPassword" serializeAs="String">
+                <value/>
+            </setting>
+            <setting name="ProxyAuthentication" serializeAs="String">
+                <value>False</value>
+            </setting>
+            <setting name="Setting" serializeAs="String">
+                <value/>
+            </setting>
+            <setting name="UserName" serializeAs="String">
+                <value/>
+            </setting>
+            <setting name="ApiKey" serializeAs="String">
+                <value/>
+            </setting>
+        </Pithos.Client.Properties.Settings>
+    </userSettings>
+<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
diff --git a/trunk/Pithos.Client/header.jpg b/trunk/Pithos.Client/header.jpg
new file mode 100644 (file)
index 0000000..f5a4936
Binary files /dev/null and b/trunk/Pithos.Client/header.jpg differ
diff --git a/trunk/Pithos.Client/packages.config b/trunk/Pithos.Client/packages.config
new file mode 100644 (file)
index 0000000..edf7d1d
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="Massive" version="1.0" />
+</packages>
\ No newline at end of file
diff --git a/trunk/Pithos.Core.Test/MockSettings.cs b/trunk/Pithos.Core.Test/MockSettings.cs
new file mode 100644 (file)
index 0000000..5584a9a
--- /dev/null
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Pithos.Interfaces;
+
+namespace Pithos.Core.Test
+{
+    class MockSettings:IPithosSettings
+    {
+        public string PithosPath { get; set; }
+
+        public string IconsPath { get; set; }
+        public string UserName { get; set; }
+        public string ApiKey { get; set; }
+
+        public void Save()
+        {
+            
+        }
+
+        public void Reload()
+        {
+            
+        }
+    }
+}
diff --git a/trunk/Pithos.Core.Test/MockStatusKeeper.cs b/trunk/Pithos.Core.Test/MockStatusKeeper.cs
new file mode 100644 (file)
index 0000000..577b7fc
--- /dev/null
@@ -0,0 +1,79 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.Contracts;
+using System.Linq;
+using System.Text;
+using Pithos.Interfaces;
+
+namespace Pithos.Core.Test
+{
+    public class MockStatusChecker : IStatusChecker, IStatusKeeper
+    {
+        public IPithosSettings Settings { get; set; }
+
+        private readonly string[] _states = { "Normal", "Modified", "Conflict", "Synch" };
+
+        Dictionary<string, FileOverlayStatus> _overlayCache = new Dictionary<string, FileOverlayStatus>();
+        Dictionary<string, FileStatus> _statusCache = new Dictionary<string, FileStatus>();
+        Dictionary<string, string> _checksums = new Dictionary<string, string>();
+
+        public FileOverlayStatus GetFileOverlayStatus(string path)
+        {
+            Contract.Requires(!String.IsNullOrWhiteSpace(path));
+            if (!_overlayCache.ContainsKey(path))
+                return FileOverlayStatus.NA;
+
+            var pithosPath = Settings.PithosPath;
+            if (path.StartsWith(pithosPath, true, null))
+            {
+                var status = _overlayCache[path];
+                return status;
+            }
+            return FileOverlayStatus.NA;
+        }
+
+        public PithosStatus GetPithosStatus()
+        {
+            return PithosStatus.InSynch;
+        }
+
+        public void SetFileOverlayStatus(string path, FileOverlayStatus overlayStatus)
+        {
+            _overlayCache[path] = overlayStatus;
+        }
+
+        public void RemoveFileOverlayStatus(string path)
+        {
+            _overlayCache.Remove(path);
+        }
+
+        public void RenameFileOverlayStatus(string oldPath, string newPath)
+        {
+            var status = _overlayCache[oldPath];
+            _overlayCache[newPath] = status;
+            _overlayCache.Remove(oldPath);
+        }
+
+        public void UpdateFileChecksum(string path, string checksum)
+        {
+            _checksums[path] = checksum;
+        }
+
+        public void SetFileStatus(string path, FileStatus status)
+        {
+            _statusCache[path] = status;
+        }
+
+        public FileStatus GetFileStatus(string path)
+        {
+            if (!_statusCache.ContainsKey(path))
+                return FileStatus.Missing;
+            return _statusCache[path];
+        }
+
+        public void ClearFileStatus(string path)
+        {
+            _statusCache.Remove(path);
+        }
+    }
+}
diff --git a/trunk/Pithos.Core.Test/Pithos.Core.Test.csproj b/trunk/Pithos.Core.Test/Pithos.Core.Test.csproj
new file mode 100644 (file)
index 0000000..7c63eac
--- /dev/null
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{F9AF3E97-BCB7-46B7-8014-7FC858AEE9BA}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Pithos.Core.Test</RootNamespace>
+    <AssemblyName>Pithos.Core.Test</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <CodeContractsAssemblyMode>0</CodeContractsAssemblyMode>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
+    <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
+    <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
+    <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
+    <CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers>
+    <CodeContractsRunCodeAnalysis>False</CodeContractsRunCodeAnalysis>
+    <CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
+    <CodeContractsBoundsObligations>False</CodeContractsBoundsObligations>
+    <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
+    <CodeContractsEnumObligations>False</CodeContractsEnumObligations>
+    <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
+    <CodeContractsRunInBackground>True</CodeContractsRunInBackground>
+    <CodeContractsShowSquigglies>False</CodeContractsShowSquigglies>
+    <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
+    <CodeContractsEmitXMLDocs>False</CodeContractsEmitXMLDocs>
+    <CodeContractsCustomRewriterAssembly />
+    <CodeContractsCustomRewriterClass />
+    <CodeContractsLibPaths />
+    <CodeContractsExtraRewriteOptions />
+    <CodeContractsExtraAnalysisOptions />
+    <CodeContractsBaseLineFile />
+    <CodeContractsCacheAnalysisResults>False</CodeContractsCacheAnalysisResults>
+    <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
+    <CodeContractsReferenceAssembly>%28none%29</CodeContractsReferenceAssembly>
+    <CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="nunit.framework, Version=2.5.10.11092, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL" />
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="PithosWorkflowTest.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="StatusCheckerTest.cs" />
+    <Compile Include="MockSettings.cs" />
+    <Compile Include="MockStatusKeeper.cs" />
+    <Compile Include="WorkflowFileStatusTest.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\Pithos.Core\Pithos.Core.csproj">
+      <Project>{142AF135-DF30-4563-B0AC-B604235AE874}</Project>
+      <Name>Pithos.Core</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\Pithos.Interfaces\Pithos.Interfaces.csproj">
+      <Project>{7EEFF32F-CCF8-436A-9E0B-F40434C09AF4}</Project>
+      <Name>Pithos.Interfaces</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
diff --git a/trunk/Pithos.Core.Test/PithosWorkflowTest.cs b/trunk/Pithos.Core.Test/PithosWorkflowTest.cs
new file mode 100644 (file)
index 0000000..7714054
--- /dev/null
@@ -0,0 +1,48 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using Pithos.Interfaces;
+
+namespace Pithos.Core.Test
+{
+    [TestFixture]
+    public class PithosWorkflowTest
+    {
+        private MockSettings _settings;
+        private MockStatusChecker _statusChecker;
+
+        [SetUp]
+        public void SetUp()
+        {
+            _settings = new MockSettings
+                            {
+                                PithosPath = @"e:\Pithos",
+                                IconsPath = @"C:\Program Files\Common Files\TortoiseOverlays\icons\XPStyle"
+                            };
+            _statusChecker = new MockStatusChecker {Settings = _settings};
+        }
+
+        [Test]
+        public void TestSendNotificationForFile()
+        {
+            IPithosWorkflow workflow = new PithosWorkflow {Settings = _settings, StatusKeeper = _statusChecker};
+            var path = @"e:\pithos\0File.txt";
+
+            Assert.DoesNotThrow(() =>
+                                    {
+                                        workflow.RaiseChangeNotification(path);
+                                    });
+            path = @"e:\pithos\01New folder";
+            Assert.DoesNotThrow(() =>
+                                    {
+                                        workflow.RaiseChangeNotification(path);
+                                    });
+
+        }
+
+
+    }
+}
diff --git a/trunk/Pithos.Core.Test/Properties/AssemblyInfo.cs b/trunk/Pithos.Core.Test/Properties/AssemblyInfo.cs
new file mode 100644 (file)
index 0000000..d08db46
--- /dev/null
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Pithos.Core.Test")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("Pithos.Core.Test")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("6b7b9383-b929-45ab-a633-eea0fc85bccb")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/trunk/Pithos.Core.Test/StatusCheckerTest.cs b/trunk/Pithos.Core.Test/StatusCheckerTest.cs
new file mode 100644 (file)
index 0000000..adbdcd8
--- /dev/null
@@ -0,0 +1,85 @@
+using System;
+using NUnit.Framework;
+using Pithos.Interfaces;
+
+namespace Pithos.Core.Test
+{
+    [TestFixture]
+    public class StatusCheckerTest
+    {
+        [Test]
+        public void TestFileCheck()
+        {
+
+            var files = new[] {Tuple.Create(@"e:\pithos\0File1.txt", FileOverlayStatus.Normal),
+                                     Tuple.Create(@"e:\pithos\0File2.txt", FileOverlayStatus.Conflict),
+                                     Tuple.Create(@"e:\pithos\0File3.txt", FileOverlayStatus.Modified),
+                                     Tuple.Create(@"e:\pithos\0File4.txt", FileOverlayStatus.Synch)
+                                    };
+
+            var checker = new StatusChecker();
+
+            foreach (var file in files)
+            {
+                checker.SetFileOverlayStatus(file.Item1,file.Item2);
+            }
+
+            foreach (var file in files)
+            {
+
+                var status = checker.GetFileOverlayStatus(file.Item1);                
+                Assert.AreEqual(file.Item2,status);
+            }
+        }
+        
+        [Test]
+        public void TestFileRemoval()
+        {
+
+            var files = new[] {Tuple.Create(@"e:\pithos\0File1.txt", FileOverlayStatus.Normal),
+                                     Tuple.Create(@"e:\pithos\0File2.txt", FileOverlayStatus.Conflict),
+                                     Tuple.Create(@"e:\pithos\0File3.txt", FileOverlayStatus.Modified),
+                                     Tuple.Create(@"e:\pithos\0File4.txt", FileOverlayStatus.Synch)
+                                    };
+
+            var checker = new StatusChecker();
+
+            foreach (var file in files)
+            {
+                checker.SetFileOverlayStatus(file.Item1,file.Item2);
+            }
+
+            checker.RemoveFileOverlayStatus(@"e:\pithos\0File3.txt");
+            var status = checker.GetFileOverlayStatus(@"e:\pithos\0File3.txt");                
+            Assert.AreEqual(FileOverlayStatus.NA,status);
+            
+        }
+
+
+
+        [Test]
+        public void TestNonExistent()
+        {
+            var files = new[]
+                            {
+                                Tuple.Create(@"e:\pithos\0File1.txt", FileOverlayStatus.Normal),
+                                Tuple.Create(@"e:\pithos\0File2.txt", FileOverlayStatus.Conflict),
+                                Tuple.Create(@"e:\pithos\0File3.txt", FileOverlayStatus.Modified),
+                                Tuple.Create(@"e:\pithos\0File4.txt", FileOverlayStatus.Synch)
+                            };
+
+            var checker = new StatusChecker();
+
+            foreach (var file in files)
+            {
+                checker.SetFileOverlayStatus(file.Item1, file.Item2);
+            }
+
+            
+                var status = checker.GetFileOverlayStatus(@"e:\pithos\notexisting");
+            Assert.AreEqual(FileOverlayStatus.NA,status);
+
+
+        }
+    }
+}
diff --git a/trunk/Pithos.Core.Test/WorkflowFileStatusTest.cs b/trunk/Pithos.Core.Test/WorkflowFileStatusTest.cs
new file mode 100644 (file)
index 0000000..2764aae
--- /dev/null
@@ -0,0 +1,156 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+
+
+namespace Pithos.Core.Test
+{
+    [TestFixture]
+    public class WorkflowFileStatusTest
+    {
+        private MockSettings _settings;
+        private MockStatusChecker _statusChecker;
+
+        [SetUp]
+        public void SetUp()
+        {
+            _settings = new MockSettings
+            {
+                PithosPath = @"e:\Pithos",
+                IconsPath = @"C:\Program Files\Common Files\TortoiseOverlays\icons\XPStyle"
+            };
+            _statusChecker = new MockStatusChecker { Settings = _settings };
+        }
+
+        [Test]
+        public void TestSetFileStatusCreated()
+        {
+            PithosWorkflow workflow = new PithosWorkflow { Settings = _settings, StatusKeeper = _statusChecker };
+
+            var path = @"e:\pithos\0File1.txt";
+            workflow.SetFileStatus(path, FileStatus.Created);
+            var status = _statusChecker.GetFileStatus(path);
+            Assert.AreEqual(FileStatus.Created, status);
+
+        }
+
+        [Test]
+        public void TestSetFileStatusCreatedTransitions()
+        {
+            IPithosWorkflow workflow = new PithosWorkflow { Settings = _settings, StatusKeeper = _statusChecker };
+
+            var path = @"e:\pithos\0File1.txt";
+
+            var initialStatus = FileStatus.Created;
+            FileStatus[,] transitions = { { FileStatus.Modified, FileStatus.Created },
+                                            { FileStatus.Created, FileStatus.Created },
+                                            { FileStatus.Deleted, FileStatus.Deleted },
+                                            { FileStatus.Renamed, FileStatus.Renamed },
+                                            { FileStatus.Unchanged, FileStatus.Unchanged },
+                                        };
+
+
+            TestTransitions(transitions, workflow, path, initialStatus);
+        }
+
+        [Test]
+        public void TestSetFileStatusModifiedTransitions()
+        {
+            IPithosWorkflow workflow = new PithosWorkflow { Settings = _settings, StatusKeeper = _statusChecker };
+
+            var path = @"e:\pithos\0File1.txt";
+
+            var initialStatus = FileStatus.Modified;
+            FileStatus[,] transitions = { { FileStatus.Modified, FileStatus.Modified },
+                                            { FileStatus.Created, FileStatus.Modified },
+                                            { FileStatus.Deleted, FileStatus.Deleted },
+                                            { FileStatus.Renamed, FileStatus.Renamed },
+                                            { FileStatus.Unchanged, FileStatus.Unchanged },
+                                        };
+
+
+            TestTransitions(transitions, workflow, path, initialStatus);
+        }
+
+        [Test]
+        public void TestSetFileStatusUnchangedTransitions()
+        {
+            IPithosWorkflow workflow = new PithosWorkflow { Settings = _settings, StatusKeeper = _statusChecker };
+
+            var path = @"e:\pithos\0File1.txt";
+
+            var initialStatus = FileStatus.Unchanged;
+            FileStatus[,] transitions = { { FileStatus.Modified, FileStatus.Modified },
+                                            { FileStatus.Created, FileStatus.Created },
+                                            { FileStatus.Deleted, FileStatus.Deleted },
+                                            { FileStatus.Renamed, FileStatus.Renamed },
+                                            { FileStatus.Unchanged, FileStatus.Unchanged },
+                                        };
+
+
+            TestTransitions(transitions, workflow, path, initialStatus);
+        }
+
+        [Test]
+        public void TestSetFileStatusDeletedTransitions()
+        {
+            IPithosWorkflow workflow = new PithosWorkflow { Settings = _settings, StatusKeeper = _statusChecker };
+
+            var path = @"e:\pithos\0File1.txt";
+
+            var initialStatus = FileStatus.Deleted;
+            FileStatus[,] transitions = { { FileStatus.Modified, FileStatus.Deleted },
+                                            { FileStatus.Created, FileStatus.Deleted },
+                                            { FileStatus.Deleted, FileStatus.Deleted },
+                                            { FileStatus.Renamed, FileStatus.Deleted },
+                                            { FileStatus.Unchanged, FileStatus.Deleted },
+                                        };
+
+
+            TestTransitions(transitions, workflow, path, initialStatus);
+        }
+
+        [Test]
+        public void TestSetFileStatusRenamedTransitions()
+        {
+            IPithosWorkflow workflow = new PithosWorkflow { Settings = _settings, StatusKeeper = _statusChecker };
+
+            var path = @"e:\pithos\0File1.txt";
+
+            var initialStatus = FileStatus.Renamed;
+            FileStatus[,] transitions = { { FileStatus.Modified, FileStatus.Modified },
+                                            { FileStatus.Created, FileStatus.Renamed },
+                                            { FileStatus.Deleted, FileStatus.Deleted },
+                                            { FileStatus.Renamed, FileStatus.Renamed },
+                                            { FileStatus.Unchanged, FileStatus.Unchanged },
+                                        };
+
+
+            TestTransitions(transitions, workflow, path, initialStatus);
+        }
+
+        private void TestTransitions(FileStatus[,] transitions, IPithosWorkflow workflow, string path, FileStatus initialStatus)
+        {
+            workflow.SetFileStatus(path, initialStatus);
+            var status = _statusChecker.GetFileStatus(path);
+            Assert.AreEqual(initialStatus, status, "Setting new file to {0}", status);
+            for (int i = 0; i < transitions.GetLength(0); i++)
+            {
+                workflow.ClearFileStatus(path);
+                status = _statusChecker.GetFileStatus(path);
+                Assert.AreEqual(FileStatus.Missing, status, "Clear status");
+
+                workflow.SetFileStatus(path, initialStatus);
+
+                var transition = transitions[i, 0];
+                var result = transitions[i, 1];
+                workflow.SetFileStatus(path, transition);
+                status = _statusChecker.GetFileStatus(path);
+                Assert.AreEqual(result, status, "Marking {0} as {1}", initialStatus, transition);
+
+            }
+        }
+    }
+}
diff --git a/trunk/Pithos.Core/IPithosWorkflow.cs b/trunk/Pithos.Core/IPithosWorkflow.cs
new file mode 100644 (file)
index 0000000..87bc50e
--- /dev/null
@@ -0,0 +1,25 @@
+using Pithos.Interfaces;
+
+namespace Pithos.Core
+{
+    public interface IPithosWorkflow
+    {
+        IPithosSettings Settings { get; set; }
+        IStatusKeeper StatusKeeper { get; set; }
+        FileStatus SetFileStatus(string path,FileStatus status);
+        void ClearFileStatus(string path);
+        void RaiseChangeNotification(string path);
+
+
+    }
+
+    public enum FileStatus
+    {
+        Missing,
+        Unchanged,
+        Created,
+        Modified,
+        Renamed,
+        Deleted
+    }
+}
\ No newline at end of file
diff --git a/trunk/Pithos.Core/IStatusKeeper.cs b/trunk/Pithos.Core/IStatusKeeper.cs
new file mode 100644 (file)
index 0000000..16145b6
--- /dev/null
@@ -0,0 +1,61 @@
+using System;
+using System.Diagnostics.Contracts;
+using Pithos.Interfaces;
+
+namespace Pithos.Core
+{
+    [ContractClass(typeof(IStatusKeeperContract))]
+    public interface IStatusKeeper
+    {
+        void SetFileOverlayStatus(string path,FileOverlayStatus status);
+        void UpdateFileChecksum(string path, string checksum);
+        void RemoveFileOverlayStatus(string path);
+        void SetFileStatus(string path, FileStatus status);
+        FileStatus GetFileStatus(string path);
+        void ClearFileStatus(string path);
+    }
+
+    [ContractClassFor(typeof(IStatusKeeper))]
+    public abstract class IStatusKeeperContract : IStatusKeeper
+    {
+        public void SetFileOverlayStatus(string path, FileOverlayStatus status)
+        {
+            Contract.Requires(!String.IsNullOrWhiteSpace(path));
+        }
+
+        public void UpdateFileChecksum(string path, string checksum)
+        {
+            Contract.Requires(!String.IsNullOrWhiteSpace(path));
+            Contract.Requires(checksum!=null);
+        }
+
+        public void RemoveFileOverlayStatus(string path)
+        {
+            Contract.Requires(!String.IsNullOrWhiteSpace(path));
+        }
+
+        public void RenameFileOverlayStatus(string oldPath, string newPath)
+        {
+            Contract.Requires(!String.IsNullOrWhiteSpace(oldPath));
+            Contract.Requires(!String.IsNullOrWhiteSpace(newPath));
+
+        }
+
+        public void SetFileStatus(string path, FileStatus status)
+        {
+            Contract.Requires(!String.IsNullOrWhiteSpace(path));
+        }
+
+        public FileStatus GetFileStatus(string path)
+        {
+            Contract.Requires(!String.IsNullOrWhiteSpace(path));
+
+            return default(FileStatus);
+        }
+
+        public void ClearFileStatus(string path)
+        {
+            Contract.Requires(!String.IsNullOrWhiteSpace(path));
+        }
+    }
+}
diff --git a/trunk/Pithos.Core/NativeMethods.cs b/trunk/Pithos.Core/NativeMethods.cs
new file mode 100644 (file)
index 0000000..8ed34cf
--- /dev/null
@@ -0,0 +1,281 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace Pithos.Core
+{
+    #region Enums & Structs
+
+    #region enum HChangeNotifyEventID
+    /// <summary>
+    /// Describes the event that has occurred. 
+    /// Typically, only one event is specified at a time. 
+    /// If more than one event is specified, the values contained 
+    /// in the <i>dwItem1</i> and <i>dwItem2</i> 
+    /// parameters must be the same, respectively, for all specified events. 
+    /// This parameter can be one or more of the following values. 
+    /// </summary>
+    /// <remarks>
+    /// <para><b>Windows NT/2000/XP:</b> <i>dwItem2</i> contains the index 
+    /// in the system image list that has changed. 
+    /// <i>dwItem1</i> is not used and should be <see langword="null"/>.</para>
+    /// <para><b>Windows 95/98:</b> <i>dwItem1</i> contains the index 
+    /// in the system image list that has changed. 
+    /// <i>dwItem2</i> is not used and should be <see langword="null"/>.</para>
+    /// </remarks>
+    [Flags]
+    enum HChangeNotifyEventID
+    {
+        /// <summary>
+        /// All events have occurred. 
+        /// </summary>
+        SHCNE_ALLEVENTS = 0x7FFFFFFF,
+
+        /// <summary>
+        /// A file type association has changed. <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> 
+        /// must be specified in the <i>uFlags</i> parameter. 
+        /// <i>dwItem1</i> and <i>dwItem2</i> are not used and must be <see langword="null"/>. 
+        /// </summary>
+        SHCNE_ASSOCCHANGED = 0x08000000,
+
+        /// <summary>
+        /// The attributes of an item or folder have changed. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the item or folder that has changed. 
+        /// <i>dwItem2</i> is not used and should be <see langword="null"/>.
+        /// </summary>
+        SHCNE_ATTRIBUTES = 0x00000800,
+
+        /// <summary>
+        /// A nonfolder item has been created. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the item that was created. 
+        /// <i>dwItem2</i> is not used and should be <see langword="null"/>.
+        /// </summary>
+        SHCNE_CREATE = 0x00000002,
+
+        /// <summary>
+        /// A nonfolder item has been deleted. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the item that was deleted. 
+        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
+        /// </summary>
+        SHCNE_DELETE = 0x00000004,
+
+        /// <summary>
+        /// A drive has been added. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the root of the drive that was added. 
+        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
+        /// </summary>
+        SHCNE_DRIVEADD = 0x00000100,
+
+        /// <summary>
+        /// A drive has been added and the Shell should create a new window for the drive. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the root of the drive that was added. 
+        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
+        /// </summary>
+        SHCNE_DRIVEADDGUI = 0x00010000,
+
+        /// <summary>
+        /// A drive has been removed. <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the root of the drive that was removed.
+        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
+        /// </summary>
+        SHCNE_DRIVEREMOVED = 0x00000080,
+
+        /// <summary>
+        /// Not currently used. 
+        /// </summary>
+        SHCNE_EXTENDED_EVENT = 0x04000000,
+
+        /// <summary>
+        /// The amount of free space on a drive has changed. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the root of the drive on which the free space changed.
+        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
+        /// </summary>
+        SHCNE_FREESPACE = 0x00040000,
+
+        /// <summary>
+        /// Storage media has been inserted into a drive. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the root of the drive that contains the new media. 
+        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
+        /// </summary>
+        SHCNE_MEDIAINSERTED = 0x00000020,
+
+        /// <summary>
+        /// Storage media has been removed from a drive. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the root of the drive from which the media was removed. 
+        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
+        /// </summary>
+        SHCNE_MEDIAREMOVED = 0x00000040,
+
+        /// <summary>
+        /// A folder has been created. <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> 
+        /// or <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the folder that was created. 
+        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
+        /// </summary>
+        SHCNE_MKDIR = 0x00000008,
+
+        /// <summary>
+        /// A folder on the local computer is being shared via the network. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the folder that is being shared. 
+        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
+        /// </summary>
+        SHCNE_NETSHARE = 0x00000200,
+
+        /// <summary>
+        /// A folder on the local computer is no longer being shared via the network. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the folder that is no longer being shared. 
+        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
+        /// </summary>
+        SHCNE_NETUNSHARE = 0x00000400,
+
+        /// <summary>
+        /// The name of a folder has changed. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the previous pointer to an item identifier list (PIDL) or name of the folder. 
+        /// <i>dwItem2</i> contains the new PIDL or name of the folder. 
+        /// </summary>
+        SHCNE_RENAMEFOLDER = 0x00020000,
+
+        /// <summary>
+        /// The name of a nonfolder item has changed. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the previous PIDL or name of the item. 
+        /// <i>dwItem2</i> contains the new PIDL or name of the item. 
+        /// </summary>
+        SHCNE_RENAMEITEM = 0x00000001,
+
+        /// <summary>
+        /// A folder has been removed. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the folder that was removed. 
+        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
+        /// </summary>
+        SHCNE_RMDIR = 0x00000010,
+
+        /// <summary>
+        /// The computer has disconnected from a server. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the server from which the computer was disconnected. 
+        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
+        /// </summary>
+        SHCNE_SERVERDISCONNECT = 0x00004000,
+
+        /// <summary>
+        /// The contents of an existing folder have changed, 
+        /// but the folder still exists and has not been renamed. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the folder that has changed. 
+        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
+        /// If a folder has been created, deleted, or renamed, use SHCNE_MKDIR, SHCNE_RMDIR, or 
+        /// SHCNE_RENAMEFOLDER, respectively, instead. 
+        /// </summary>
+        SHCNE_UPDATEDIR = 0x00001000,
+
+        SHCNE_UPDATEITEM = 0x00002000,
+
+        /// <summary>
+        /// An image in the system image list has changed. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_DWORD"/> must be specified in <i>uFlags</i>. 
+        /// </summary>
+        SHCNE_UPDATEIMAGE = 0x00008000,
+
+    }
+    #endregion // enum HChangeNotifyEventID
+
+    #region public enum HChangeNotifyFlags
+    /// <summary>
+    /// Flags that indicate the meaning of the <i>dwItem1</i> and <i>dwItem2</i> parameters. 
+    /// The uFlags parameter must be one of the following values.
+    /// </summary>
+    [Flags]
+    public enum HChangeNotifyFlags
+    {
+        /// <summary>
+        /// The <i>dwItem1</i> and <i>dwItem2</i> parameters are DWORD values. 
+        /// </summary>
+        SHCNF_DWORD = 0x0003,
+        /// <summary>
+        /// <i>dwItem1</i> and <i>dwItem2</i> are the addresses of ITEMIDLIST structures that 
+        /// represent the item(s) affected by the change. 
+        /// Each ITEMIDLIST must be relative to the desktop folder. 
+        /// </summary>
+        SHCNF_IDLIST = 0x0000,
+        /// <summary>
+        /// <i>dwItem1</i> and <i>dwItem2</i> are the addresses of null-terminated strings of 
+        /// maximum length MAX_PATH that contain the full path names 
+        /// of the items affected by the change. 
+        /// </summary>
+        SHCNF_PATHA = 0x0001,
+        /// <summary>
+        /// <i>dwItem1</i> and <i>dwItem2</i> are the addresses of null-terminated strings of 
+        /// maximum length MAX_PATH that contain the full path names 
+        /// of the items affected by the change. 
+        /// </summary>
+        SHCNF_PATHW = 0x0005,
+        /// <summary>
+        /// <i>dwItem1</i> and <i>dwItem2</i> are the addresses of null-terminated strings that 
+        /// represent the friendly names of the printer(s) affected by the change. 
+        /// </summary>
+        SHCNF_PRINTERA = 0x0002,
+        /// <summary>
+        /// <i>dwItem1</i> and <i>dwItem2</i> are the addresses of null-terminated strings that 
+        /// represent the friendly names of the printer(s) affected by the change. 
+        /// </summary>
+        SHCNF_PRINTERW = 0x0006,
+        /// <summary>
+        /// The function should not return until the notification 
+        /// has been delivered to all affected components. 
+        /// As this flag modifies other data-type flags, it cannot by used by itself.
+        /// </summary>
+        SHCNF_FLUSH = 0x1000,
+        /// <summary>
+        /// The function should begin delivering notifications to all affected components 
+        /// but should return as soon as the notification process has begun. 
+        /// As this flag modifies other data-type flags, it cannot by used by itself.
+        /// </summary>
+        SHCNF_FLUSHNOWAIT = 0x2000
+    }
+    #endregion // enum HChangeNotifyFlags
+
+
+    #endregion
+
+
+    internal static class NativeMethods
+    {
+        [DllImport("shell32.dll")]
+        public static extern void SHChangeNotify(HChangeNotifyEventID wEventId,
+                                           HChangeNotifyFlags uFlags,
+                                           IntPtr dwItem1,
+                                           IntPtr dwItem2);
+
+    }
+}
diff --git a/trunk/Pithos.Core/Pithos.Core.csproj b/trunk/Pithos.Core/Pithos.Core.csproj
new file mode 100644 (file)
index 0000000..9b436b9
--- /dev/null
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{142AF135-DF30-4563-B0AC-B604235AE874}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Pithos.Core</RootNamespace>
+    <AssemblyName>Pithos.Core</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <CodeContractsAssemblyMode>1</CodeContractsAssemblyMode>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
+    <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
+    <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
+    <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
+    <CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers>
+    <CodeContractsRunCodeAnalysis>False</CodeContractsRunCodeAnalysis>
+    <CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
+    <CodeContractsBoundsObligations>False</CodeContractsBoundsObligations>
+    <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
+    <CodeContractsEnumObligations>False</CodeContractsEnumObligations>
+    <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
+    <CodeContractsRunInBackground>True</CodeContractsRunInBackground>
+    <CodeContractsShowSquigglies>False</CodeContractsShowSquigglies>
+    <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
+    <CodeContractsEmitXMLDocs>True</CodeContractsEmitXMLDocs>
+    <CodeContractsCustomRewriterAssembly />
+    <CodeContractsCustomRewriterClass />
+    <CodeContractsLibPaths />
+    <CodeContractsExtraRewriteOptions />
+    <CodeContractsExtraAnalysisOptions />
+    <CodeContractsBaseLineFile />
+    <CodeContractsCacheAnalysisResults>False</CodeContractsCacheAnalysisResults>
+    <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
+    <CodeContractsReferenceAssembly>Build</CodeContractsReferenceAssembly>
+    <CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.ComponentModel.Composition" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="IPithosWorkflow.cs" />
+    <Compile Include="IStatusKeeper.cs" />
+    <Compile Include="NativeMethods.cs" />
+    <Compile Include="PithosMonitor.cs" />
+    <Compile Include="PithosWorkflow.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="StatusChecker.cs" />
+    <Compile Include="StatusInfo.cs" />
+    <Compile Include="WorkflowState.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\..\..\ParallelProgrammingSamples\ParallelExtensionsExtras\ParallelExtensionsExtras.csproj">
+      <Project>{C45218F8-09E7-4F57-85BC-5D8D2AC736A3}</Project>
+      <Name>ParallelExtensionsExtras</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\Pithos.Interfaces\Pithos.Interfaces.csproj">
+      <Project>{7EEFF32F-CCF8-436A-9E0B-F40434C09AF4}</Project>
+      <Name>Pithos.Interfaces</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\Pithos.Network\Pithos.Network.csproj">
+      <Project>{C8E2BC8B-C7F1-4222-855C-4B04A57FFDFD}</Project>
+      <Name>Pithos.Network</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
diff --git a/trunk/Pithos.Core/PithosMonitor.cs b/trunk/Pithos.Core/PithosMonitor.cs
new file mode 100644 (file)
index 0000000..c58c264
--- /dev/null
@@ -0,0 +1,469 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.ComponentModel.Composition;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.IO;
+using System.Linq;
+using System.Security.Cryptography;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Pithos.Interfaces;
+
+namespace Pithos.Core
+{
+    [Export(typeof(PithosMonitor))]
+    public class PithosMonitor:IDisposable
+    {
+
+        [Import]
+        public IPithosSettings Settings{get;set;}
+
+        [Import]
+        public IStatusKeeper StatusKeeper { get; set; }
+
+        [Import]
+        public IPithosWorkflow Workflow { get; set; }
+
+        [Import]
+        public ICloudClient CloudClient { get; set; }
+
+        [Import]
+        public ICloudClient CloudListeningClient { get; set; }
+
+        private FileSystemWatcher _watcher;
+
+        public bool Pause
+        {
+            get { return _watcher == null || !_watcher.EnableRaisingEvents; }
+            set
+            {
+                if (_watcher!=null)
+                    _watcher.EnableRaisingEvents = !value;                
+            }
+        }
+
+
+        CancellationTokenSource _cancellationSource;
+
+        BlockingCollection<WorkflowState> _fileEvents = new BlockingCollection<WorkflowState>();
+
+        
+
+        public void Start()
+        {
+            string path = Settings.PithosPath;
+
+            CloudClient.Authenticate(Settings.UserName,Settings.ApiKey);
+
+            if (_cancellationSource != null)
+            {
+                if (!_cancellationSource.IsCancellationRequested)
+                    return;
+            }
+            _cancellationSource=new CancellationTokenSource();
+            StartListening();
+            StartSending();
+
+
+            _watcher = new FileSystemWatcher(path);            
+            _watcher.Changed += OnFileEvent;
+            _watcher.Created += OnFileEvent;
+            _watcher.Deleted += OnFileEvent;
+            _watcher.Renamed += OnRenameEvent;
+            _watcher.EnableRaisingEvents = true;            
+        }
+
+        internal enum CloudActionType
+        {
+            Upload=0,
+            Download,
+            UploadUnconditional,
+            DownloadUnconditional,
+            DeleteLocal,
+            DeleteCloud
+        }
+
+        internal class ListenerAction
+        {
+            public CloudActionType Action { get; set; }
+            public FileInfo LocalFile { get; set; }
+            public ObjectInfo CloudFile { get; set; }
+
+            public Lazy<string> LocalHash { get; set; }
+
+            public ListenerAction(CloudActionType action, FileInfo localFile, ObjectInfo cloudFile)
+            {
+                Action = action;
+                LocalFile = localFile;
+                CloudFile = cloudFile;
+                LocalHash=new Lazy<string>(()=>CalculateHash(LocalFile.FullName),LazyThreadSafetyMode.ExecutionAndPublication);
+            }
+            
+        }
+
+        internal class LocalFileComparer:EqualityComparer<ListenerAction>
+        {
+            public override bool Equals(ListenerAction x, ListenerAction y)
+            {
+                if (x.Action != y.Action)
+                    return false;
+                if (x.LocalFile != null && y.LocalFile != null && !x.LocalFile.FullName.Equals(y.LocalFile.FullName))
+                    return false;
+                if (x.CloudFile != null && y.CloudFile != null && !x.CloudFile.Hash.Equals(y.CloudFile.Hash))
+                    return false;
+                if (x.CloudFile == null ^ y.CloudFile == null ||
+                    x.LocalFile == null ^ y.LocalFile == null)
+                    return false;
+                return true;
+            }
+
+            public override int GetHashCode(ListenerAction obj)
+            {
+                var hash1 = (obj.LocalFile == null) ? int.MaxValue : obj.LocalFile.FullName.GetHashCode();
+                var hash2 = (obj.CloudFile == null) ? int.MaxValue : obj.CloudFile.Hash.GetHashCode();
+                var hash3 = obj.Action.GetHashCode();
+                return hash1 ^ hash2 & hash3;
+            }
+        }
+
+        private BlockingCollection<ListenerAction> _listenerActions=new BlockingCollection<ListenerAction>();
+
+        private Timer timer;
+
+        private void StartListening()
+        {
+            
+            Func<Task> listener = ()=>Task.Factory.StartNew(()=>CloudClient.ListObjects("PITHOS"))
+                .ContinueWith(task =>
+                                  {
+                                      
+                                      var objects = task.Result;
+                                      if (objects.Count == 0)
+                                          return;
+
+                                      var pithosDir = new DirectoryInfo(Settings.PithosPath);
+                                      
+                                      var upFiles = from info in objects
+                                                    select info.Name;
+                                      
+                                      var onlyLocal = from localFile in pithosDir.EnumerateFiles()
+                                                      where !upFiles.Contains(localFile.Name) 
+                                                      select new ListenerAction(CloudActionType.UploadUnconditional, localFile,null);
+                                      
+                                      
+                                    
+
+                                      var localNames =pithosDir.EnumerateFiles().Select(info => info.Name);
+                                      var onlyRemote = from upFile in objects
+                                                       where !localNames.Contains(upFile.Name)
+                                                       select new ListenerAction(CloudActionType.DownloadUnconditional,null,upFile);
+
+
+                                      var existingObjects = from  upFile in objects
+                                                            join  localFile in pithosDir.EnumerateFiles()
+                                                            on upFile.Name equals localFile.Name 
+                                                       select new ListenerAction(CloudActionType.Download, localFile, upFile);
+
+                                      var uniques =
+                                          onlyLocal.Union(onlyRemote).Union(existingObjects)
+                                          .Except(_listenerActions,new LocalFileComparer());
+
+                                      _listenerActions.AddFromEnumerable(uniques, false);
+                                     
+                                 }
+                );
+
+            Task.Factory.StartNew(() =>
+                                      {
+                                          foreach (var action in _listenerActions.GetConsumingEnumerable())
+                                          {
+                                              var localFile = action.LocalFile;
+                                              var cloudFile = action.CloudFile;
+                                              var downloadPath = (cloudFile==null)? String.Empty:Path.Combine(Settings.PithosPath,cloudFile.Name);
+
+                                              switch(action.Action)
+                                              {
+                                                  case CloudActionType.UploadUnconditional:
+                                                                                                        
+                                                    UploadCloudFile(localFile.Name, localFile.Length, localFile.FullName, action.LocalHash.Value);
+                                                    break;
+                                                  case CloudActionType.DownloadUnconditional:                                                      
+                                                    DownloadCloudFile("PITHOS", cloudFile.Name, downloadPath);
+                                                    break;
+                                                  case CloudActionType.Download:                                                    
+                                                    if (File.Exists(downloadPath))
+                                                    {                                                                                                     
+                                                        if (cloudFile.Hash != action.LocalHash.Value)
+                                                        {
+                                                            var lastLocalTime=localFile.LastWriteTime;
+                                                            var lastUpTime=cloudFile.Last_Modified;
+                                                            if(lastUpTime<=lastLocalTime)
+                                                            {
+                                                                //Files in conflict
+                                                                StatusKeeper.SetFileOverlayStatus(downloadPath,FileOverlayStatus.Conflict);
+                                                            }
+                                                            else
+                                                                DownloadCloudFile("PITHOS", action.CloudFile.Name, downloadPath);
+                                                        }
+                                                    }
+                                                    else
+                                                        DownloadCloudFile("PITHOS", action.CloudFile.Name, downloadPath);
+                                                    break;
+                                              }
+                                          }
+                                      }
+                );
+            
+            timer = new Timer(o => listener(), null, TimeSpan.Zero, TimeSpan.FromSeconds(10));
+            
+        }
+
+        private void DownloadCloudFile(string container, string fileName, string localPath)
+        {
+            using (var upstream = CloudClient.GetObject(container, fileName))
+            using (var fileStream = File.OpenWrite(localPath))
+            {
+                upstream.CopyTo(fileStream);
+            }
+        }
+
+        private void StartSending()
+        {
+            Task.Factory.StartNew(() =>
+                                      {
+                                          foreach (var state in _fileEvents.GetConsumingEnumerable())
+                                          {
+                                              try
+                                              {
+                                                  UpdateFileStatus(state);
+                                                  UpdateOverlayStatus(state);
+                                                  UpdateFileChecksum(state);
+                                                  SynchToCloud(state);
+                                              }
+                                              catch (OperationCanceledException)
+                                              {
+                                                  throw;
+                                              }
+                                              catch(Exception ex)
+                                              {}
+                                          }
+                                          
+                                      },_cancellationSource.Token);
+        }
+
+
+        private WorkflowState SynchToCloud(WorkflowState state)
+        {
+            if (state.Skip)
+                return state;
+            string path = state.Path;
+            string fileName = Path.GetFileName(path);
+
+            switch(state.Status)
+            {
+                case FileStatus.Created:
+                case FileStatus.Modified:
+                    var info = new FileInfo(path);
+                    long fileSize = info.Length;
+                    UploadCloudFile(fileName, fileSize, path,state.Hash);
+                    break;
+                case FileStatus.Deleted:
+                    DeleteCloudFile(fileName);
+                    break;
+                case FileStatus.Renamed:
+                    RenameCloudFile(state);
+                    break;
+            }
+            return state;
+        }
+
+        private void RenameCloudFile(WorkflowState state)
+        {
+            this.StatusKeeper.SetFileOverlayStatus(state.Path, FileOverlayStatus.Synch);
+
+
+
+            CloudClient.MoveObject("PITHOS", state.OldFileName, state.FileName);
+
+            this.StatusKeeper.SetFileStatus(state.Path, FileStatus.Unchanged);
+            this.StatusKeeper.SetFileOverlayStatus(state.Path, FileOverlayStatus.Normal);
+            Workflow.RaiseChangeNotification(state.Path);
+        }
+
+        private void DeleteCloudFile(string fileName)
+        {
+            Contract.Requires(!Path.IsPathRooted(fileName));
+
+            this.StatusKeeper.SetFileOverlayStatus(fileName, FileOverlayStatus.Synch);
+            CloudClient.DeleteObject("PITHOS", fileName);
+            this.StatusKeeper.ClearFileStatus(fileName);
+            this.StatusKeeper.RemoveFileOverlayStatus(fileName);            
+        }
+
+        private void UploadCloudFile(string fileName, long fileSize, string path,string hash)
+        {
+            Contract.Requires(!Path.IsPathRooted(fileName));
+            //Even if GetObjectInfo times out, we can proceed with the upload
+            var info=CloudClient.GetObjectInfo("PITHOS", fileName);
+            if ( hash != info.Hash)
+            {
+                this.StatusKeeper.SetFileOverlayStatus(path, FileOverlayStatus.Synch);
+                using (var stream = File.OpenRead(path))
+                {
+                    CloudClient.PutObject("PITHOS", fileName, stream, fileSize);
+                }
+            }
+            this.StatusKeeper.SetFileStatus(path,FileStatus.Unchanged);
+            this.StatusKeeper.SetFileOverlayStatus(path,FileOverlayStatus.Normal);
+            Workflow.RaiseChangeNotification(path);
+        }
+
+        private Dictionary<WatcherChangeTypes, FileStatus> _statusDict = new Dictionary<WatcherChangeTypes, FileStatus>
+        {
+            {WatcherChangeTypes.Created,FileStatus.Created},
+            {WatcherChangeTypes.Changed,FileStatus.Modified},
+            {WatcherChangeTypes.Deleted,FileStatus.Deleted},
+            {WatcherChangeTypes.Renamed,FileStatus.Renamed}
+        };
+
+        private WorkflowState UpdateFileStatus(WorkflowState  state)
+        {
+            string path = state.Path;
+            FileStatus status = _statusDict[state.TriggeringChange];
+            var oldStatus = Workflow.StatusKeeper.GetFileStatus(path);
+            if (status == oldStatus)
+            {
+                state.Status = status;
+                state.Skip = true;
+                return state;
+            }
+            if (state.Status == FileStatus.Renamed)
+                Workflow.ClearFileStatus(path);                
+
+            state.Status = Workflow.SetFileStatus(path, status);                
+            return state;
+        }
+
+        private WorkflowState UpdateOverlayStatus(WorkflowState state)
+        {            
+            if (state.Skip)
+                return state;
+
+            switch (state.Status)
+            {
+                case FileStatus.Created:
+                case FileStatus.Modified:
+                    this.StatusKeeper.SetFileOverlayStatus(state.Path, FileOverlayStatus.Modified);
+                    break;
+                case FileStatus.Deleted:
+                    this.StatusKeeper.RemoveFileOverlayStatus(state.Path);
+                    break;
+                case FileStatus.Renamed:
+                    this.StatusKeeper.RemoveFileOverlayStatus(state.OldPath);
+                    this.StatusKeeper.SetFileOverlayStatus(state.Path, FileOverlayStatus.Modified);
+                    break;
+                case FileStatus.Unchanged:
+                    this.StatusKeeper.SetFileOverlayStatus(state.Path, FileOverlayStatus.Normal);
+                    break;
+            }
+
+            if (state.Status==FileStatus.Deleted)
+                Workflow.RaiseChangeNotification(Path.GetDirectoryName(state.Path));
+            else
+                Workflow.RaiseChangeNotification(state.Path);
+            return state;
+        }
+
+
+        private WorkflowState UpdateFileChecksum(WorkflowState state)
+        {
+            if (state.Skip)
+                return state;
+
+            if (state.Status == FileStatus.Deleted)
+                return state;
+
+            string path = state.Path;
+            string hash = CalculateHash(path);
+
+            StatusKeeper.UpdateFileChecksum(path, hash);
+
+            state.Hash = hash;
+            return state;
+        }
+
+        private static string CalculateHash(string path)
+        {
+            string hash;
+            using (var hasher = MD5.Create())
+            using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 4096, true))
+            {
+                var hashBytes = hasher.ComputeHash(stream);
+                var hashBuilder = new StringBuilder();
+                foreach (byte b in hasher.ComputeHash(stream))
+                    hashBuilder.Append(b.ToString("x2").ToLower());
+                hash = hashBuilder.ToString();
+
+            }
+            return hash;
+        }
+
+        private FileSystemEventArgs CalculateSignature(FileSystemEventArgs arg)
+        {
+            Debug.WriteLine(String.Format("{0} {1} {2}", arg.ChangeType, arg.Name, arg.FullPath), "INFO");
+            return arg;
+        }
+
+        void OnFileEvent(object sender, FileSystemEventArgs e)
+        {
+            _fileEvents.Add(new WorkflowState{Path=e.FullPath,FileName = e.Name,TriggeringChange=e.ChangeType});            
+        }
+
+        void OnRenameEvent(object sender, RenamedEventArgs e)
+        {
+            _fileEvents.Add(new WorkflowState { OldPath=e.OldFullPath,OldFileName=e.OldName,
+                Path = e.FullPath, FileName = e.Name, TriggeringChange = e.ChangeType });
+        }
+
+        public void Stop()
+        {
+            if (_watcher != null)
+            {
+                _watcher.Changed -= OnFileEvent;
+                _watcher.Created -= OnFileEvent;
+                _watcher.Deleted -= OnFileEvent;
+                _watcher.Renamed -= OnRenameEvent;
+                _watcher.Dispose();
+            }
+            _watcher = null;
+            _fileEvents.CompleteAdding();
+            if (timer != null)
+                timer.Dispose();
+            timer = null;
+        }
+
+        ~PithosMonitor()
+        {
+            Dispose(false);
+        }
+
+        public void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+
+        protected virtual void Dispose(bool disposing)
+        {
+            if (disposing)
+            {
+                Stop();
+            }
+        }
+
+
+    }
+}
diff --git a/trunk/Pithos.Core/PithosWorkflow.cs b/trunk/Pithos.Core/PithosWorkflow.cs
new file mode 100644 (file)
index 0000000..8f8313a
--- /dev/null
@@ -0,0 +1,113 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Pithos.Interfaces;
+using System.IO;
+
+namespace Pithos.Core
+{
+    [Export(typeof(IPithosWorkflow))]
+    public class PithosWorkflow:IPithosWorkflow
+    {
+        [Import]
+        public IPithosSettings Settings { get; set; }
+
+        [Import]
+        public IStatusKeeper StatusKeeper { get; set; }
+
+        public FileStatus SetFileStatus(string path, FileStatus status)
+        {
+            if (String.IsNullOrWhiteSpace(path))
+                throw new ArgumentNullException("path", "The path parameter must not be emtpy");
+
+            var oldStatus=StatusKeeper.GetFileStatus(path);
+
+            if (oldStatus == status)
+                return oldStatus;
+
+            switch(oldStatus)
+            {
+                case FileStatus.Unchanged :
+                    break;
+                case FileStatus.Created:
+                    if (status == FileStatus.Modified)
+                        return oldStatus;
+                    break;
+                case FileStatus.Modified:
+                case FileStatus.Renamed:
+                    if (status == FileStatus.Created)
+                        return oldStatus;
+                    break;
+                case FileStatus.Deleted:
+                    return oldStatus;                    
+            }
+            StatusKeeper.SetFileStatus(path, status);
+            return status;
+        }
+
+        public void ClearFileStatus(string path)
+        {
+            if (String.IsNullOrWhiteSpace(path))
+                throw new ArgumentNullException("path", "The path parameter must not be emtpy");
+
+            StatusKeeper.ClearFileStatus(path);
+        }
+
+        public void RaiseChangeNotification(string path)
+        {
+            if (String.IsNullOrWhiteSpace(path))
+                throw new ArgumentNullException("path", "The path parameter must not be emtpy");
+            
+            if (!Directory.Exists(path ) && !File.Exists(path))
+                throw new FileNotFoundException("The specified file or path does not exist",path);
+            
+
+            IntPtr pathPointer = Marshal.StringToCoTaskMemAuto(path);
+
+            try
+            {
+                NativeMethods.SHChangeNotify(HChangeNotifyEventID.SHCNE_UPDATEITEM,
+                                             HChangeNotifyFlags.SHCNF_PATHW | HChangeNotifyFlags.SHCNF_FLUSHNOWAIT,
+                                             pathPointer, IntPtr.Zero);                
+            }
+            finally
+            {
+                Marshal.FreeHGlobal(pathPointer);
+            }
+
+        }
+
+        public Task<FileStream> OpenStreamWithWaiting(string path)
+        {
+            if (String.IsNullOrWhiteSpace(path))
+                throw new ArgumentNullException("path","The path parameter must not be emtpy");
+
+            if (!File.Exists(path))
+                throw new FileNotFoundException("The specified file or path does not exist", path);
+
+            return new Task<FileStream>(() =>
+                    {
+                        int counter = 0;
+                        while (true)
+                        {
+                            try
+                            {
+                                var stream=File.OpenRead(path);
+                                return stream;                                
+                            }
+                            catch (Exception ex)
+                            {
+                                Thread.Sleep(500);
+                                if (++counter > 10)
+                                    throw;
+                            }
+                        }
+                    });
+        }
+    }
+}
diff --git a/trunk/Pithos.Core/Properties/AssemblyInfo.cs b/trunk/Pithos.Core/Properties/AssemblyInfo.cs
new file mode 100644 (file)
index 0000000..2467066
--- /dev/null
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Pithos.Core")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("Pithos.Core")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("42686253-9460-441a-b2fb-5976957744df")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/trunk/Pithos.Core/StatusChecker.cs b/trunk/Pithos.Core/StatusChecker.cs
new file mode 100644 (file)
index 0000000..7319ac8
--- /dev/null
@@ -0,0 +1,79 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition;
+using System.Diagnostics.Contracts;
+using Pithos.Interfaces;
+
+namespace Pithos.Core
+{
+    [Export(typeof(IStatusChecker)),Export(typeof(IStatusKeeper))]
+    public class StatusChecker:IStatusChecker,IStatusKeeper
+    {
+        [Import]
+        public IPithosSettings Settings { get; set; }
+
+        private readonly string[] _states = {"Normal", "Modified", "Conflict","Synch"};
+
+        Dictionary<string,FileOverlayStatus> _overlayCache=new Dictionary<string,FileOverlayStatus>();
+        Dictionary<string, FileStatus> _statusCache= new Dictionary<string, FileStatus>();
+        Dictionary<string, string> _checksums = new Dictionary<string, string>();
+
+        public FileOverlayStatus GetFileOverlayStatus(string path)
+        {
+            if (!_overlayCache.ContainsKey(path))
+                return FileOverlayStatus.NA;
+
+            var pithosPath = Settings.PithosPath;
+            if (path.StartsWith(pithosPath,true,null))
+            {
+                var status = _overlayCache[path];
+                return status;
+            }
+            return FileOverlayStatus.NA;
+        }
+
+        public PithosStatus GetPithosStatus()
+        {
+            return PithosStatus.InSynch;
+        }
+
+        public void SetFileOverlayStatus(string path, FileOverlayStatus overlayStatus)
+        {
+            _overlayCache[path] = overlayStatus;
+        }
+
+        public void RemoveFileOverlayStatus(string path)
+        {
+            _overlayCache.Remove(path);
+        }
+
+        public void RenameFileOverlayStatus(string oldPath, string newPath)
+        {
+            var status=_overlayCache[oldPath];
+            _overlayCache[newPath] = status;            
+            _overlayCache.Remove(oldPath);
+        }
+
+        public void SetFileStatus(string path, FileStatus status)
+        {
+            _statusCache[path] = status;
+        }
+
+        public FileStatus GetFileStatus(string path)
+        {
+            if (!_statusCache.ContainsKey(path))
+                return FileStatus.Missing;
+            return _statusCache[path];
+        }
+
+        public void ClearFileStatus(string path)
+        {
+            _statusCache.Remove(path);
+        }
+
+        public void UpdateFileChecksum(string path, string checksum)
+        {
+            _checksums[path] = checksum;
+        }
+    }
+}
diff --git a/trunk/Pithos.Core/StatusInfo.cs b/trunk/Pithos.Core/StatusInfo.cs
new file mode 100644 (file)
index 0000000..4d9639a
--- /dev/null
@@ -0,0 +1,20 @@
+using Pithos.Interfaces;
+
+namespace Pithos.Core
+{
+    public class StatusInfo
+    {
+        public StatusInfo(PithosStatus status, string statusText, string iconName)
+        {
+            Status = status;
+            StatusText = statusText;
+            IconName = iconName;
+        }
+
+        public PithosStatus Status { get; set; }
+        public string StatusText { get; set; }
+        public string IconName { get; set; }
+
+
+    }
+}
diff --git a/trunk/Pithos.Core/WorkflowState.cs b/trunk/Pithos.Core/WorkflowState.cs
new file mode 100644 (file)
index 0000000..0300da7
--- /dev/null
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Pithos.Core
+{
+    class WorkflowState
+    {
+        public string Path { get; set; }
+        public string FileName { get; set; }
+        
+        public string OldPath { get; set; }
+        public string OldFileName{ get; set; }
+
+        public WatcherChangeTypes TriggeringChange { get; set; }
+        public FileStatus Status { get; set; }
+        
+        public bool Skip { get; set; }
+
+        public string Hash { get; set; }
+        public string LastUpdateHash { get; set; }
+    }
+}
diff --git a/trunk/Pithos.Interfaces/ICloudClient.cs b/trunk/Pithos.Interfaces/ICloudClient.cs
new file mode 100644 (file)
index 0000000..6d0770e
--- /dev/null
@@ -0,0 +1,175 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.Contracts;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Pithos.Interfaces
+{
+    [ContractClass(typeof(ICloudClientContract))]
+    public interface ICloudClient
+    {
+        string ApiKey { get; set; }
+        string UserName { get; set; }
+        string StorageUrl { get; set; }
+        string Token { get; set; }
+        void Authenticate(string userName,string apiKey);
+        
+        IList<ContainerInfo> ListContainers();
+        IList<ObjectInfo> ListObjects(string container);
+        bool ContainerExists(string container);
+        ContainerInfo GetContainerInfo(string container);
+        void CreateContainer(string container);
+        
+        Stream GetObject(string container, string objectName);
+        void PutObject(string container, string objectName, Stream file,long fileSize);
+        void DeleteObject(string container, string objectName);
+        void MoveObject(string container, string oldObjectName, string newObjectName);
+        bool ObjectExists(string container,string objectName);
+        ObjectInfo GetObjectInfo(string container, string objectName);
+    }
+
+
+    [ContractClassFor(typeof(ICloudClient))]
+    public abstract class ICloudClientContract:ICloudClient
+    {
+        public string ApiKey { get; set; }
+        public string UserName { get; set; }
+        public string StorageUrl { get; set; }
+        public string Token { get; set; }
+
+        public void Authenticate(string userName, string apiKey)
+        {
+            Contract.Requires<ArgumentNullException>(!String.IsNullOrWhiteSpace(apiKey), "ApiKey must be filled before calling Authenticate");
+            Contract.Requires<ArgumentNullException>(!String.IsNullOrWhiteSpace(userName), "UserName must be filled before calling Authenticate");
+
+
+            Contract.Ensures(apiKey==ApiKey);
+            Contract.Ensures(userName==UserName);
+            Contract.Ensures(!String.IsNullOrWhiteSpace(StorageUrl));
+            Contract.Ensures(!String.IsNullOrWhiteSpace(Token));
+            
+        }
+
+        public IList<ContainerInfo> ListContainers()
+        {
+            Contract.Requires(!String.IsNullOrWhiteSpace(Token));
+            Contract.Requires(!String.IsNullOrWhiteSpace(StorageUrl));
+
+            return default(IList<ContainerInfo>);
+        }
+
+        public IList<ObjectInfo> ListObjects(string container)
+        {
+            Contract.Requires(!String.IsNullOrWhiteSpace(Token));
+            Contract.Requires(!String.IsNullOrWhiteSpace(StorageUrl));
+            Contract.Requires(!String.IsNullOrWhiteSpace(container));
+
+            return default(IList<ObjectInfo>);
+        }
+
+        public bool ContainerExists(string container)
+        {
+            Contract.Requires(!String.IsNullOrWhiteSpace(Token));
+            Contract.Requires(!String.IsNullOrWhiteSpace(StorageUrl));
+            Contract.Requires(!String.IsNullOrWhiteSpace(container));
+
+            return default(bool);
+        }
+
+        public ContainerInfo GetContainerInfo(string container)
+        {
+            Contract.Requires(!String.IsNullOrWhiteSpace(Token));
+            Contract.Requires(!String.IsNullOrWhiteSpace(StorageUrl));
+            Contract.Requires(!String.IsNullOrWhiteSpace(container));
+
+            return default(ContainerInfo);
+        }
+
+        public void CreateContainer(string container)
+        {
+            Contract.Requires(!String.IsNullOrWhiteSpace(Token));
+            Contract.Requires(!String.IsNullOrWhiteSpace(StorageUrl));
+            Contract.Requires(!String.IsNullOrWhiteSpace(container));
+        }
+
+        public Stream GetObject(string container, string objectName)
+        {
+            Contract.Requires(!String.IsNullOrWhiteSpace(Token));
+            Contract.Requires(!String.IsNullOrWhiteSpace(StorageUrl));
+            Contract.Requires(!String.IsNullOrWhiteSpace(container));
+            Contract.Requires(!String.IsNullOrWhiteSpace(objectName));
+
+            return default(Stream);
+        }
+
+        public void PutObject(string container, string objectName, Stream file,long fileSize)
+        {
+            Contract.Requires(!String.IsNullOrWhiteSpace(Token));
+            Contract.Requires(!String.IsNullOrWhiteSpace(StorageUrl));
+            Contract.Requires(!String.IsNullOrWhiteSpace(container));
+            Contract.Requires(file!=null);
+            Contract.Requires(file.CanRead);
+            Contract.Requires(fileSize>=0);            
+            Contract.Requires(!String.IsNullOrWhiteSpace(objectName));
+        }
+
+        public void DeleteObject(string container, string objectName)
+        {
+            Contract.Requires(!String.IsNullOrWhiteSpace(Token));
+            Contract.Requires(!String.IsNullOrWhiteSpace(StorageUrl));
+            Contract.Requires(!String.IsNullOrWhiteSpace(container));
+            Contract.Requires(!String.IsNullOrWhiteSpace(objectName));
+        }
+
+        public void MoveObject(string container, string oldObjectName, string newObjectName)
+        {
+            Contract.Requires(!String.IsNullOrWhiteSpace(Token));
+            Contract.Requires(!String.IsNullOrWhiteSpace(StorageUrl));
+            Contract.Requires(!String.IsNullOrWhiteSpace(container));
+            Contract.Requires(!String.IsNullOrWhiteSpace(oldObjectName));
+            Contract.Requires(!String.IsNullOrWhiteSpace(newObjectName));
+        }
+
+        public bool ObjectExists(string container,string objectName)
+        {
+            Contract.Requires(!String.IsNullOrWhiteSpace(Token));
+            Contract.Requires(!String.IsNullOrWhiteSpace(StorageUrl));
+            Contract.Requires(!String.IsNullOrWhiteSpace(container));
+            Contract.Requires(!String.IsNullOrWhiteSpace(objectName));
+
+            return default(bool);
+        }
+
+        public ObjectInfo GetObjectInfo(string container,string objectName)
+        {
+            Contract.Requires(!String.IsNullOrWhiteSpace(Token));
+            Contract.Requires(!String.IsNullOrWhiteSpace(StorageUrl));
+            Contract.Requires(!String.IsNullOrWhiteSpace(container));
+            Contract.Requires(!String.IsNullOrWhiteSpace(objectName));
+
+            return default(ObjectInfo);
+        }
+    }
+
+    public class ContainerInfo
+    {
+        public string Name { get; set; }
+        public long Count { get; set; }
+        public long Bytes { get; set; }
+
+        public static ContainerInfo Empty=new ContainerInfo();
+    }
+    
+    public class ObjectInfo
+    {
+        public string Name { get; set; }
+        public string Hash { get; set; }
+        public long Bytes { get; set; }
+        public string Content_Type { get; set; }
+        public DateTime Last_Modified { get; set; }
+
+        public static ObjectInfo Empty=new ObjectInfo {Name=String.Empty,Hash=String.Empty,Bytes=0,Content_Type=String.Empty,Last_Modified=DateTime.MinValue};
+    }
+}
diff --git a/trunk/Pithos.Interfaces/IPithosSettings.cs b/trunk/Pithos.Interfaces/IPithosSettings.cs
new file mode 100644 (file)
index 0000000..e421700
--- /dev/null
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Pithos.Interfaces
+{
+    public interface IPithosSettings
+    {
+        string PithosPath { get; set; }
+        string IconsPath { get; set; }
+        string UserName { get; set; }
+        string ApiKey { get; set; }
+
+        void Save();
+        void Reload();
+    }
+}
diff --git a/trunk/Pithos.Interfaces/IStatusChecker.cs b/trunk/Pithos.Interfaces/IStatusChecker.cs
new file mode 100644 (file)
index 0000000..08c14e6
--- /dev/null
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.Contracts;
+using System.Linq;
+using System.Text;
+
+namespace Pithos.Interfaces
+{
+    [ContractClass(typeof(IStatusCheckerContract))]
+    public interface IStatusChecker
+    {
+        FileOverlayStatus GetFileOverlayStatus(string path);
+
+        PithosStatus GetPithosStatus();
+
+    }
+
+    [ContractClassFor(typeof(IStatusChecker))]
+    public abstract class IStatusCheckerContract:IStatusChecker
+    {
+        public FileOverlayStatus GetFileOverlayStatus(string path)
+        {
+            Contract.Requires(!String.IsNullOrWhiteSpace(path),"Null or empty paths not allowed");
+
+            return default(FileOverlayStatus);
+        }
+
+        public PithosStatus GetPithosStatus()
+        {
+            return default(PithosStatus);
+        }
+    }
+
+    public enum FileOverlayStatus
+    {
+        Deleted=-2,
+        NA=-1,
+        Normal=0,
+        Modified,
+        Conflict,
+        Synch       
+    }
+
+    public enum PithosStatus
+    {
+        InSynch,
+        Synching,
+        HasConflicts,
+        Disconnected
+    }
+}
diff --git a/trunk/Pithos.Interfaces/Pithos.Interfaces.csproj b/trunk/Pithos.Interfaces/Pithos.Interfaces.csproj
new file mode 100644 (file)
index 0000000..545ca85
--- /dev/null
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{7EEFF32F-CCF8-436A-9E0B-F40434C09AF4}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Pithos.Interfaces</RootNamespace>
+    <AssemblyName>Pithos.Interfaces</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <CodeContractsAssemblyMode>1</CodeContractsAssemblyMode>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
+    <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
+    <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
+    <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
+    <CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers>
+    <CodeContractsRunCodeAnalysis>True</CodeContractsRunCodeAnalysis>
+    <CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
+    <CodeContractsBoundsObligations>False</CodeContractsBoundsObligations>
+    <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
+    <CodeContractsEnumObligations>False</CodeContractsEnumObligations>
+    <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
+    <CodeContractsRunInBackground>True</CodeContractsRunInBackground>
+    <CodeContractsShowSquigglies>True</CodeContractsShowSquigglies>
+    <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
+    <CodeContractsEmitXMLDocs>True</CodeContractsEmitXMLDocs>
+    <CodeContractsCustomRewriterAssembly />
+    <CodeContractsCustomRewriterClass />
+    <CodeContractsLibPaths />
+    <CodeContractsExtraRewriteOptions />
+    <CodeContractsExtraAnalysisOptions />
+    <CodeContractsBaseLineFile />
+    <CodeContractsCacheAnalysisResults>False</CodeContractsCacheAnalysisResults>
+    <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
+    <CodeContractsReferenceAssembly>Build</CodeContractsReferenceAssembly>
+    <CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup>
+    <SignAssembly>true</SignAssembly>
+  </PropertyGroup>
+  <PropertyGroup>
+    <AssemblyOriginatorKeyFile>pithos.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="ICloudClient.cs" />
+    <Compile Include="IPithosSettings.cs" />
+    <Compile Include="IStatusChecker.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="pithos.snk" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
diff --git a/trunk/Pithos.Interfaces/Properties/AssemblyInfo.cs b/trunk/Pithos.Interfaces/Properties/AssemblyInfo.cs
new file mode 100644 (file)
index 0000000..90bdcf7
--- /dev/null
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Pithos.Interfaces")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("Pithos.Interfaces")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("3683c574-ab30-4a94-aaff-9a3b262da7e6")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/trunk/Pithos.Interfaces/pithos.snk b/trunk/Pithos.Interfaces/pithos.snk
new file mode 100644 (file)
index 0000000..2069d32
Binary files /dev/null and b/trunk/Pithos.Interfaces/pithos.snk differ
diff --git a/trunk/Pithos.Network.Test/ChecksumTest.cs b/trunk/Pithos.Network.Test/ChecksumTest.cs
new file mode 100644 (file)
index 0000000..42030f3
--- /dev/null
@@ -0,0 +1,66 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Security.Cryptography;
+using System.Text;
+using NUnit.Framework;
+using Pithos.Interfaces;
+
+
+namespace Pithos.Network.Test
+{
+    [TestFixture]
+    class ChecksumTest
+    {
+        private ICloudClient client;
+        [SetUp]
+        public void Setup()
+        {
+            client = new CloudFilesClient();
+            client.Authenticate("", "");
+            
+        }
+
+        [Test]
+        public void TestChecksum()
+        {
+            Assert.DoesNotThrow(() =>
+            {
+
+                var filePath = @"e:\DeveloperGuide.pdf";
+                var info=new FileInfo(filePath);
+
+                using (var file = File.OpenRead(filePath))
+                {
+                    var hash = CalculateHash(file);
+                    file.Seek(0, 0);
+                    client.PutObject("Shares", info.Name, file, info.Length);
+
+
+                    var meta = client.GetObjectInfo("Shares", "DeveloperGuide.pdf");
+                    Assert.IsNotEmpty(meta.Hash);
+                    
+
+                    Assert.AreEqual(hash,meta.Hash,String.Format("The hashes don't match, expected {0} but got {1}",hash,meta.Hash));
+                }
+
+            });
+
+        
+        }
+
+        private static string CalculateHash(FileStream file)
+        {
+            string hash;
+            using (var hasher = MD5.Create())
+            {
+                var hashBuilder = new StringBuilder();
+                foreach (byte b in hasher.ComputeHash(file))
+                    hashBuilder.Append(b.ToString("x2").ToLower());
+                hash = hashBuilder.ToString();
+            }
+            return hash;
+        }
+    }
+}
diff --git a/trunk/Pithos.Network.Test/NetworkOpsTest.cs b/trunk/Pithos.Network.Test/NetworkOpsTest.cs
new file mode 100644 (file)
index 0000000..088b71b
--- /dev/null
@@ -0,0 +1,269 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using Pithos.Interfaces;
+using System.IO;
+
+namespace Pithos.Network.Test
+{
+    [TestFixture]
+    class NetworkOpsTest
+    {
+        [Test]
+        public void TestAuthenticate()
+        {
+            ICloudClient client = new CloudFilesClient();
+            client.Authenticate("", "");
+            string storageUrl=client.StorageUrl;
+            string token = client.Token;
+
+            Assert.IsNotEmpty(storageUrl, "Storage Url was empty");
+            Assert.IsNotEmpty(token, "Token was empty");
+        }
+
+        [Test]
+        public void TestListContainers()
+        {
+            ICloudClient client = new CloudFilesClient();
+            client.Authenticate("", "");
+
+            IList<ContainerInfo> containers=client.ListContainers();
+            Assert.IsTrue(containers.Count()>1);
+        }
+
+        [Test]
+        public void TestListObjects()
+        {
+            ICloudClient client = new CloudFilesClient();
+            client.Authenticate("", "");
+
+            IList<ObjectInfo> objects=client.ListObjects("PITHOS");
+            Assert.IsTrue(objects.Count()>=1);
+        }
+
+        [Test]
+        public void TestContainerExists()
+        {
+            ICloudClient client = new CloudFilesClient();
+            client.Authenticate("", "");
+
+            bool dnzExists=client.ContainerExists("DotNetZone");
+            bool pithosExists = client.ContainerExists("PITHOS");
+            bool mooExists = client.ContainerExists("Moo");
+            Assert.IsTrue(dnzExists);
+            Assert.IsTrue(pithosExists);
+            Assert.IsFalse(mooExists);
+        }
+
+        [Test]
+        public void TestGetContainerInfo()
+        {
+            ICloudClient client = new CloudFilesClient();
+            client.Authenticate("", "");
+
+            var dnzInfo =client.GetContainerInfo("DotNetZone");
+            Assert.AreNotEqual(ContainerInfo.Empty, dnzInfo);
+
+            var pithosInfo = client.GetContainerInfo("PITHOS");
+            Assert.AreNotEqual(ContainerInfo.Empty, pithosInfo);
+
+            var mooInfo = client.GetContainerInfo("moo");
+            Assert.AreEqual(ContainerInfo.Empty, mooInfo);
+        }
+
+        [Test]
+        public void TestCreateContainer()
+        {
+            Assert.DoesNotThrow(() =>
+                                    {
+                                        ICloudClient client = new CloudFilesClient();
+                                        client.Authenticate("", "");
+
+                                        client.CreateContainer("Shares");
+                                        Assert.IsTrue(client.ContainerExists("Shares"));
+                                        client.CreateContainer("DotNetZone");
+                                        Assert.IsTrue(client.ContainerExists("DotNetZone"));
+                                    });
+        }
+
+        [Test]
+        public void TestGetObject()
+        {
+            Assert.DoesNotThrow(() =>
+            {
+                ICloudClient client = new CloudFilesClient();
+                client.Authenticate("", "");
+
+                client.CreateContainer("Shares");
+                Assert.IsTrue(client.ContainerExists("Shares"));
+                using (var stream = client.GetObject("DotNetZone", "OData and WCF Data Services.pptx"))
+                using(var file=File.Create(@"e:\test.pptx",4096,FileOptions.DeleteOnClose))
+                {
+                    stream.CopyTo(file);
+                    Assert.IsTrue(File.Exists(@"e:\test.pptx"));
+                }
+                
+            });
+            
+        }
+
+        [Test]
+        public void TestPutObject()
+        {
+            Assert.DoesNotThrow(() =>
+            {
+                ICloudClient client = new CloudFilesClient();
+                client.Authenticate("", "");
+
+                client.CreateContainer("Shares");
+                Assert.IsTrue(client.ContainerExists("Shares"));                
+
+                var filePath = @"e:\DeveloperGuide.pdf";
+                FileInfo info=new FileInfo(filePath);
+                
+                using (var file = File.OpenRead(filePath))
+                {
+                    client.PutObject("Shares",info.Name, file,info.Length );
+                }
+
+            });
+
+        }
+
+        [Test]
+        public void TestGetObjectMetadata()
+        {
+            Assert.DoesNotThrow(() =>
+            {
+                ICloudClient client = new CloudFilesClient();
+                client.Authenticate("", "");
+
+                var filePath = "DeveloperGuide.pdf";
+                var meta=client.GetObjectInfo("Shares", filePath);
+                Assert.IsNotEmpty(meta.Hash);
+                Assert.AreEqual(meta.Name,filePath);
+
+            });
+
+        }
+
+        [Test]
+        public void TestDeleteObject()
+        {
+            Assert.DoesNotThrow(() =>
+            {
+                ICloudClient client = new CloudFilesClient();
+                client.Authenticate("", "");
+
+                client.CreateContainer("Shares");
+                Assert.IsTrue(client.ContainerExists("Shares"),"Container Exists");                
+
+                var filePath = @"e:\DeveloperGuide.pdf";
+                FileInfo info=new FileInfo(filePath);
+                
+                using (var file = File.OpenRead(filePath))
+                {
+                    client.PutObject("Shares",info.Name, file,info.Length );
+                }
+
+                Assert.IsTrue(client.ObjectExists("Shares",info.Name),"File Created");
+
+                client.DeleteObject("Shares",info.Name);
+                Assert.IsFalse(client.ObjectExists("Shares", info.Name),"File Deleted");
+                
+
+
+
+            });
+
+        }
+
+        [Test]
+        public void TestFilesWithSpaces()
+        {
+            ICloudClient client = new CloudFilesClient();
+            client.Authenticate("", "");
+            
+            var testName = "Name with spaces.txt";
+            
+            using(var stream=new MemoryStream())
+            using (var writer = new StreamWriter(stream))
+            {
+                
+                writer.WriteLine("This is a test line");
+                stream.Seek(0, 0);
+                
+                client.PutObject("PITHOS",testName,stream,stream.Length);                
+            }
+
+            Assert.DoesNotThrow(() =>
+                                    {
+                                        var info = client.GetObjectInfo("PITHOS", testName);
+                                        Assert.AreEqual(testName, info.Name);
+                                    });
+            Assert.DoesNotThrow(() =>
+                                    {
+                                        client.DeleteObject("PITHOS", testName);                                        
+                                    });
+        }
+
+        [Test]
+        public void TestMoveObject()
+        {
+            Assert.DoesNotThrow(() =>
+            {
+                ICloudClient client = new CloudFilesClient();
+                client.Authenticate("", "");
+
+                client.CreateContainer("Shares");
+                Assert.IsTrue(client.ContainerExists("Shares"),"Container Exists");                
+
+                var filePath = @"e:\DeveloperGuide.pdf";
+                FileInfo info=new FileInfo(filePath);
+                
+                using (var file = File.OpenRead(filePath))
+                {
+                    client.PutObject("Shares",info.Name, file,info.Length );
+                }
+
+                Assert.IsTrue(client.ObjectExists("Shares",info.Name),"File Created");
+
+                client.MoveObject("Shares",info.Name,"smoo.pdf");
+                Assert.IsFalse(client.ObjectExists("Shares", info.Name),"Original File Deleted");
+                Assert.IsTrue(client.ObjectExists("Shares", "smoo.pdf"), "Target File Created");
+
+            });
+
+        }
+
+        [Test]
+        public void TestGetObjectMissing()
+        {
+
+        }
+
+
+        [Test]
+        public void TestAuthenticateMissingArguments()
+        {
+            Assert.Catch<ArgumentNullException>(() =>
+            {
+                ICloudClient client = new CloudFilesClient();                
+                client.Authenticate("someUser",null);
+            });
+
+            Assert.Catch<ArgumentNullException>(() =>
+            {
+                ICloudClient client = new CloudFilesClient();
+                client.Authenticate(null,"someKey");
+            });
+
+        }
+    }
+
+    
+}
diff --git a/trunk/Pithos.Network.Test/Pithos.Network.Test.csproj b/trunk/Pithos.Network.Test/Pithos.Network.Test.csproj
new file mode 100644 (file)
index 0000000..620960b
--- /dev/null
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{E027200B-C26A-4877-BFD9-1A18CF5DF2F4}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Pithos.Network.Test</RootNamespace>
+    <AssemblyName>Pithos.Network.Test</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Microsoft.Pex.Framework, Version=0.94.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
+    <Reference Include="nunit.framework, Version=2.5.10.11092, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL" />
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="ChecksumTest.cs" />
+    <Compile Include="NetworkOpsTest.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\Pithos.Interfaces\Pithos.Interfaces.csproj">
+      <Project>{7EEFF32F-CCF8-436A-9E0B-F40434C09AF4}</Project>
+      <Name>Pithos.Interfaces</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\Pithos.Network\Pithos.Network.csproj">
+      <Project>{C8E2BC8B-C7F1-4222-855C-4B04A57FFDFD}</Project>
+      <Name>Pithos.Network</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
diff --git a/trunk/Pithos.Network.Test/Properties/AssemblyInfo.cs b/trunk/Pithos.Network.Test/Properties/AssemblyInfo.cs
new file mode 100644 (file)
index 0000000..88a1171
--- /dev/null
@@ -0,0 +1,42 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using Microsoft.Pex.Framework.Instrumentation;
+using Pithos.Network;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Pithos.Network.Test")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("Pithos.Network.Test")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("593df921-d80c-43fb-8df7-2b10a9c2b48d")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+
+
+// monitor types in Pithos.Network.dll
+[assembly: PexInstrumentAssembly(typeof(CloudFilesClient))]
diff --git a/trunk/Pithos.Network/CloudFilesClient.cs b/trunk/Pithos.Network/CloudFilesClient.cs
new file mode 100644 (file)
index 0000000..d282d88
--- /dev/null
@@ -0,0 +1,352 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition;
+using System.Diagnostics.Contracts;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Security.Cryptography;
+using System.Text;
+using Hammock;
+using Hammock.Caching;
+using Hammock.Retries;
+using Hammock.Serialization;
+using Hammock.Web;
+using Newtonsoft.Json;
+using Pithos.Interfaces;
+
+namespace Pithos.Network
+{
+    [Export(typeof(ICloudClient))]
+    public class CloudFilesClient:ICloudClient
+    {
+        string _authUrl = "https://auth.api.rackspacecloud.com/v1.0";
+        private RestClient _client;
+        private readonly TimeSpan _timeout = TimeSpan.FromSeconds(10);
+        private readonly int _retries = 5;
+        public string ApiKey { get; set; }
+        public string UserName { get; set; }
+        public string StorageUrl { get; set; }
+        public string Token { get; set; }
+
+        public void Authenticate(string userName,string apiKey)
+        {
+            if (String.IsNullOrWhiteSpace(userName))
+                throw new ArgumentNullException("userName","The userName property can't be empty");
+            if (String.IsNullOrWhiteSpace(apiKey))
+                throw new ArgumentNullException("apiKey", "The apiKey property can't be empty");
+            
+
+            UserName = userName;
+            ApiKey = apiKey;
+
+            RestClient authClient = new RestClient();
+            var request = new RestRequest {Path = _authUrl};
+            request.AddHeader("X-Auth-User",UserName);
+            request.AddHeader("X-Auth-Key",ApiKey);            
+            
+            var response=authClient.Request(request);
+            
+            ThrowIfNotStatusOK(response, "Authentication failed");
+
+            var keys = response.Headers.AllKeys.AsQueryable();
+
+            var storageUrl=GetHeaderValue("X-Storage-Url", response, keys);
+            
+            if (String.IsNullOrWhiteSpace(storageUrl))
+                throw new InvalidOperationException("Failed to obtain storage url");
+            StorageUrl = storageUrl;
+
+            
+            var token = GetHeaderValue("X-Auth-Token",response,keys);
+            if (String.IsNullOrWhiteSpace(token))
+                throw new InvalidOperationException("Failed to obtain token url");
+            Token = token;
+
+            _client = new RestClient { Authority = StorageUrl, RetryPolicy = new RetryPolicy { RetryCount = _retries }, Timeout = _timeout };
+            _client.RetryPolicy.RetryConditions.Add(new TimeoutRetryCondition());
+            _client.AddHeader("X-Auth-Token", Token);
+            
+
+        }
+
+        public IList<ContainerInfo> ListContainers()
+        {                        
+            var request = new RestRequest();
+            request.AddParameter("format","json");
+            var response = _client.Request(request);
+
+            ThrowIfNotStatusOK(response, "List Containers failed");
+
+            if (response.StatusCode == HttpStatusCode.NoContent)
+                return new List<ContainerInfo>();
+
+            var infos=JsonConvert.DeserializeObject<IList<ContainerInfo>>(response.Content);
+            
+            return infos;
+        }
+
+        public IList<ObjectInfo> ListObjects(string container)
+        {
+            if (String.IsNullOrWhiteSpace(container))
+                throw new ArgumentNullException("container", "The container property can't be empty");
+
+            var request = new RestRequest{Path=container};
+            request.AddParameter("format", "json");
+            var response = _client.Request(request);
+            if (response.TimedOut)
+                return new List<ObjectInfo>();
+
+            ThrowIfNotStatusOK(response, "List Objects failed");
+
+            if (response.StatusCode == HttpStatusCode.NoContent)
+                return new List<ObjectInfo>();
+            
+
+            var infos = JsonConvert.DeserializeObject<IList<ObjectInfo>>(response.Content);
+
+            return infos;
+        }
+
+        public bool ContainerExists(string container)
+        {
+            if (String.IsNullOrWhiteSpace(container))
+                throw new ArgumentNullException("container", "The container property can't be empty");
+
+            var request = new RestRequest {Path = container, Method = WebMethod.Head};
+            var response = _client.Request(request);
+
+            switch(response.StatusCode)
+            {
+                case HttpStatusCode.NoContent:
+                    return true;
+                case HttpStatusCode.NotFound:
+                    return false;                    
+                default:
+                    throw new WebException(String.Format("ContainerExists failed with unexpected status code {0}",response.StatusCode));
+            }
+        }
+
+        public bool ObjectExists(string container,string objectName)
+        {
+            if (String.IsNullOrWhiteSpace(container))
+                throw new ArgumentNullException("container", "The container property can't be empty");
+            if (String.IsNullOrWhiteSpace(objectName))
+                throw new ArgumentNullException("objectName", "The objectName property can't be empty");
+
+            
+            var request = new RestRequest { Path = container + "/" + objectName, Method = WebMethod.Head };
+            var response = _client.Request(request);
+
+            switch (response.StatusCode)
+            {
+                case HttpStatusCode.OK:
+                case HttpStatusCode.NoContent:
+                    return true;
+                case HttpStatusCode.NotFound:
+                    return false;
+                default:
+                    throw new WebException(String.Format("ObjectExists failed with unexpected status code {0}", response.StatusCode));
+            }
+            
+        }
+
+        public ObjectInfo GetObjectInfo(string container, string objectName)
+        {
+            if (String.IsNullOrWhiteSpace(container))
+                throw new ArgumentNullException("container", "The container property can't be empty");
+            if (String.IsNullOrWhiteSpace(objectName))
+                throw new ArgumentNullException("objectName", "The objectName property can't be empty");
+
+
+            var request = new RestRequest { Path = container + "/" + objectName, Method = WebMethod.Head };
+            var response = _client.Request(request);
+
+            if (response.TimedOut)
+                return ObjectInfo.Empty;
+
+            switch (response.StatusCode)
+            {
+                case HttpStatusCode.OK:
+                case HttpStatusCode.NoContent:
+                    var keys = response.Headers.AllKeys.AsQueryable();
+                    return new ObjectInfo
+                               {
+                                   Name=objectName,
+                                   Bytes = long.Parse(GetHeaderValue("Content-Length", response, keys)),
+                                   Hash = GetHeaderValue("ETag", response, keys),
+                                   Content_Type = GetHeaderValue("Content-Type", response, keys)
+                               };
+                case HttpStatusCode.NotFound:
+                    return ObjectInfo.Empty;
+                default:
+                        throw new WebException(String.Format("GetObjectInfo failed with unexpected status code {0}", response.StatusCode));
+            }
+        }
+
+        public ContainerInfo GetContainerInfo(string container)
+        {
+            if (String.IsNullOrWhiteSpace(container))
+                throw new ArgumentNullException("container", "The container property can't be empty");
+
+            var request = new RestRequest {Path = container, Method = WebMethod.Head};
+            var response = _client.Request(request);
+
+            switch(response.StatusCode)
+            {
+                case HttpStatusCode.NoContent:
+                    var keys = response.Headers.AllKeys.AsQueryable();
+                    var containerInfo = new ContainerInfo
+                                            {
+                                                Name = container,
+                                                Count =long.Parse(GetHeaderValue("X-Container-Object-Count", response, keys)),
+                                                Bytes =long.Parse(GetHeaderValue("X-Container-Bytes-Used", response, keys))
+                                            };
+                    return containerInfo;
+                case HttpStatusCode.NotFound:
+                    return ContainerInfo.Empty;                    
+                default:
+                    throw new WebException(String.Format("ContainerExists failed with unexpected status code {0}",response.StatusCode));
+            }
+        }
+
+        public void CreateContainer(string container)
+        {
+            if (String.IsNullOrWhiteSpace(container))
+                throw new ArgumentNullException("container", "The container property can't be empty");
+
+            var request = new RestRequest { Path = container, Method = WebMethod.Put };
+            var response = _client.Request(request);
+            
+            
+            if (response.StatusCode!=HttpStatusCode.Created && response.StatusCode!=HttpStatusCode.Accepted )
+                    throw new WebException(String.Format("ContainerExists failed with unexpected status code {0}", response.StatusCode));
+        }
+
+        public Stream GetObject(string container, string objectName)
+        {
+            if (String.IsNullOrWhiteSpace(container))
+                throw new ArgumentNullException("container", "The container property can't be empty");
+            if (String.IsNullOrWhiteSpace(objectName))
+                throw new ArgumentNullException("objectName", "The objectName property can't be empty");
+
+            var request = new RestRequest { Path = container + "/" + objectName, Method = WebMethod.Get };
+            var response = _client.Request(request);
+            
+            if (response.StatusCode == HttpStatusCode.NotFound)
+                throw new FileNotFoundException();
+            if (response.StatusCode == HttpStatusCode.OK)
+            {
+                return response.ContentStream;
+            }
+            else
+                throw new WebException(String.Format("GetObject failed with unexpected status code {0}", response.StatusCode));
+        }
+
+        public void PutObject(string container, string objectName, Stream file,long fileSize)
+        {
+            if (String.IsNullOrWhiteSpace(container))
+                throw new ArgumentNullException("container", "The container property can't be empty");
+            if (String.IsNullOrWhiteSpace(objectName))
+                throw new ArgumentNullException("objectName", "The objectName property can't be empty");
+            if (file==null)
+                throw new ArgumentNullException("file", "The file property can't be empty");
+
+
+            string url = StorageUrl + "/" + container + "/" + objectName;                        
+
+            WebRequest request = WebRequest.Create(url);
+            request.Headers["X-Auth-Token"]=Token;
+            request.Method = "PUT";
+            //request.Headers.Add("Content-Length",fileSize.ToString());
+            //request.Headers.Add("Content-Type","application/octet-stream");            
+
+
+            string hash = CalculateHash(file);
+
+            request.Headers["ETag"] = hash;
+            using (var stream = request.GetRequestStream())
+            {
+                file.Seek(0, SeekOrigin.Begin);
+                file.CopyTo(stream);
+            }
+
+
+            var response=request.GetResponse() as HttpWebResponse;
+
+            if (response.StatusCode == HttpStatusCode.Created)
+                return;
+            if (response.StatusCode == HttpStatusCode.LengthRequired)
+                throw new InvalidOperationException();
+            else
+                throw new WebException(String.Format("GetObject failed with unexpected status code {0}", response.StatusCode));
+        }
+
+        private static string CalculateHash(Stream file)
+        {
+            string hash;
+            using (var hasher = MD5.Create())
+            {
+                var hashBuilder=new StringBuilder();
+                foreach (byte b in hasher.ComputeHash(file))
+                    hashBuilder.Append(b.ToString("x2").ToLower());
+                hash = hashBuilder.ToString();                
+            }
+            return hash;
+        }
+
+        public void DeleteObject(string container, string objectName)
+        {
+            if (String.IsNullOrWhiteSpace(container))
+                throw new ArgumentNullException("container", "The container property can't be empty");
+            if (String.IsNullOrWhiteSpace(objectName))
+                throw new ArgumentNullException("objectName", "The objectName property can't be empty");
+
+            var request = new RestRequest { Path = container + "/" + objectName, Method = WebMethod.Delete };
+            var response = _client.Request(request);
+
+            if (response.StatusCode == HttpStatusCode.NotFound || response.StatusCode == HttpStatusCode.NoContent)
+                return;
+            else
+                throw new WebException(String.Format("GetObject failed with unexpected status code {0}", response.StatusCode));
+   
+        }
+
+        public void MoveObject(string container, string oldObjectName, string newObjectName)
+        {
+            if (String.IsNullOrWhiteSpace(container))
+                throw new ArgumentNullException("container", "The container property can't be empty");
+            if (String.IsNullOrWhiteSpace(oldObjectName))
+                throw new ArgumentNullException("oldObjectName", "The oldObjectName property can't be empty");
+            if (String.IsNullOrWhiteSpace(newObjectName))
+                throw new ArgumentNullException("newObjectName", "The newObjectName property can't be empty");
+
+            var request = new RestRequest { Path = container + "/" + newObjectName, Method = WebMethod.Put };
+            request.AddHeader("X-Copy-From",String.Format("/{0}/{1}",container,oldObjectName));
+            request.AddPostContent(new byte[]{});
+            var response = _client.Request(request);
+
+            if (response.StatusCode == HttpStatusCode.OK || response.StatusCode == HttpStatusCode.NoContent || response.StatusCode==HttpStatusCode.Created)
+            {
+                this.DeleteObject(container,oldObjectName);
+            }                
+            else
+                throw new WebException(String.Format("MoveObject failed with unexpected status code {0}", response.StatusCode));
+        }
+
+        private string GetHeaderValue(string headerName, RestResponse response, IQueryable<string> keys)
+        {
+            if (keys.Any(key => key == headerName))
+                return response.Headers[headerName];
+            else
+                throw new WebException(String.Format("The {0}  header is missing",headerName));
+        }
+
+        private static void ThrowIfNotStatusOK(RestResponse response, string message)
+        {
+            int status = (int)response.StatusCode;
+            if (status < 200 || status >= 300)
+                throw new WebException(String.Format("{0} with code {1}",message, status));
+        }
+    }
+}
diff --git a/trunk/Pithos.Network/Pithos.Network.csproj b/trunk/Pithos.Network/Pithos.Network.csproj
new file mode 100644 (file)
index 0000000..55ca6d9
--- /dev/null
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{C8E2BC8B-C7F1-4222-855C-4B04A57FFDFD}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Pithos.Network</RootNamespace>
+    <AssemblyName>Pithos.Network</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <CodeContractsAssemblyMode>1</CodeContractsAssemblyMode>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
+    <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
+    <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
+    <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
+    <CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers>
+    <CodeContractsRunCodeAnalysis>True</CodeContractsRunCodeAnalysis>
+    <CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
+    <CodeContractsBoundsObligations>False</CodeContractsBoundsObligations>
+    <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
+    <CodeContractsEnumObligations>False</CodeContractsEnumObligations>
+    <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
+    <CodeContractsRunInBackground>True</CodeContractsRunInBackground>
+    <CodeContractsShowSquigglies>False</CodeContractsShowSquigglies>
+    <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
+    <CodeContractsEmitXMLDocs>False</CodeContractsEmitXMLDocs>
+    <CodeContractsCustomRewriterAssembly />
+    <CodeContractsCustomRewriterClass />
+    <CodeContractsLibPaths />
+    <CodeContractsExtraRewriteOptions />
+    <CodeContractsExtraAnalysisOptions />
+    <CodeContractsBaseLineFile />
+    <CodeContractsCacheAnalysisResults>False</CodeContractsCacheAnalysisResults>
+    <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
+    <CodeContractsReferenceAssembly>Build</CodeContractsReferenceAssembly>
+    <CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Hammock">
+      <HintPath>..\packages\Hammock.1.2.3\lib\net40\Hammock.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.ComponentModel.Composition" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="CloudFilesClient.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="TimeoutRetryCondition.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\Libraries\Json40r2\Source\Src\Newtonsoft.Json\Newtonsoft.Json.csproj">
+      <Project>{A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}</Project>
+      <Name>Newtonsoft.Json</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\Pithos.Interfaces\Pithos.Interfaces.csproj">
+      <Project>{7EEFF32F-CCF8-436A-9E0B-F40434C09AF4}</Project>
+      <Name>Pithos.Interfaces</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
diff --git a/trunk/Pithos.Network/Properties/AssemblyInfo.cs b/trunk/Pithos.Network/Properties/AssemblyInfo.cs
new file mode 100644 (file)
index 0000000..49eb5f4
--- /dev/null
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Pithos.Network")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("Pithos.Network")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("495e23f2-f451-4d24-aa39-961f97144a90")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/trunk/Pithos.Network/TimeoutRetryCondition.cs b/trunk/Pithos.Network/TimeoutRetryCondition.cs
new file mode 100644 (file)
index 0000000..193a6cb
--- /dev/null
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Text;
+using Hammock.Retries;
+
+namespace Pithos.Network
+{
+    class TimeoutRetryCondition:RetryResultCondition
+    {
+        public override Predicate<Hammock.Web.WebQueryResult> RetryIf
+        {
+            get
+            {
+                return r => 
+                    (r.Exception != null && r.Exception is WebException 
+                    && (((WebException)r.Exception).Status == WebExceptionStatus.Timeout));
+            }
+        }
+    }
+}
diff --git a/trunk/Pithos.Network/packages.config b/trunk/Pithos.Network/packages.config
new file mode 100644 (file)
index 0000000..5d5eed2
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="Hammock" version="1.2.3" />
+</packages>
\ No newline at end of file
diff --git a/trunk/Pithos.ShellExtensions.Test/FileContextMenuTest.cs b/trunk/Pithos.ShellExtensions.Test/FileContextMenuTest.cs
new file mode 100644 (file)
index 0000000..fbf5990
--- /dev/null
@@ -0,0 +1,28 @@
+using System;
+using System.ComponentModel.Composition.Hosting;
+using System.Reflection;
+using System.Runtime.InteropServices.ComTypes;
+using NUnit.Framework;
+using Pithos.ShellExtensions.Menus;
+using System.Runtime.InteropServices;
+
+namespace Pithos.ShellExtensions.Test
+{
+    [TestFixture]
+    public class FileContextMenuTest
+    {
+        [SetUp]
+        public void Setup()
+        {
+        }
+
+        [Test]
+        public void TestCreation()
+        {
+            
+            var ctxMenu = new FileContextMenu();
+            ctxMenu.Context.Settings=new TestPithosSettings();
+
+        }
+    }
+}
diff --git a/trunk/Pithos.ShellExtensions.Test/FileContextTest.cs b/trunk/Pithos.ShellExtensions.Test/FileContextTest.cs
new file mode 100644 (file)
index 0000000..48fa0c9
--- /dev/null
@@ -0,0 +1,58 @@
+using NUnit.Framework;
+
+namespace Pithos.ShellExtensions.Test
+{
+    [TestFixture]
+    public class FileContextTest
+    {
+        [Test]
+        public void CheckIsManaged()
+        {
+            var ctx = new FileContext {CurrentFile = @"e:\Pithos\moo.txt"};
+            ctx.Settings=new TestPithosSettings();
+            
+            Assert.IsTrue(ctx.IsManaged);
+            Assert.IsFalse(ctx.IsFolder );
+
+            ctx = new FileContext { CurrentFile = @"e:\Pithos\" };
+            ctx.Settings = new TestPithosSettings();
+            Assert.IsTrue(ctx.IsManaged);
+            Assert.IsTrue(ctx.IsFolder);
+
+            ctx = new FileContext { CurrentFile = @"e:\Pithos" };
+            ctx.Settings = new TestPithosSettings();
+            Assert.IsTrue(ctx.IsManaged);
+            Assert.IsTrue(ctx.IsFolder);
+
+            ctx = new FileContext { CurrentFile = @"e:\pithos" };
+            ctx.Settings = new TestPithosSettings();
+            Assert.IsTrue(ctx.IsManaged);
+            Assert.IsTrue(ctx.IsFolder);
+
+            ctx = new FileContext { CurrentFile = @"e:\Pithos.txt" };
+            ctx.Settings = new TestPithosSettings();
+            Assert.IsTrue(!ctx.IsManaged);
+
+            ctx = new FileContext { CurrentFile = @"e:\Pithos\01New Folder" };
+            ctx.Settings = new TestPithosSettings();
+            Assert.IsTrue(ctx.IsManaged); 
+            Assert.IsTrue(ctx.IsFolder);
+        }
+
+        [Test]
+        public void CheckCurrentFile()
+        {
+            var ctx = new FileContext {CurrentFile = @"e:\Pithos\moo.txt"};
+            ctx.Settings = new TestPithosSettings();
+            Assert.AreEqual(@"e:\pithos", ctx.CurrentFolder);
+            Assert.IsTrue(ctx.IsManaged); 
+            Assert.IsFalse(ctx.IsFolder);
+            
+            ctx = new FileContext { CurrentFile = @"e:\Pithos\01New Folder" };
+            ctx.Settings = new TestPithosSettings();
+            Assert.AreEqual(@"e:\pithos\01new folder", ctx.CurrentFolder);
+            Assert.IsTrue(ctx.IsManaged); 
+            Assert.IsTrue(ctx.IsFolder);
+        }
+    }
+}
diff --git a/trunk/Pithos.ShellExtensions.Test/IconOverlayTest.cs b/trunk/Pithos.ShellExtensions.Test/IconOverlayTest.cs
new file mode 100644 (file)
index 0000000..4093f19
--- /dev/null
@@ -0,0 +1,77 @@
+using System;
+using System.IO;
+using NUnit.Framework;
+using Pithos.ShellExtensions.Overlays;
+
+namespace Pithos.ShellExtensions.Test
+{
+    [TestFixture]
+    public class IconOverlayTest
+    {
+        public const int S_OK = 0x0000;
+        public const int S_FALSE = 0x0001;
+
+        [SetUp]
+        public void Setup()
+        {/*
+            var ioc = IoC.Current;
+            var catalog = new AggregateCatalog();
+            catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
+
+            ioc.Container = new CompositionContainer(catalog);
+*/   
+        }
+
+        [Test]
+        public void CreateOverlayTest()
+        {
+            var normalOverlay=new NormalIconOverlay();
+            
+            Assert.IsFalse(String.IsNullOrWhiteSpace(normalOverlay.IconPath ));
+            Assert.IsFalse(String.IsNullOrWhiteSpace(normalOverlay.OverlayName));
+            Assert.AreEqual("0PithosNormal", normalOverlay.OverlayName);
+
+            var iconPath = @"C:\Program Files\Common Files\TortoiseOverlays\icons\XPStyle\";
+
+            Assert.AreEqual(Path.Combine(iconPath,"NormalIcon.ico"),normalOverlay.IconPath);
+
+            var conflictOverlay = new ConflictIconOverlay();
+            Assert.AreEqual(Path.Combine(iconPath, "ConflictIcon.ico"), conflictOverlay.IconPath);
+
+            var modifiedOverlay = new ModifiedIconOverlay();
+            Assert.AreEqual(Path.Combine(iconPath, "ModifiedIcon.ico"), modifiedOverlay.IconPath);
+
+            var synchOverlay = new SynchIconOverlay();
+            Assert.AreEqual(Path.Combine(iconPath, "SynchIcon.ico"), synchOverlay.IconPath);
+        }
+        
+        [Test]
+        public void TestMembership()
+        {
+            var overlay=new NormalIconOverlay();
+
+            var status = overlay.IsMemberOf(@"e:\pithos\0file.txt", 0);
+            Assert.AreEqual(status,S_OK);
+
+            status = overlay.IsMemberOf(@"e:\Pithos\0file.txt", 0);
+            Assert.AreEqual(status, S_OK,"Failed checking Camel cased folder");
+
+            status = overlay.IsMemberOf(@"e:\Pithos\", 0);
+            Assert.AreEqual(status, S_OK,"Failed checking camel folder with slash");
+
+            status = overlay.IsMemberOf(@"e:\pithos\", 0);
+            Assert.AreEqual(status, S_OK,"Failed lower folder with slash");
+
+            status = overlay.IsMemberOf(@"e:\pithos", 0);
+            Assert.AreEqual(status, S_OK,"Failed lower folder no slash");
+
+            status = overlay.IsMemberOf(@"e:\0file.txt", 0);
+            Assert.AreEqual(status, S_FALSE,"Failed unrelated file");
+
+            status = overlay.IsMemberOf(@"e:\pithos\1file.txt", 0);
+            Assert.AreEqual(status, S_FALSE,"Failed different state file");
+
+        }
+
+    }
+}
diff --git a/trunk/Pithos.ShellExtensions.Test/IoCTest.cs b/trunk/Pithos.ShellExtensions.Test/IoCTest.cs
new file mode 100644 (file)
index 0000000..861c3fd
--- /dev/null
@@ -0,0 +1,23 @@
+using System.Linq;
+using NUnit.Framework;
+
+namespace Pithos.ShellExtensions.Test
+{
+    [TestFixture]
+    public class IoCTest
+    {
+        [Test]
+        public void TestIoCInit()
+        {
+            var ioc = IoC.Current;
+           /* var catalog = new AggregateCatalog();
+            catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
+
+            ioc.Container = new CompositionContainer(catalog);
+*/
+            
+
+            Assert.IsTrue(ioc.Container.Catalog.Parts.Any());
+        }
+    }
+}
diff --git a/trunk/Pithos.ShellExtensions.Test/Pithos.ShellExtensions.Test.csproj b/trunk/Pithos.ShellExtensions.Test/Pithos.ShellExtensions.Test.csproj
new file mode 100644 (file)
index 0000000..9626a0f
--- /dev/null
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{2CFE2DF1-20AE-47E2-B1BB-36B974600BE1}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Pithos.ShellExtensions.Test</RootNamespace>
+    <AssemblyName>Pithos.ShellExtensions.Test</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="nunit.framework, Version=2.5.10.11092, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL" />
+    <Reference Include="System" />
+    <Reference Include="System.ComponentModel.Composition" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="FileContextMenuTest.cs" />
+    <Compile Include="FileContextTest.cs" />
+    <Compile Include="IoCTest.cs" />
+    <Compile Include="IconOverlayTest.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="TestPithosSettings.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <WCFMetadata Include="Service References\" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\Pithos.Interfaces\Pithos.Interfaces.csproj">
+      <Project>{7EEFF32F-CCF8-436A-9E0B-F40434C09AF4}</Project>
+      <Name>Pithos.Interfaces</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\Pithos.ShellExtensions\Pithos.ShellExtensions.csproj">
+      <Project>{240B432F-1030-4623-BCC3-FF351D6C1B63}</Project>
+      <Name>Pithos.ShellExtensions</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
diff --git a/trunk/Pithos.ShellExtensions.Test/Properties/AssemblyInfo.cs b/trunk/Pithos.ShellExtensions.Test/Properties/AssemblyInfo.cs
new file mode 100644 (file)
index 0000000..108732d
--- /dev/null
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Pithos.ShellExtensions.Test")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("Pithos.ShellExtensions.Test")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("3c1311e4-b7aa-476f-9bbe-381c9c68c65d")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/trunk/Pithos.ShellExtensions.Test/TestPithosSettings.cs b/trunk/Pithos.ShellExtensions.Test/TestPithosSettings.cs
new file mode 100644 (file)
index 0000000..43da0e9
--- /dev/null
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition;
+using System.Linq;
+using System.Text;
+using Pithos.Interfaces;
+
+namespace Pithos.ShellExtensions.Test
+{
+    [Export(typeof(IPithosSettings))]
+    class TestPithosSettings:IPithosSettings
+    {
+        public string PithosPath
+        {
+            get { return @"e:\pithos"; }
+            set { throw new NotImplementedException(); }
+        }
+
+        public string IconsPath
+        {
+            get { return @"C:\Program Files\Common Files\TortoiseOverlays\icons\XPStyle\"; }
+            set { throw new NotImplementedException(); }
+        }
+
+        public string UserName { get; set; }
+        public string ApiKey { get; set; }
+
+        public void Save()
+        {
+            
+        }
+
+        public void Reload()
+        {
+            
+        }
+    }
+}
diff --git a/trunk/Pithos.ShellExtensions.Test/TestStatusChecker.cs b/trunk/Pithos.ShellExtensions.Test/TestStatusChecker.cs
new file mode 100644 (file)
index 0000000..f53a457
--- /dev/null
@@ -0,0 +1,34 @@
+using System;
+using System.ComponentModel.Composition;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.IO;
+using Pithos.Interfaces;
+
+namespace Pithos.ShellExtensions
+{
+    [Export(typeof(IStatusChecker))]
+    public class TestStatusChecker:IStatusChecker
+    {
+        [Import]
+        private IPithosSettings Settings;
+
+        private readonly string[] _states = {"Normal", "Modified", "Conflict","Synch"};
+
+        public string GetFileStatus(string path)
+        {
+            Contract.Requires(!String.IsNullOrWhiteSpace(path));
+            var pithosPath = Settings.PithosPath;
+            if (path.StartsWith(pithosPath,true,null))
+            {
+                var fileName = Path.GetFileName(path);
+                if (String.IsNullOrWhiteSpace(fileName))
+                    return _states[0];
+
+                var status = Char.ConvertToUtf32(fileName, 0)%4;
+                return _states[status];
+            }
+            return String.Empty;
+        }
+    }
+}
diff --git a/trunk/Pithos.ShellExtensions/FileContext.cs b/trunk/Pithos.ShellExtensions/FileContext.cs
new file mode 100644 (file)
index 0000000..0450c65
--- /dev/null
@@ -0,0 +1,69 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Text;
+using Pithos.Interfaces;
+
+namespace Pithos.ShellExtensions
+{
+    [Export]
+    public class FileContext
+    {
+        [Import]
+        public IPithosSettings Settings { get; set; }
+
+        [Import]
+        public IStatusChecker StatusChecker { get; set; }
+
+        public string PithosPath { get { return Settings.PithosPath.ToLower(); } }
+
+
+        public bool IsManaged
+        {
+            get
+            {
+                Trace.Write(String.Format("Managed path is {0}\r\n Current Path is {1}", PithosPath, CurrentFile));
+                return CurrentFolder.StartsWith(PithosPath, true, null);
+            }
+        }
+
+        public bool IsFolder { get; set; }
+        private string _currentFolder;
+        public string CurrentFolder
+        {
+            get { return _currentFolder; }
+            set
+            {
+                _currentFolder = value.ToLower();
+                IsFolder = true;
+                _currentFile = _currentFolder;
+            }
+        }
+
+        private string _currentFile;
+        public string CurrentFile
+        {
+            get { return _currentFile; }
+            set
+            {
+                _currentFile = value.ToLower();
+                Trace.Write(String.Format("File is {0}", _currentFile));
+                if (Directory.Exists(_currentFile))
+                {
+                    _currentFolder = _currentFile;
+                    IsFolder = true;
+                }
+                else
+                {
+                    _currentFolder = Path.GetDirectoryName(_currentFile);
+                    IsFolder = false;
+                }
+
+            }
+        }
+    }
+
+}
diff --git a/trunk/Pithos.ShellExtensions/IoC.cs b/trunk/Pithos.ShellExtensions/IoC.cs
new file mode 100644 (file)
index 0000000..280555f
--- /dev/null
@@ -0,0 +1,44 @@
+using System;
+using System.ComponentModel.Composition.Hosting;
+using System.Diagnostics;
+using System.Reflection;
+using System.ComponentModel.Composition;
+
+namespace Pithos.ShellExtensions
+{
+    public class IoC
+    {
+        public CompositionContainer Container;
+        
+        static readonly Lazy<IoC> Instance=new Lazy<IoC>();
+
+        public static IoC Current
+        {
+            get { return Instance.Value; }
+        }
+
+        public IoC()
+        {
+            var catalog = new AggregateCatalog();
+            catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));            
+            
+            Container=new CompositionContainer(catalog);
+        }
+        
+
+
+        public T Compose<T>(T target)
+        {
+            try
+            {
+                Container.ComposeParts(target);
+                return target;
+            }
+            catch (Exception exc)
+            {
+                Trace.TraceError(exc.ToString());
+                throw;
+            }
+        }
+    }
+}
diff --git a/trunk/Pithos.ShellExtensions/MarshalHelpers.cs b/trunk/Pithos.ShellExtensions/MarshalHelpers.cs
new file mode 100644 (file)
index 0000000..93897c1
--- /dev/null
@@ -0,0 +1,30 @@
+using System;
+using System.Diagnostics.Contracts;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace Pithos.ShellExtensions
+{
+    public static class MarshalHelpers
+    {
+        
+        public static void CopyToBuffer(string input, IntPtr buffer, int bufferSize)
+        {        
+            Contract.Requires(buffer != IntPtr.Zero);
+            Contract.Requires(bufferSize >=0 );
+            
+            var bytes = Encoding.Unicode.GetBytes(input);
+            
+            if (bytes.Length + 2 >= bufferSize) 
+                return;
+
+            for (var i = 0; i < bytes.Length; i++)
+            {
+                Marshal.WriteByte(buffer, i, bytes[i]);
+            }
+            //write the null terminator "\0\0" 
+            Marshal.WriteByte(buffer, bytes.Length, 0);
+            Marshal.WriteByte(buffer, bytes.Length + 1, 0);
+        }
+    }
+}
diff --git a/trunk/Pithos.ShellExtensions/Menus/DisplayFlags.cs b/trunk/Pithos.ShellExtensions/Menus/DisplayFlags.cs
new file mode 100644 (file)
index 0000000..6702375
--- /dev/null
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Pithos.ShellExtensions.Menus
+{
+    [Flags]
+    enum DisplayFlags
+    {
+        None,
+        Folder,
+        File,
+        All
+    }
+
+}
diff --git a/trunk/Pithos.ShellExtensions/Menus/FileContextMenu.cs b/trunk/Pithos.ShellExtensions/Menus/FileContextMenu.cs
new file mode 100644 (file)
index 0000000..e7bd4b8
--- /dev/null
@@ -0,0 +1,506 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Runtime.InteropServices.ComTypes;
+using System.Text;
+
+namespace Pithos.ShellExtensions.Menus
+{
+    [ClassInterface(ClassInterfaceType.None)]
+    [Guid("B1F1405D-94A1-4692-B72F-FC8CAF8B8700"), ComVisible(true)]
+    public class FileContextMenu : IShellExtInit, IContextMenu
+    {
+        private const string MenuHandlername = "CSShellExtContextMenuHandler.FileContextMenuExt";
+
+
+        private readonly Dictionary<string, MenuItem> _items;
+
+
+        private FileContext _context =new FileContext();
+        public FileContext Context
+        {
+            get { return _context; }
+            set { _context = value; }
+        }
+
+        public FileContextMenu()
+        {
+            _items = new Dictionary<string, MenuItem>{
+                {"gotoPithos",new MenuItem{
+                                           MenuText = "&Go to Pithos",
+                                            Verb = "gotoPithos",
+                                             VerbCanonicalName = "PITHOSGoTo",
+                                              VerbHelpText = "Go to Pithos",
+                                               MenuDisplayId = 0,
+                                               MenuCommand=OnVerbDisplayFileName,
+                                               DisplayFlags=DisplayFlags.All
+                                           }},
+                {"prevVersions",new MenuItem{
+                                           MenuText = "&Show Previous Versions",
+                                            Verb = "prevVersions",
+                                             VerbCanonicalName = "PITHOSPrevVersions",
+                                              VerbHelpText = "Go to Pithos and display previous versions",
+                                               MenuDisplayId = 1,
+                                               MenuCommand=OnVerbDisplayFileName,
+                                               DisplayFlags=DisplayFlags.File
+                                           }}
+            };
+
+            
+        }
+
+
+        void OnVerbDisplayFileName(IntPtr hWnd)
+        {
+            string message = String.Format("The selected file is {0}\r\n\r\nThe selected Path is {1}",
+                                           Context.CurrentFile,
+                                           Context.CurrentFolder);
+
+            System.Windows.Forms.MessageBox.Show(
+                message,
+                "CSShellExtContextMenuHandler");
+            NativeMethods.SHChangeNotify(HChangeNotifyEventID.SHCNE_ASSOCCHANGED, HChangeNotifyFlags.SHCNF_IDLIST,
+                                             IntPtr.Zero, IntPtr.Zero);
+        }
+        
+
+        #region Shell Extension Registration
+
+        [ComRegisterFunction]
+        public static void Register(Type t)
+        {
+            try
+            {
+                ShellExtReg.RegisterShellExtContextMenuHandler(t.GUID, ".cs",
+                    MenuHandlername);
+                ShellExtReg.RegisterShellExtContextMenuHandler(t.GUID, "Directory",
+                    MenuHandlername);
+                ShellExtReg.RegisterShellExtContextMenuHandler(t.GUID, @"Directory\Background",
+                    MenuHandlername);
+                ShellExtReg.RegisterShellExtContextMenuHandler(t.GUID, "*",
+                    MenuHandlername);
+
+                //ShellExtReg.MarkApproved(t.GUID, MenuHandlername);
+            }
+            catch (Exception ex)
+            {
+                Console.WriteLine(ex.Message); // Log the error
+                throw;  // Re-throw the exception
+            }
+        }
+
+        [ComUnregisterFunction]
+        public static void Unregister(Type t)
+        {
+            try
+            {
+                ShellExtReg.UnregisterShellExtContextMenuHandler(t.GUID, ".cs", MenuHandlername);
+                ShellExtReg.UnregisterShellExtContextMenuHandler(t.GUID, "Directory", MenuHandlername);
+                ShellExtReg.UnregisterShellExtContextMenuHandler(t.GUID, @"Directory\Background", MenuHandlername);
+                ShellExtReg.UnregisterShellExtContextMenuHandler(t.GUID, "*", MenuHandlername);
+
+                //ShellExtReg.RemoveApproved(t.GUID, MenuHandlername);
+            }
+            catch (Exception ex)
+            {
+                Console.WriteLine(ex.Message); // Log the error
+                throw;  // Re-throw the exception
+            }
+        }
+
+        #endregion
+
+
+        #region IShellExtInit Members
+
+        /// <summary>
+        /// Initialize the context menu handler.
+        /// </summary>
+        /// <param name="pidlFolder">
+        /// A pointer to an ITEMIDLIST structure that uniquely identifies a folder.
+        /// </param>
+        /// <param name="pDataObj">
+        /// A pointer to an IDataObject interface object that can be used to retrieve 
+        /// the objects being acted upon.
+        /// </param>
+        /// <param name="hKeyProgID">
+        /// The registry key for the file object or folder type.
+        /// </param>
+        public void Initialize(IntPtr pidlFolder, IntPtr pDataObj, IntPtr hKeyProgID)
+        {
+            
+            if(pDataObj == IntPtr.Zero && pidlFolder == IntPtr.Zero)
+            {
+                throw new ArgumentException("pidlFolder and pDataObj shouldn't be null at the same time");
+            }
+
+
+            Trace.Write("Initializing");
+
+            if (pDataObj != IntPtr.Zero)
+            {
+                Trace.Write("Got a data object");
+
+                FORMATETC fe = new FORMATETC();
+                fe.cfFormat = (short)CLIPFORMAT.CF_HDROP;
+                fe.ptd = IntPtr.Zero;
+                fe.dwAspect = DVASPECT.DVASPECT_CONTENT;
+                fe.lindex = -1;
+                fe.tymed = TYMED.TYMED_HGLOBAL;
+                STGMEDIUM stm = new STGMEDIUM();
+
+                // The pDataObj pointer contains the objects being acted upon. In this 
+                // example, we get an HDROP handle for enumerating the selected files 
+                // and folders.
+                IDataObject dataObject = (IDataObject)Marshal.GetObjectForIUnknown(pDataObj);
+                dataObject.GetData(ref fe, out stm);
+
+                try
+                {
+                    // Get an HDROP handle.
+                    IntPtr hDrop = stm.unionmember;
+                    if (hDrop == IntPtr.Zero)
+                    {
+                        throw new ArgumentException();
+                    }
+
+                    // Determine how many files are involved in this operation.
+                    uint nFiles = NativeMethods.DragQueryFile(hDrop, UInt32.MaxValue, null, 0);
+
+                    Trace.Write(String.Format("Got {0} files", nFiles));
+                    // This code sample displays the custom context menu item when only 
+                    // one file is selected. 
+                    if (nFiles == 1)
+                    {
+                        // Get the path of the file.
+                        var fileName = new StringBuilder(260);
+                        if (0 == NativeMethods.DragQueryFile(hDrop, 0, fileName,
+                                                             fileName.Capacity))
+                        {
+                            Marshal.ThrowExceptionForHR(WinError.E_FAIL);
+                        }
+                        Context.CurrentFile = fileName.ToString();
+                    }
+                    /* else
+                     {
+                         Marshal.ThrowExceptionForHR(WinError.E_FAIL);
+                     }*/
+
+                    // [-or-]
+
+                    // Enumerate the selected files and folders.
+                    //if (nFiles > 0)
+                    //{
+                    //    StringCollection selectedFiles = new StringCollection();
+                    //    StringBuilder fileName = new StringBuilder(260);
+                    //    for (uint i = 0; i < nFiles; i++)
+                    //    {
+                    //        // Get the next file name.
+                    //        if (0 != NativeMethods.DragQueryFile(hDrop, i, fileName,
+                    //            fileName.Capacity))
+                    //        {
+                    //            // Add the file name to the list.
+                    //            selectedFiles.Add(fileName.ToString());
+                    //        }
+                    //    }
+                    //
+                    //    // If we did not find any files we can work with, throw 
+                    //    // exception.
+                    //    if (selectedFiles.Count == 0)
+                    //    {
+                    //        Marshal.ThrowExceptionForHR(WinError.E_FAIL);
+                    //    }
+                    //}
+                    //else
+                    //{
+                    //    Marshal.ThrowExceptionForHR(WinError.E_FAIL);
+                    //}
+                }
+                finally
+                {
+                    NativeMethods.ReleaseStgMedium(ref stm);
+                }
+            }
+
+            if (pidlFolder != IntPtr.Zero)
+            {
+                Trace.Write("Got a folder");
+                StringBuilder path = new StringBuilder();
+                if (!NativeMethods.SHGetPathFromIDList(pidlFolder, path))
+                {
+                    int error = Marshal.GetHRForLastWin32Error();
+                    Marshal.ThrowExceptionForHR(error);
+                }
+                Context.CurrentFolder = path.ToString();
+                Trace.Write(String.Format("Folder is {0}", Context.CurrentFolder));
+            }
+        }
+
+        #endregion
+
+
+        #region IContextMenu Members
+
+        /// <summary>
+        /// Add commands to a shortcut menu.
+        /// </summary>
+        /// <param name="hMenu">A handle to the shortcut menu.</param>
+        /// <param name="iMenu">
+        /// The zero-based position at which to insert the first new menu item.
+        /// </param>
+        /// <param name="idCmdFirst">
+        /// The minimum value that the handler can specify for a menu item ID.
+        /// </param>
+        /// <param name="idCmdLast">
+        /// The maximum value that the handler can specify for a menu item ID.
+        /// </param>
+        /// <param name="uFlags">
+        /// Optional flags that specify how the shortcut menu can be changed.
+        /// </param>
+        /// <returns>
+        /// If successful, returns an HRESULT value that has its severity value set 
+        /// to SEVERITY_SUCCESS and its code value set to the offset of the largest 
+        /// command identifier that was assigned, plus one.
+        /// </returns>
+        public int QueryContextMenu(
+            IntPtr hMenu,
+            uint iMenu,
+            uint idCmdFirst,
+            uint idCmdLast,
+            uint uFlags)
+        {
+            Trace.Write("Start qcm");
+            // If uFlags include CMF_DEFAULTONLY then we should not do anything.
+            Trace.Write(String.Format("Flags {0}", uFlags));
+
+            if (((uint)CMF.CMF_DEFAULTONLY & uFlags) != 0)
+            {
+                Trace.Write("Default only flag, returning");
+                return WinError.MAKE_HRESULT(WinError.SEVERITY_SUCCESS, 0, 0);
+            }
+
+            if (!Context.IsManaged)
+            {
+                Trace.Write("Not a PITHOS folder");
+                return WinError.MAKE_HRESULT(WinError.SEVERITY_SUCCESS, 0, 0);
+            }
+
+            /*
+                        if (!selectedFolder.ToLower().Contains("pithos"))
+                            return WinError.MAKE_HRESULT(WinError.SEVERITY_SUCCESS, 0, 0);
+            */
+
+            // Use either InsertMenu or InsertMenuItem to add menu items.
+
+            uint largestID = 0;
+
+            DisplayFlags itemType = (Context.IsFolder) ? DisplayFlags.Folder : DisplayFlags.File;
+
+            Trace.Write(String.Format("Item Flags {0}", itemType));
+
+            foreach (var menuItem in _items.Values)
+            {
+                Trace.Write(String.Format("Menu Flags {0}", menuItem.DisplayFlags));
+                if ((itemType & menuItem.DisplayFlags) != DisplayFlags.None)
+                {
+                    Trace.Write("Adding Menu");
+
+                    MENUITEMINFO mii = menuItem.CreateInfo(idCmdFirst);
+                    if (!NativeMethods.InsertMenuItem(hMenu, iMenu, true, ref mii))
+                    {
+                        return Marshal.GetHRForLastWin32Error();
+                    }
+                    if (largestID < menuItem.MenuDisplayId)
+                        largestID = menuItem.MenuDisplayId;
+                }
+            }
+
+            Trace.Write("Adding Separator 1");
+            // Add a separator.
+            MENUITEMINFO sep = new MENUITEMINFO();
+            sep.cbSize = (uint)Marshal.SizeOf(sep);
+            sep.fMask = MIIM.MIIM_TYPE;
+            sep.fType = MFT.MFT_SEPARATOR;
+            if (!NativeMethods.InsertMenuItem(hMenu, iMenu, true, ref sep))
+            {
+                Trace.TraceError("Error adding separator 1\r\n{0}", Marshal.GetLastWin32Error());
+                return Marshal.GetHRForLastWin32Error();
+            }
+
+
+
+
+            Trace.Write("Menus added");
+            // Return an HRESULT value with the severity set to SEVERITY_SUCCESS. 
+            // Set the code value to the offset of the largest command identifier 
+            // that was assigned, plus one (1).
+            return WinError.MAKE_HRESULT(WinError.SEVERITY_SUCCESS, 0,
+                largestID + 1);
+        }
+
+        /// <summary>
+        /// Carry out the command associated with a shortcut menu item.
+        /// </summary>
+        /// <param name="pici">
+        /// A pointer to a CMINVOKECOMMANDINFO or CMINVOKECOMMANDINFOEX structure 
+        /// containing information about the command. 
+        /// </param>
+        public void InvokeCommand(IntPtr pici)
+        {
+            bool isUnicode = false;
+
+            // Determine which structure is being passed in, CMINVOKECOMMANDINFO or 
+            // CMINVOKECOMMANDINFOEX based on the cbSize member of lpcmi. Although 
+            // the lpcmi parameter is declared in Shlobj.h as a CMINVOKECOMMANDINFO 
+            // structure, in practice it often points to a CMINVOKECOMMANDINFOEX 
+            // structure. This struct is an extended version of CMINVOKECOMMANDINFO 
+            // and has additional members that allow Unicode strings to be passed.
+            CMINVOKECOMMANDINFO ici = (CMINVOKECOMMANDINFO)Marshal.PtrToStructure(
+                pici, typeof(CMINVOKECOMMANDINFO));
+            CMINVOKECOMMANDINFOEX iciex = new CMINVOKECOMMANDINFOEX();
+            if (ici.cbSize == Marshal.SizeOf(typeof(CMINVOKECOMMANDINFOEX)))
+            {
+                if ((ici.fMask & CMIC.CMIC_MASK_UNICODE) != 0)
+                {
+                    isUnicode = true;
+                    iciex = (CMINVOKECOMMANDINFOEX)Marshal.PtrToStructure(pici,
+                        typeof(CMINVOKECOMMANDINFOEX));
+                }
+            }
+
+            // Determines whether the command is identified by its offset or verb.
+            // There are two ways to identify commands:
+            // 
+            //   1) The command's verb string 
+            //   2) The command's identifier offset
+            // 
+            // If the high-order word of lpcmi->lpVerb (for the ANSI case) or 
+            // lpcmi->lpVerbW (for the Unicode case) is nonzero, lpVerb or lpVerbW 
+            // holds a verb string. If the high-order word is zero, the command 
+            // offset is in the low-order word of lpcmi->lpVerb.
+
+            // For the ANSI case, if the high-order word is not zero, the command's 
+            // verb string is in lpcmi->lpVerb. 
+            if (!isUnicode && NativeMethods.HighWord(ici.verb.ToInt32()) != 0)
+            {
+                // Is the verb supported by this context menu extension?
+                string verbAnsi = Marshal.PtrToStringAnsi(ici.verb);
+                if (_items.ContainsKey(verbAnsi))
+                {
+                    _items[verbAnsi].MenuCommand(ici.hwnd);
+                }
+                else
+                {
+                    // If the verb is not recognized by the context menu handler, it 
+                    // must return E_FAIL to allow it to be passed on to the other 
+                    // context menu handlers that might implement that verb.
+                    Marshal.ThrowExceptionForHR(WinError.E_FAIL);
+                }
+            }
+
+                // For the Unicode case, if the high-order word is not zero, the 
+            // command's verb string is in lpcmi->lpVerbW. 
+            else if (isUnicode && NativeMethods.HighWord(iciex.verbW.ToInt32()) != 0)
+            {
+                // Is the verb supported by this context menu extension?
+                string verbUTF = Marshal.PtrToStringUni(iciex.verbW);
+                if (_items.ContainsKey(verbUTF))
+                {
+                    _items[verbUTF].MenuCommand(ici.hwnd);
+                }
+                else
+                {
+                    // If the verb is not recognized by the context menu handler, it 
+                    // must return E_FAIL to allow it to be passed on to the other 
+                    // context menu handlers that might implement that verb.
+                    Marshal.ThrowExceptionForHR(WinError.E_FAIL);
+                }
+            }
+
+                // If the command cannot be identified through the verb string, then 
+            // check the identifier offset.
+            else
+            {
+                // Is the command identifier offset supported by this context menu 
+                // extension?
+                int menuID = NativeMethods.LowWord(ici.verb.ToInt32());
+                var menuItem = _items.FirstOrDefault(item => item.Value.MenuDisplayId == menuID).Value;
+                if (menuItem != null)
+                {
+                    menuItem.MenuCommand(ici.hwnd);
+                }
+                else
+                {
+                    // If the verb is not recognized by the context menu handler, it 
+                    // must return E_FAIL to allow it to be passed on to the other 
+                    // context menu handlers that might implement that verb.
+                    Marshal.ThrowExceptionForHR(WinError.E_FAIL);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Get information about a shortcut menu command, including the help string 
+        /// and the language-independent, or canonical, name for the command.
+        /// </summary>
+        /// <param name="idCmd">Menu command identifier offset.</param>
+        /// <param name="uFlags">
+        /// Flags specifying the information to return. This parameter can have one 
+        /// of the following values: GCS_HELPTEXTA, GCS_HELPTEXTW, GCS_VALIDATEA, 
+        /// GCS_VALIDATEW, GCS_VERBA, GCS_VERBW.
+        /// </param>
+        /// <param name="pReserved">Reserved. Must be IntPtr.Zero</param>
+        /// <param name="pszName">
+        /// The address of the buffer to receive the null-terminated string being 
+        /// retrieved.
+        /// </param>
+        /// <param name="cchMax">
+        /// Size of the buffer, in characters, to receive the null-terminated string.
+        /// </param>
+        public void GetCommandString(
+            UIntPtr idCmd,
+            uint uFlags,
+            IntPtr pReserved,
+            StringBuilder pszName,
+            uint cchMax)
+        {
+            uint menuID = idCmd.ToUInt32();
+            var menuItem = _items.FirstOrDefault(item => item.Value.MenuDisplayId == menuID).Value;
+            if (menuItem != null)
+            {
+                switch ((GCS)uFlags)
+                {
+                    case GCS.GCS_VERBW:
+                        if (menuItem.VerbCanonicalName.Length > cchMax - 1)
+                        {
+                            Marshal.ThrowExceptionForHR(WinError.STRSAFE_E_INSUFFICIENT_BUFFER);
+                        }
+                        else
+                        {
+                            pszName.Clear();
+                            pszName.Append(menuItem.VerbCanonicalName);
+                        }
+                        break;
+
+                    case GCS.GCS_HELPTEXTW:
+                        if (menuItem.VerbHelpText.Length > cchMax - 1)
+                        {
+                            Marshal.ThrowExceptionForHR(WinError.STRSAFE_E_INSUFFICIENT_BUFFER);
+                        }
+                        else
+                        {
+                            pszName.Clear();
+                            pszName.Append(menuItem.VerbHelpText);
+                        }
+                        break;
+                }
+            }
+        }
+
+        #endregion
+    }
+}
diff --git a/trunk/Pithos.ShellExtensions/Menus/MenuItem.cs b/trunk/Pithos.ShellExtensions/Menus/MenuItem.cs
new file mode 100644 (file)
index 0000000..f442de8
--- /dev/null
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace Pithos.ShellExtensions.Menus
+{
+    internal class MenuItem
+    {
+        public string MenuText { get; set; }
+        public string Verb { get; set; }
+        public string VerbCanonicalName { get; set; }
+        public string VerbHelpText { get; set; }
+        public uint MenuDisplayId { get; set; }
+        public Action<IntPtr> MenuCommand { get; set; }
+        public DisplayFlags DisplayFlags { get; set; }
+
+        public MENUITEMINFO CreateInfo(uint idCmdFirst)
+        {
+            var mii = new MENUITEMINFO();
+            mii.cbSize = (uint)Marshal.SizeOf(mii);
+            mii.fMask = MIIM.MIIM_ID | MIIM.MIIM_TYPE | MIIM.MIIM_STATE;
+            mii.wID = idCmdFirst + MenuDisplayId;
+            mii.fType = MFT.MFT_STRING;
+            mii.dwTypeData = MenuText;
+            mii.fState = MFS.MFS_ENABLED;
+            return mii;
+        }
+    }
+}
diff --git a/trunk/Pithos.ShellExtensions/Overlays/ConflictIconOverlay.cs b/trunk/Pithos.ShellExtensions/Overlays/ConflictIconOverlay.cs
new file mode 100644 (file)
index 0000000..89357ef
--- /dev/null
@@ -0,0 +1,36 @@
+using System;
+using System.Runtime.InteropServices;
+
+
+namespace Pithos.ShellExtensions.Overlays
+{
+    [ClassInterface(ClassInterfaceType.None), ComVisible(true)]
+    [Guid("3EFA16FC-C6B6-4673-BFEC-BD9518F1EFCE")]
+    public class ConflictIconOverlay: IconOverlayBase
+    {
+
+        private static string _iconName = "Conflict";
+
+        public ConflictIconOverlay():base(_iconName)
+        {
+            
+        }
+
+        #region Shell Extension Registration
+        [ComRegisterFunction()]
+        public static void Register(Type t)
+        {
+            RegisterOverlay(t,_iconName);
+        }
+
+        [ComUnregisterFunction]
+        public static void Unregister(Type t)
+        {
+            UnregisterOverlay(t,_iconName);
+        }
+
+        #endregion
+
+
+    }
+}
\ No newline at end of file
diff --git a/trunk/Pithos.ShellExtensions/Overlays/IconOverlayBase.cs b/trunk/Pithos.ShellExtensions/Overlays/IconOverlayBase.cs
new file mode 100644 (file)
index 0000000..56dd321
--- /dev/null
@@ -0,0 +1,126 @@
+using System;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.IO;
+
+using System.ComponentModel.Composition;
+using Pithos.Interfaces;
+
+namespace Pithos.ShellExtensions.Overlays
+{
+
+    public class IconOverlayBase : IShellIconOverlayIdentifier
+    {
+        protected static string PithosPrefix = "0Pithos";
+
+        public string OverlayName { get; private set; }
+        public string IconPath { get; private set; }
+
+        [Import(typeof (IStatusChecker))] 
+        public IStatusChecker StatusChecker;
+        [Import(typeof (IPithosSettings))] 
+        public IPithosSettings Settings;
+
+
+
+        public IconOverlayBase(string iconName)
+        {
+            Trace.Write("Icon Overlay Instance created");
+            IoC.Current.Compose(this);
+            
+
+            string overlayName=PithosPrefix + iconName;
+            string iconFile = iconName + "Icon.ico";
+
+
+            var iconsFolder = Settings.IconsPath;
+            var fullPath = Path.Combine(iconsFolder, iconFile);
+
+            OverlayName = overlayName;
+            IconPath = fullPath;
+
+            
+        }
+
+
+        public int IsMemberOf(string path, uint attributes)
+        {
+            if (String.IsNullOrWhiteSpace(path))
+                throw new ArgumentNullException("Empty path");
+
+            Trace.Write(String.Format("ICON Status check for {0} - {1}",path,GetType().Name));
+            
+            if (!path.StartsWith(Settings.PithosPath,true,null))
+                return WinError.S_FALSE;
+
+            var status=StatusChecker.GetFileOverlayStatus(path);
+            var isMember = (PithosPrefix + status == OverlayName);
+            Trace.Write(String.Format("Status check for {0} is {1}",path,isMember));
+            return isMember ? WinError.S_OK : WinError.S_FALSE;
+        }
+
+        public int GetOverlayInfo(
+            IntPtr iconFileBuffer,
+            int iconFileBufferSize,
+            out int iconIndex,
+            out uint flags)
+        {
+            Trace.Write("Looking for icons");
+
+            Trace.WriteLine(string.Format("ICON file {0}", IconPath));
+            
+            int bytesCount = System.Text.Encoding.Unicode.GetByteCount(IconPath);
+
+            Trace.WriteLine(string.Format(" GetOverlayInfo::{0}",bytesCount));
+
+            MarshalHelpers.CopyToBuffer(IconPath, iconFileBuffer, iconFileBufferSize);
+
+            flags = (uint)(ISIOI.ISIOI_ICONFILE);// | ISIOI.ISIOI_ICONINDEX);
+            iconIndex = 0;
+            return WinError.S_OK;
+        }
+
+        public int  GetPriority(out int priority)
+        {
+            Trace.Write("Checking for priority");
+            priority = 0;
+            return WinError.S_OK;
+        }
+
+        
+        public static void RegisterOverlay(Type t,string iconName)
+        {
+            try
+            {
+                string overlayName = PithosPrefix + iconName;
+                ShellExtReg.RegisterIconOverlayIdentifier(t.GUID, overlayName);
+
+                NativeMethods.SHChangeNotify(HChangeNotifyEventID.SHCNE_ASSOCCHANGED, HChangeNotifyFlags.SHCNF_IDLIST,
+                                             IntPtr.Zero, IntPtr.Zero);
+                Trace.Write("Registered icon handler");
+            }
+            catch (Exception ex)
+            {
+                Trace.WriteLine(ex.Message); // Log the error
+                throw;  // Re-throw the exception
+            }
+        }
+
+        
+        public static void UnregisterOverlay(Type t,string iconName)
+        {
+            try
+            {
+                string overlayName = PithosPrefix + iconName;
+                ShellExtReg.UnregisterIconOverlayIdentifier(t.GUID, overlayName);
+                Trace.Write("UnRegistered icon handler");
+            }
+            catch (Exception ex)
+            {
+                Trace.WriteLine(ex.Message); // Log the error
+                throw;  // Re-throw the exception
+            }
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/trunk/Pithos.ShellExtensions/Overlays/ModifiedIconOverlay.cs b/trunk/Pithos.ShellExtensions/Overlays/ModifiedIconOverlay.cs
new file mode 100644 (file)
index 0000000..4646b82
--- /dev/null
@@ -0,0 +1,35 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Pithos.ShellExtensions.Overlays
+{
+    [ClassInterface(ClassInterfaceType.None), ComVisible(true)]
+    [Guid("3D05BCB0-733B-49CD-B340-9D79C17C73CC")]
+    public class ModifiedIconOverlay: IconOverlayBase
+    {
+
+        private static string _iconName = "Modified";
+
+        public ModifiedIconOverlay():base(_iconName)
+        {
+            
+        }
+
+        #region Shell Extension Registration
+        [ComRegisterFunction()]
+        public static void Register(Type t)
+        {
+            RegisterOverlay(t,_iconName);
+        }
+
+        [ComUnregisterFunction]
+        public static void Unregister(Type t)
+        {
+            UnregisterOverlay(t,_iconName);
+        }
+
+        #endregion
+
+
+    }
+}
\ No newline at end of file
diff --git a/trunk/Pithos.ShellExtensions/Overlays/NormalIconOverlay.cs b/trunk/Pithos.ShellExtensions/Overlays/NormalIconOverlay.cs
new file mode 100644 (file)
index 0000000..57bdf21
--- /dev/null
@@ -0,0 +1,35 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Pithos.ShellExtensions.Overlays
+{
+    [ClassInterface(ClassInterfaceType.None)]
+    [Guid("1941D8CA-2727-491B-BC03-9E8CA4FE972B"), ComVisible(true)]
+    public class NormalIconOverlay: IconOverlayBase
+    {
+
+        private static string _iconName = "Normal";
+
+        public NormalIconOverlay():base(_iconName)
+        {
+            
+        }
+
+        #region Shell Extension Registration
+        [ComRegisterFunction()]
+        public static void Register(Type t)
+        {
+            RegisterOverlay(t,_iconName);
+        }
+
+        [ComUnregisterFunction]
+        public static void Unregister(Type t)
+        {
+            UnregisterOverlay(t,_iconName);
+        }
+
+        #endregion
+
+
+    }
+}
diff --git a/trunk/Pithos.ShellExtensions/Overlays/SynchIconOverlay.cs b/trunk/Pithos.ShellExtensions/Overlays/SynchIconOverlay.cs
new file mode 100644 (file)
index 0000000..04cea45
--- /dev/null
@@ -0,0 +1,35 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Pithos.ShellExtensions.Overlays
+{
+    [ClassInterface(ClassInterfaceType.None), ComVisible(true)]
+    [Guid("20FCF62D-E553-48FA-99B8-6C0A4E1C5D55")]
+    public class SynchIconOverlay: IconOverlayBase
+    {
+
+        private static string _iconName = "Synch";
+
+        public SynchIconOverlay():base(_iconName)
+        {
+            
+        }
+
+        #region Shell Extension Registration
+        [ComRegisterFunction()]
+        public static void Register(Type t)
+        {
+            RegisterOverlay(t,_iconName);
+        }
+
+        [ComUnregisterFunction]
+        public static void Unregister(Type t)
+        {
+            UnregisterOverlay(t,_iconName);
+        }
+
+        #endregion
+
+
+    }
+}
\ No newline at end of file
diff --git a/trunk/Pithos.ShellExtensions/Pithos.ShellExtensions.csproj b/trunk/Pithos.ShellExtensions/Pithos.ShellExtensions.csproj
new file mode 100644 (file)
index 0000000..09e9787
--- /dev/null
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{240B432F-1030-4623-BCC3-FF351D6C1B63}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Pithos.ShellExtensions</RootNamespace>
+    <AssemblyName>Pithos.ShellExtensions</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <CodeContractsAssemblyMode>1</CodeContractsAssemblyMode>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <RegisterForComInterop>true</RegisterForComInterop>
+    <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
+    <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
+    <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
+    <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
+    <CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers>
+    <CodeContractsRunCodeAnalysis>True</CodeContractsRunCodeAnalysis>
+    <CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
+    <CodeContractsBoundsObligations>False</CodeContractsBoundsObligations>
+    <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
+    <CodeContractsEnumObligations>False</CodeContractsEnumObligations>
+    <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
+    <CodeContractsRunInBackground>True</CodeContractsRunInBackground>
+    <CodeContractsShowSquigglies>False</CodeContractsShowSquigglies>
+    <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
+    <CodeContractsEmitXMLDocs>True</CodeContractsEmitXMLDocs>
+    <CodeContractsCustomRewriterAssembly />
+    <CodeContractsCustomRewriterClass />
+    <CodeContractsLibPaths />
+    <CodeContractsExtraRewriteOptions />
+    <CodeContractsExtraAnalysisOptions />
+    <CodeContractsBaseLineFile />
+    <CodeContractsCacheAnalysisResults>False</CodeContractsCacheAnalysisResults>
+    <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
+    <CodeContractsReferenceAssembly>Build</CodeContractsReferenceAssembly>
+    <CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup>
+    <SignAssembly>true</SignAssembly>
+  </PropertyGroup>
+  <PropertyGroup>
+    <AssemblyOriginatorKeyFile>pithos.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.ComponentModel.Composition" />
+    <Reference Include="System.Configuration.Install" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="FileContext.cs" />
+    <Compile Include="IoC.cs" />
+    <Compile Include="MarshalHelpers.cs" />
+    <Compile Include="Menus\DisplayFlags.cs" />
+    <Compile Include="Menus\FileContextMenu.cs" />
+    <Compile Include="Menus\MenuItem.cs" />
+    <Compile Include="Overlays\ConflictIconOverlay.cs" />
+    <Compile Include="Overlays\IconOverlayBase.cs" />
+    <Compile Include="Overlays\ModifiedIconOverlay.cs" />
+    <Compile Include="Overlays\NormalIconOverlay.cs" />
+    <Compile Include="Overlays\SynchIconOverlay.cs" />
+    <Compile Include="ProjectInstaller.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="ProjectInstaller.designer.cs">
+      <DependentUpon>ProjectInstaller.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="ShellExtLib.cs" />
+    <Compile Include="TestPithosSettings.cs" />
+    <Compile Include="TestStatusChecker.cs" />
+  </ItemGroup>
+  <ItemGroup />
+  <ItemGroup>
+    <None Include="app.config" />
+    <None Include="pithos.snk" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\Pithos.Interfaces\Pithos.Interfaces.csproj">
+      <Project>{7EEFF32F-CCF8-436A-9E0B-F40434C09AF4}</Project>
+      <Name>Pithos.Interfaces</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
diff --git a/trunk/Pithos.ShellExtensions/ProjectInstaller.cs b/trunk/Pithos.ShellExtensions/ProjectInstaller.cs
new file mode 100644 (file)
index 0000000..e538286
--- /dev/null
@@ -0,0 +1,60 @@
+/********************************** Module Header **********************************\
+Module Name:  ProjectInstaller.cs
+Project:      CSShellExtContextMenuHandler
+Copyright (c) Microsoft Corporation.
+
+The installer class defines the custom actions in the setup. We use the custom 
+actions to register and unregister the COM-visible classes in the current managed 
+assembly.
+
+This source is subject to the Microsoft Public License.
+See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
+All other rights reserved.
+
+THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER 
+EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF 
+MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
+\***********************************************************************************/
+
+#region Using directives
+
+using System.Collections;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
+
+#endregion
+
+
+namespace Pithos.ShellExtensions
+{
+    [RunInstaller(true), ComVisible(false)]
+    public partial class ProjectInstaller : System.Configuration.Install.Installer
+    {
+        public ProjectInstaller()
+        {
+            InitializeComponent();
+        }
+
+        public override void Install(IDictionary stateSaver)
+        {
+            base.Install(stateSaver);
+
+            // Call RegistrationServices.RegisterAssembly to register the classes in 
+            // the current managed assembly to enable creation from COM.
+            RegistrationServices regService = new RegistrationServices();
+            regService.RegisterAssembly(
+                this.GetType().Assembly, 
+                AssemblyRegistrationFlags.SetCodeBase);
+        }
+
+        public override void Uninstall(IDictionary savedState)
+        {
+            base.Uninstall(savedState);
+
+            // Call RegistrationServices.UnregisterAssembly to unregister the classes 
+            // in the current managed assembly.
+            RegistrationServices regService = new RegistrationServices();
+            regService.UnregisterAssembly(this.GetType().Assembly);
+        }
+    }
+}
\ No newline at end of file
diff --git a/trunk/Pithos.ShellExtensions/ProjectInstaller.designer.cs b/trunk/Pithos.ShellExtensions/ProjectInstaller.designer.cs
new file mode 100644 (file)
index 0000000..e7e4737
--- /dev/null
@@ -0,0 +1,36 @@
+namespace Pithos.ShellExtensions
+{
+    partial class ProjectInstaller
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary> 
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Component Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            components = new System.ComponentModel.Container();
+        }
+
+        #endregion
+    }
+}
\ No newline at end of file
diff --git a/trunk/Pithos.ShellExtensions/Properties/AssemblyInfo.cs b/trunk/Pithos.ShellExtensions/Properties/AssemblyInfo.cs
new file mode 100644 (file)
index 0000000..e78ae0d
--- /dev/null
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Pithos.ShellExtensions")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("Pithos.ShellExtensions")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("622f73d0-45af-4bad-8316-c6fa216cb1e9")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/trunk/Pithos.ShellExtensions/ShellExtLib.cs b/trunk/Pithos.ShellExtensions/ShellExtLib.cs
new file mode 100644 (file)
index 0000000..41e385b
--- /dev/null
@@ -0,0 +1,834 @@
+using System;
+using System.Diagnostics;
+using System.Text;
+using Microsoft.Win32;
+using System.Runtime.InteropServices;
+using System.Runtime.InteropServices.ComTypes;
+
+
+namespace Pithos.ShellExtensions
+{
+    #region Shell Interfaces
+    [Flags]
+    public enum ISIOI
+    {
+        ISIOI_ICONFILE = 1,
+        ISIOI_ICONINDEX = 2
+    }
+
+    [ComVisible(false)]
+    [ComImport]
+    [Guid("0C6C4200-C589-11D0-999A-00C04FD655E1")]
+    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+    public interface IShellIconOverlayIdentifier
+    {
+
+        [PreserveSig]
+        int IsMemberOf(
+            [MarshalAs(UnmanagedType.LPWStr)] string path,
+
+            uint attributes);
+
+        [PreserveSig]
+        int GetOverlayInfo(
+            IntPtr iconFileBuffer,
+            int iconFileBufferSize,
+            out int iconIndex,
+            out uint flags);
+
+        [PreserveSig]
+        int GetPriority(
+            out int priority);
+
+    }
+
+
+
+    [ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+    [Guid("000214e8-0000-0000-c000-000000000046")]
+    internal interface IShellExtInit
+    {
+        void Initialize(
+            IntPtr /*LPCITEMIDLIST*/ pidlFolder,
+            IntPtr /*LPDATAOBJECT*/ pDataObj,
+            IntPtr /*HKEY*/ hKeyProgID);
+    }
+
+
+    [ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+    [Guid("000214e4-0000-0000-c000-000000000046")]
+    internal interface IContextMenu
+    {
+        [PreserveSig]
+        int QueryContextMenu(
+            IntPtr /*HMENU*/ hMenu,
+            uint iMenu,
+            uint idCmdFirst,
+            uint idCmdLast,
+            uint uFlags);
+
+        void InvokeCommand(IntPtr pici);
+
+        void GetCommandString(
+            UIntPtr idCmd,
+            uint uFlags,
+            IntPtr pReserved,
+            StringBuilder pszName,
+            uint cchMax);
+    }
+
+    #endregion
+
+
+    #region Shell Registration
+
+    internal class ShellExtReg
+    {
+        private const string _approvedKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved";
+
+        public static void RegisterIconOverlayIdentifier(Guid clsid,
+            string friendlyName)
+        {
+            if (clsid == Guid.Empty)
+            {
+                throw new ArgumentException("clsid must not be empty");
+            }
+            if (string.IsNullOrEmpty(friendlyName))
+            {
+                throw new ArgumentException("friendlyName must not be null or empty");
+            }
+
+            // Create the key HKCR\<File Type>\shellex\ContextMenuHandlers\{<CLSID>}.
+            string keyName = string.Format(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers\{0}",
+                friendlyName);
+            using (RegistryKey key = Registry.LocalMachine.CreateSubKey(keyName))
+            {
+                // Set the default value of the key.
+                if (key != null)//&& !string.IsNullOrEmpty(clsid.ToString("B")))
+                {
+                    key.SetValue(null, clsid.ToString("B"));
+                }
+            }
+        }
+
+        internal static void UnregisterIconOverlayIdentifier(Guid clsid,
+            string friendlyName)
+        {
+            if (clsid == null)
+            {
+                throw new ArgumentException("clsid must not be null");
+            }
+            if (string.IsNullOrEmpty(friendlyName))
+            {
+                throw new ArgumentException("friendlyName must not be null or empty");
+            }
+
+
+            // Remove the key HKCR\<File Type>\shellex\ContextMenuHandlers\{<CLSID>}.
+            string keyName = string.Format(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers\{0}",
+                friendlyName);
+            Registry.ClassesRoot.DeleteSubKeyTree(keyName, false);
+        }
+
+
+        /// <summary>
+        /// Register the context menu handler.
+        /// </summary>
+        /// <param name="clsid">The CLSID of the component.</param>
+        /// <param name="fileType">
+        /// The file type that the context menu handler is associated with. For 
+        /// example, '*' means all file types; '.txt' means all .txt files. The 
+        /// parameter must not be NULL or an empty string. 
+        /// </param>
+        /// <param name="friendlyName">The friendly name of the component.</param>
+        public static void RegisterShellExtContextMenuHandler(Guid clsid,
+            string fileType, string friendlyName)
+        {
+            if (clsid == Guid.Empty)
+            {
+                throw new ArgumentException("clsid must not be empty");
+            }
+            if (string.IsNullOrEmpty(fileType))
+            {
+                throw new ArgumentException("fileType must not be null or empty");
+            }
+
+            // If fileType starts with '.', try to read the default value of the 
+            // HKCR\<File Type> key which contains the ProgID to which the file type 
+            // is linked.
+            if (fileType.StartsWith("."))
+            {
+                using (RegistryKey key = Registry.ClassesRoot.OpenSubKey(fileType))
+                {
+                    if (key != null)
+                    {
+                        // If the key exists and its default value is not empty, use 
+                        // the ProgID as the file type.
+                        string defaultVal = key.GetValue(null) as string;
+                        if (!string.IsNullOrEmpty(defaultVal))
+                        {
+                            fileType = defaultVal;
+                        }
+                    }
+                }
+            }
+
+            // Create the key HKCR\<File Type>\shellex\ContextMenuHandlers\{<CLSID>}.
+            string keyName = string.Format(@"{0}\shellex\ContextMenuHandlers\{1}",
+                fileType, friendlyName);
+            using (RegistryKey key = Registry.ClassesRoot.CreateSubKey(keyName))
+            {
+                // Set the default value of the key.
+                if (key != null)//&& !string.IsNullOrEmpty(clsid.ToString("B")))
+                {
+                    key.SetValue(null, clsid.ToString("B"));
+                }
+            }
+        }
+
+        /// <summary>
+        /// Unregister the context menu handler.
+        /// </summary>
+        /// <param name="clsid">The CLSID of the component.</param>
+        /// <param name="fileType">
+        /// The file type that the context menu handler is associated with. For 
+        /// example, '*' means all file types; '.txt' means all .txt files. The 
+        /// parameter must not be NULL or an empty string. 
+        /// </param>
+        public static void UnregisterShellExtContextMenuHandler(Guid clsid,
+            string fileType, string friendlyName)
+        {
+            if (clsid == null)
+            {
+                throw new ArgumentException("clsid must not be null");
+            }
+            if (string.IsNullOrEmpty(fileType))
+            {
+                throw new ArgumentException("fileType must not be null or empty");
+            }
+
+            // If fileType starts with '.', try to read the default value of the 
+            // HKCR\<File Type> key which contains the ProgID to which the file type 
+            // is linked.
+            if (fileType.StartsWith("."))
+            {
+                using (RegistryKey key = Registry.ClassesRoot.OpenSubKey(fileType))
+                {
+                    if (key != null)
+                    {
+                        // If the key exists and its default value is not empty, use 
+                        // the ProgID as the file type.
+                        string defaultVal = key.GetValue(null) as string;
+                        if (!string.IsNullOrEmpty(defaultVal))
+                        {
+                            fileType = defaultVal;
+                        }
+                    }
+                }
+            }
+
+            // Remove the key HKCR\<File Type>\shellex\ContextMenuHandlers\{<CLSID>}.
+            string keyName = string.Format(@"{0}\shellex\ContextMenuHandlers\{1}",
+                fileType, friendlyName);
+            Registry.ClassesRoot.DeleteSubKeyTree(keyName, false);
+        }
+
+        public static void MarkApproved(Guid guid, string friendlyName)
+        {
+            Trace.Write(String.Format("Marking approved {0} {1}", guid, friendlyName));
+            using (RegistryKey key = Registry.LocalMachine.OpenSubKey(_approvedKey))
+            {
+                // Set the default value of the key.
+                if (key != null)//&& !string.IsNullOrEmpty(clsid.ToString("B")))
+                {
+                    key.SetValue(guid.ToString("B"), friendlyName, RegistryValueKind.String);
+                }
+                else
+                {
+                    Trace.Write("Error - failed to open key " + _approvedKey);
+                }
+            }
+        }
+
+        public static void RemoveApproved(Guid guid, string csshellextcontextmenuhandlerFilecontextmenuext)
+        {
+            using (RegistryKey key = Registry.LocalMachine.OpenSubKey(_approvedKey))
+            {
+                // Set the default value of the key.
+                if (key != null)//&& !string.IsNullOrEmpty(clsid.ToString("B")))
+                {
+                    key.DeleteValue(guid.ToString("B"), false);
+                }
+                else
+                {
+                    Trace.Write("Error - failed to open key " + _approvedKey);
+                }
+            }
+        }
+    }
+
+    #endregion
+
+
+    #region Enums & Structs
+
+    #region enum HChangeNotifyEventID
+    /// <summary>
+    /// Describes the event that has occurred. 
+    /// Typically, only one event is specified at a time. 
+    /// If more than one event is specified, the values contained 
+    /// in the <i>dwItem1</i> and <i>dwItem2</i> 
+    /// parameters must be the same, respectively, for all specified events. 
+    /// This parameter can be one or more of the following values. 
+    /// </summary>
+    /// <remarks>
+    /// <para><b>Windows NT/2000/XP:</b> <i>dwItem2</i> contains the index 
+    /// in the system image list that has changed. 
+    /// <i>dwItem1</i> is not used and should be <see langword="null"/>.</para>
+    /// <para><b>Windows 95/98:</b> <i>dwItem1</i> contains the index 
+    /// in the system image list that has changed. 
+    /// <i>dwItem2</i> is not used and should be <see langword="null"/>.</para>
+    /// </remarks>
+    [Flags]
+    enum HChangeNotifyEventID
+    {
+        /// <summary>
+        /// All events have occurred. 
+        /// </summary>
+        SHCNE_ALLEVENTS = 0x7FFFFFFF,
+
+        /// <summary>
+        /// A file type association has changed. <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> 
+        /// must be specified in the <i>uFlags</i> parameter. 
+        /// <i>dwItem1</i> and <i>dwItem2</i> are not used and must be <see langword="null"/>. 
+        /// </summary>
+        SHCNE_ASSOCCHANGED = 0x08000000,
+
+        /// <summary>
+        /// The attributes of an item or folder have changed. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the item or folder that has changed. 
+        /// <i>dwItem2</i> is not used and should be <see langword="null"/>.
+        /// </summary>
+        SHCNE_ATTRIBUTES = 0x00000800,
+
+        /// <summary>
+        /// A nonfolder item has been created. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the item that was created. 
+        /// <i>dwItem2</i> is not used and should be <see langword="null"/>.
+        /// </summary>
+        SHCNE_CREATE = 0x00000002,
+
+        /// <summary>
+        /// A nonfolder item has been deleted. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the item that was deleted. 
+        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
+        /// </summary>
+        SHCNE_DELETE = 0x00000004,
+
+        /// <summary>
+        /// A drive has been added. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the root of the drive that was added. 
+        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
+        /// </summary>
+        SHCNE_DRIVEADD = 0x00000100,
+
+        /// <summary>
+        /// A drive has been added and the Shell should create a new window for the drive. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the root of the drive that was added. 
+        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
+        /// </summary>
+        SHCNE_DRIVEADDGUI = 0x00010000,
+
+        /// <summary>
+        /// A drive has been removed. <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the root of the drive that was removed.
+        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
+        /// </summary>
+        SHCNE_DRIVEREMOVED = 0x00000080,
+
+        /// <summary>
+        /// Not currently used. 
+        /// </summary>
+        SHCNE_EXTENDED_EVENT = 0x04000000,
+
+        /// <summary>
+        /// The amount of free space on a drive has changed. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the root of the drive on which the free space changed.
+        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
+        /// </summary>
+        SHCNE_FREESPACE = 0x00040000,
+
+        /// <summary>
+        /// Storage media has been inserted into a drive. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the root of the drive that contains the new media. 
+        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
+        /// </summary>
+        SHCNE_MEDIAINSERTED = 0x00000020,
+
+        /// <summary>
+        /// Storage media has been removed from a drive. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the root of the drive from which the media was removed. 
+        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
+        /// </summary>
+        SHCNE_MEDIAREMOVED = 0x00000040,
+
+        /// <summary>
+        /// A folder has been created. <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> 
+        /// or <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the folder that was created. 
+        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
+        /// </summary>
+        SHCNE_MKDIR = 0x00000008,
+
+        /// <summary>
+        /// A folder on the local computer is being shared via the network. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the folder that is being shared. 
+        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
+        /// </summary>
+        SHCNE_NETSHARE = 0x00000200,
+
+        /// <summary>
+        /// A folder on the local computer is no longer being shared via the network. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the folder that is no longer being shared. 
+        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
+        /// </summary>
+        SHCNE_NETUNSHARE = 0x00000400,
+
+        /// <summary>
+        /// The name of a folder has changed. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the previous pointer to an item identifier list (PIDL) or name of the folder. 
+        /// <i>dwItem2</i> contains the new PIDL or name of the folder. 
+        /// </summary>
+        SHCNE_RENAMEFOLDER = 0x00020000,
+
+        /// <summary>
+        /// The name of a nonfolder item has changed. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the previous PIDL or name of the item. 
+        /// <i>dwItem2</i> contains the new PIDL or name of the item. 
+        /// </summary>
+        SHCNE_RENAMEITEM = 0x00000001,
+
+        /// <summary>
+        /// A folder has been removed. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the folder that was removed. 
+        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
+        /// </summary>
+        SHCNE_RMDIR = 0x00000010,
+
+        /// <summary>
+        /// The computer has disconnected from a server. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the server from which the computer was disconnected. 
+        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
+        /// </summary>
+        SHCNE_SERVERDISCONNECT = 0x00004000,
+
+        /// <summary>
+        /// The contents of an existing folder have changed, 
+        /// but the folder still exists and has not been renamed. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
+        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
+        /// <i>dwItem1</i> contains the folder that has changed. 
+        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
+        /// If a folder has been created, deleted, or renamed, use SHCNE_MKDIR, SHCNE_RMDIR, or 
+        /// SHCNE_RENAMEFOLDER, respectively, instead. 
+        /// </summary>
+        SHCNE_UPDATEDIR = 0x00001000,
+
+        /// <summary>
+        /// An image in the system image list has changed. 
+        /// <see cref="HChangeNotifyFlags.SHCNF_DWORD"/> must be specified in <i>uFlags</i>. 
+        /// </summary>
+        SHCNE_UPDATEIMAGE = 0x00008000,
+
+    }
+    #endregion // enum HChangeNotifyEventID
+
+    #region public enum HChangeNotifyFlags
+    /// <summary>
+    /// Flags that indicate the meaning of the <i>dwItem1</i> and <i>dwItem2</i> parameters. 
+    /// The uFlags parameter must be one of the following values.
+    /// </summary>
+    [Flags]
+    public enum HChangeNotifyFlags
+    {
+        /// <summary>
+        /// The <i>dwItem1</i> and <i>dwItem2</i> parameters are DWORD values. 
+        /// </summary>
+        SHCNF_DWORD = 0x0003,
+        /// <summary>
+        /// <i>dwItem1</i> and <i>dwItem2</i> are the addresses of ITEMIDLIST structures that 
+        /// represent the item(s) affected by the change. 
+        /// Each ITEMIDLIST must be relative to the desktop folder. 
+        /// </summary>
+        SHCNF_IDLIST = 0x0000,
+        /// <summary>
+        /// <i>dwItem1</i> and <i>dwItem2</i> are the addresses of null-terminated strings of 
+        /// maximum length MAX_PATH that contain the full path names 
+        /// of the items affected by the change. 
+        /// </summary>
+        SHCNF_PATHA = 0x0001,
+        /// <summary>
+        /// <i>dwItem1</i> and <i>dwItem2</i> are the addresses of null-terminated strings of 
+        /// maximum length MAX_PATH that contain the full path names 
+        /// of the items affected by the change. 
+        /// </summary>
+        SHCNF_PATHW = 0x0005,
+        /// <summary>
+        /// <i>dwItem1</i> and <i>dwItem2</i> are the addresses of null-terminated strings that 
+        /// represent the friendly names of the printer(s) affected by the change. 
+        /// </summary>
+        SHCNF_PRINTERA = 0x0002,
+        /// <summary>
+        /// <i>dwItem1</i> and <i>dwItem2</i> are the addresses of null-terminated strings that 
+        /// represent the friendly names of the printer(s) affected by the change. 
+        /// </summary>
+        SHCNF_PRINTERW = 0x0006,
+        /// <summary>
+        /// The function should not return until the notification 
+        /// has been delivered to all affected components. 
+        /// As this flag modifies other data-type flags, it cannot by used by itself.
+        /// </summary>
+        SHCNF_FLUSH = 0x1000,
+        /// <summary>
+        /// The function should begin delivering notifications to all affected components 
+        /// but should return as soon as the notification process has begun. 
+        /// As this flag modifies other data-type flags, it cannot by used by itself.
+        /// </summary>
+        SHCNF_FLUSHNOWAIT = 0x2000
+    }
+    #endregion // enum HChangeNotifyFlags
+
+    internal enum GCS : uint
+    {
+        GCS_VERBA = 0x00000000,
+        GCS_HELPTEXTA = 0x00000001,
+        GCS_VALIDATEA = 0x00000002,
+        GCS_VERBW = 0x00000004,
+        GCS_HELPTEXTW = 0x00000005,
+        GCS_VALIDATEW = 0x00000006,
+        GCS_VERBICONW = 0x00000014,
+        GCS_UNICODE = 0x00000004
+    }
+
+    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+    internal struct CMINVOKECOMMANDINFO
+    {
+        public uint cbSize;
+        public CMIC fMask;
+        public IntPtr hwnd;
+        public IntPtr verb;
+        [MarshalAs(UnmanagedType.LPStr)]
+        public string parameters;
+        [MarshalAs(UnmanagedType.LPStr)]
+        public string directory;
+        public int nShow;
+        public uint dwHotKey;
+        public IntPtr hIcon;
+    }
+
+    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+    internal struct CMINVOKECOMMANDINFOEX
+    {
+        public uint cbSize;
+        public CMIC fMask;
+        public IntPtr hwnd;
+        public IntPtr verb;
+        [MarshalAs(UnmanagedType.LPStr)]
+        public string parameters;
+        [MarshalAs(UnmanagedType.LPStr)]
+        public string directory;
+        public int nShow;
+        public uint dwHotKey;
+        public IntPtr hIcon;
+        [MarshalAs(UnmanagedType.LPStr)]
+        public string title;
+        public IntPtr verbW;
+        public string parametersW;
+        public string directoryW;
+        public string titleW;
+        POINT ptInvoke;
+    }
+
+    [Flags]
+    internal enum CMIC : uint
+    {
+        CMIC_MASK_ICON = 0x00000010,
+        CMIC_MASK_HOTKEY = 0x00000020,
+        CMIC_MASK_NOASYNC = 0x00000100,
+        CMIC_MASK_FLAG_NO_UI = 0x00000400,
+        CMIC_MASK_UNICODE = 0x00004000,
+        CMIC_MASK_NO_CONSOLE = 0x00008000,
+        CMIC_MASK_ASYNCOK = 0x00100000,
+        CMIC_MASK_NOZONECHECKS = 0x00800000,
+        CMIC_MASK_FLAG_LOG_USAGE = 0x04000000,
+        CMIC_MASK_SHIFT_DOWN = 0x10000000,
+        CMIC_MASK_PTINVOKE = 0x20000000,
+        CMIC_MASK_CONTROL_DOWN = 0x40000000
+    }
+
+    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+    public struct POINT
+    {
+        public int X;
+        public int Y;
+    }
+
+    internal enum CLIPFORMAT : uint
+    {
+        CF_TEXT = 1,
+        CF_BITMAP = 2,
+        CF_METAFILEPICT = 3,
+        CF_SYLK = 4,
+        CF_DIF = 5,
+        CF_TIFF = 6,
+        CF_OEMTEXT = 7,
+        CF_DIB = 8,
+        CF_PALETTE = 9,
+        CF_PENDATA = 10,
+        CF_RIFF = 11,
+        CF_WAVE = 12,
+        CF_UNICODETEXT = 13,
+        CF_ENHMETAFILE = 14,
+        CF_HDROP = 15,
+        CF_LOCALE = 16,
+        CF_MAX = 17,
+
+        CF_OWNERDISPLAY = 0x0080,
+        CF_DSPTEXT = 0x0081,
+        CF_DSPBITMAP = 0x0082,
+        CF_DSPMETAFILEPICT = 0x0083,
+        CF_DSPENHMETAFILE = 0x008E,
+
+        CF_PRIVATEFIRST = 0x0200,
+        CF_PRIVATELAST = 0x02FF,
+
+        CF_GDIOBJFIRST = 0x0300,
+        CF_GDIOBJLAST = 0x03FF
+    }
+
+    [Flags]
+    internal enum CMF : uint
+    {
+        CMF_NORMAL = 0x00000000,
+        CMF_DEFAULTONLY = 0x00000001,
+        CMF_VERBSONLY = 0x00000002,
+        CMF_EXPLORE = 0x00000004,
+        CMF_NOVERBS = 0x00000008,
+        CMF_CANRENAME = 0x00000010,
+        CMF_NODEFAULT = 0x00000020,
+        CMF_INCLUDESTATIC = 0x00000040,
+        CMF_ITEMMENU = 0x00000080,
+        CMF_EXTENDEDVERBS = 0x00000100,
+        CMF_DISABLEDVERBS = 0x00000200,
+        CMF_ASYNCVERBSTATE = 0x00000400,
+        CMF_OPTIMIZEFORINVOKE = 0x00000800,
+        CMF_SYNCCASCADEMENU = 0x00001000,
+        CMF_DONOTPICKDEFAULT = 0x00002000,
+        CMF_RESERVED = 0xFFFF0000
+    }
+
+    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+    internal struct MENUITEMINFO
+    {
+        public uint cbSize;
+        public MIIM fMask;
+        public MFT fType;
+        public MFS fState;
+        public uint wID;
+        public IntPtr hSubMenu;
+        public IntPtr hbmpChecked;
+        public IntPtr hbmpUnchecked;
+        public UIntPtr dwItemData;
+        public string dwTypeData;
+        public uint cch;
+        public IntPtr hbmpItem;
+    }
+
+    [Flags]
+    internal enum MIIM : uint
+    {
+        MIIM_STATE = 0x00000001,
+        MIIM_ID = 0x00000002,
+        MIIM_SUBMENU = 0x00000004,
+        MIIM_CHECKMARKS = 0x00000008,
+        MIIM_TYPE = 0x00000010,
+        MIIM_DATA = 0x00000020,
+        MIIM_STRING = 0x00000040,
+        MIIM_BITMAP = 0x00000080,
+        MIIM_FTYPE = 0x00000100
+    }
+
+    internal enum MFT : uint
+    {
+        MFT_STRING = 0x00000000,
+        MFT_BITMAP = 0x00000004,
+        MFT_MENUBARBREAK = 0x00000020,
+        MFT_MENUBREAK = 0x00000040,
+        MFT_OWNERDRAW = 0x00000100,
+        MFT_RADIOCHECK = 0x00000200,
+        MFT_SEPARATOR = 0x00000800,
+        MFT_RIGHTORDER = 0x00002000,
+        MFT_RIGHTJUSTIFY = 0x00004000
+    }
+
+    internal enum MFS : uint
+    {
+        MFS_ENABLED = 0x00000000,
+        MFS_UNCHECKED = 0x00000000,
+        MFS_UNHILITE = 0x00000000,
+        MFS_GRAYED = 0x00000003,
+        MFS_DISABLED = 0x00000003,
+        MFS_CHECKED = 0x00000008,
+        MFS_HILITE = 0x00000080,
+        MFS_DEFAULT = 0x00001000
+    }
+
+    #endregion
+
+
+    internal class NativeMethods
+    {
+        /// <summary>
+        /// Retrieve the names of dropped files that result from a successful drag-
+        /// and-drop operation.
+        /// </summary>
+        /// <param name="hDrop">
+        /// Identifier of the structure that contains the file names of the dropped 
+        /// files.
+        /// </param>
+        /// <param name="iFile">
+        /// Index of the file to query. If the value of this parameter is 0xFFFFFFFF, 
+        /// DragQueryFile returns a count of the files dropped. 
+        /// </param>
+        /// <param name="pszFile">
+        /// The address of a buffer that receives the file name of a dropped file 
+        /// when the function returns.
+        /// </param>
+        /// <param name="cch">
+        /// The size, in characters, of the pszFile buffer.
+        /// </param>
+        /// <returns>A non-zero value indicates a successful call.</returns>
+        [DllImport("shell32", CharSet = CharSet.Unicode)]
+        public static extern uint DragQueryFile(
+            IntPtr hDrop,
+            uint iFile,
+            StringBuilder pszFile,
+            int cch);
+
+        /// <summary>
+        /// Free the specified storage medium.
+        /// </summary>
+        /// <param name="pmedium">
+        /// Reference of the storage medium that is to be freed.
+        /// </param>
+        [DllImport("ole32.dll", CharSet = CharSet.Unicode)]
+        public static extern void ReleaseStgMedium(ref STGMEDIUM pmedium);
+
+        /// <summary>
+        /// Insert a new menu item at the specified position in a menu.
+        /// </summary>
+        /// <param name="hMenu">
+        /// A handle to the menu in which the new menu item is inserted. 
+        /// </param>
+        /// <param name="uItem">
+        /// The identifier or position of the menu item before which to insert the 
+        /// new item. The meaning of this parameter depends on the value of 
+        /// fByPosition.
+        /// </param>
+        /// <param name="fByPosition">
+        /// Controls the meaning of uItem. If this parameter is false, uItem is a 
+        /// menu item identifier. Otherwise, it is a menu item position. 
+        /// </param>
+        /// <param name="mii">
+        /// A reference of a MENUITEMINFO structure that contains information about 
+        /// the new menu item.
+        /// </param>
+        /// <returns>
+        /// If the function succeeds, the return value is true.
+        /// </returns>
+        [DllImport("user32", CharSet = CharSet.Unicode, SetLastError = true)]
+        [return: MarshalAs(UnmanagedType.Bool)]
+        public static extern bool InsertMenuItem(
+            IntPtr hMenu,
+            uint uItem,
+            [MarshalAs(UnmanagedType.Bool)]bool fByPosition,
+            ref MENUITEMINFO mii);
+
+        [DllImport("shell32", CharSet = CharSet.Unicode, SetLastError = true)]
+        [return: MarshalAs(UnmanagedType.Bool)]
+        public static extern bool SHGetPathFromIDList(
+            IntPtr pidl,
+            StringBuilder pszpath);
+
+        [DllImport("shell32.dll")]
+        public static extern void SHChangeNotify(HChangeNotifyEventID wEventId,
+                                           HChangeNotifyFlags uFlags,
+                                           IntPtr dwItem1,
+                                           IntPtr dwItem2);
+
+        public static int HighWord(int number)
+        {
+            return ((number & 0x80000000) == 0x80000000) ?
+                (number >> 16) : ((number >> 16) & 0xffff);
+        }
+
+        public static int LowWord(int number)
+        {
+            return number & 0xffff;
+        }
+    }
+
+    internal static class WinError
+    {
+        public const int S_OK = 0x0000;
+        public const int S_FALSE = 0x0001;
+        public const int E_FAIL = -2147467259;
+        public const int E_INVALIDARG = -2147024809;
+        public const int E_OUTOFMEMORY = -2147024882;
+        public const int STRSAFE_E_INSUFFICIENT_BUFFER = -2147024774;
+
+        public const uint SEVERITY_SUCCESS = 0;
+        public const uint SEVERITY_ERROR = 1;
+
+        /// <summary>
+        /// Create an HRESULT value from component pieces.
+        /// </summary>
+        /// <param name="sev">The severity to be used</param>
+        /// <param name="fac">The facility to be used</param>
+        /// <param name="code">The error number</param>
+        /// <returns>A HRESULT constructed from the above 3 values</returns>
+        public static int MAKE_HRESULT(uint sev, uint fac, uint code)
+        {
+            return (int)((sev << 31) | (fac << 16) | code);
+        }
+    }
+}
diff --git a/trunk/Pithos.ShellExtensions/TestPithosSettings.cs b/trunk/Pithos.ShellExtensions/TestPithosSettings.cs
new file mode 100644 (file)
index 0000000..43da0e9
--- /dev/null
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.Composition;
+using System.Linq;
+using System.Text;
+using Pithos.Interfaces;
+
+namespace Pithos.ShellExtensions.Test
+{
+    [Export(typeof(IPithosSettings))]
+    class TestPithosSettings:IPithosSettings
+    {
+        public string PithosPath
+        {
+            get { return @"e:\pithos"; }
+            set { throw new NotImplementedException(); }
+        }
+
+        public string IconsPath
+        {
+            get { return @"C:\Program Files\Common Files\TortoiseOverlays\icons\XPStyle\"; }
+            set { throw new NotImplementedException(); }
+        }
+
+        public string UserName { get; set; }
+        public string ApiKey { get; set; }
+
+        public void Save()
+        {
+            
+        }
+
+        public void Reload()
+        {
+            
+        }
+    }
+}
diff --git a/trunk/Pithos.ShellExtensions/TestStatusChecker.cs b/trunk/Pithos.ShellExtensions/TestStatusChecker.cs
new file mode 100644 (file)
index 0000000..d77b07f
--- /dev/null
@@ -0,0 +1,42 @@
+using System;
+using System.ComponentModel.Composition;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.IO;
+using Pithos.Interfaces;
+using Pithos.ShellExtensions.Test;
+
+namespace Pithos.ShellExtensions
+{
+    [Export(typeof(IStatusChecker))]
+    public class TestStatusChecker:IStatusChecker
+    {
+        
+        private IPithosSettings Settings=new TestPithosSettings();
+
+        private readonly string[] _states = {"Normal", "Modified", "Conflict","Synch"};
+
+        public FileOverlayStatus GetFileOverlayStatus(string path)
+        {
+            if (String.IsNullOrWhiteSpace(path))
+                throw new ArgumentNullException("Empty path");
+
+            var pithosPath = Settings.PithosPath;
+            if (path.StartsWith(pithosPath,true,null))
+            {
+                var fileName = Path.GetFileName(path);
+                if (String.IsNullOrWhiteSpace(fileName))
+                    return FileOverlayStatus.Normal;
+
+                var status = Char.ConvertToUtf32(fileName, 0)%4;
+                return (FileOverlayStatus)status;
+            }
+            return FileOverlayStatus.NA;
+        }
+
+        public PithosStatus GetPithosStatus()
+        {
+            return PithosStatus.InSynch;
+        }
+    }
+}
diff --git a/trunk/Pithos.ShellExtensions/app.config b/trunk/Pithos.ShellExtensions/app.config
new file mode 100644 (file)
index 0000000..49cc43e
--- /dev/null
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+</configuration>
\ No newline at end of file
diff --git a/trunk/Pithos.ShellExtensions/pithos.snk b/trunk/Pithos.ShellExtensions/pithos.snk
new file mode 100644 (file)
index 0000000..2069d32
Binary files /dev/null and b/trunk/Pithos.ShellExtensions/pithos.snk differ
diff --git a/trunk/Pithos.sln b/trunk/Pithos.sln
new file mode 100644 (file)
index 0000000..bc6d63d
--- /dev/null
@@ -0,0 +1,163 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pithos.ShellExtensions", "Pithos.ShellExtensions\Pithos.ShellExtensions.csproj", "{240B432F-1030-4623-BCC3-FF351D6C1B63}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pithos.ShellExtensions.Test", "Pithos.ShellExtensions.Test\Pithos.ShellExtensions.Test.csproj", "{2CFE2DF1-20AE-47E2-B1BB-36B974600BE1}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pithos.Client", "Pithos.Client\Pithos.Client.csproj", "{5AC90E5E-60C6-4F53-9444-6088BD7BC929}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pithos.Interfaces", "Pithos.Interfaces\Pithos.Interfaces.csproj", "{7EEFF32F-CCF8-436A-9E0B-F40434C09AF4}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common Files", "Common Files", "{E5971C66-D274-4818-B1A2-3F273994027D}"
+       ProjectSection(SolutionItems) = preProject
+               pithos.snk = pithos.snk
+       EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pithos.Client.Test", "Pithos.Client.Test\Pithos.Client.Test.csproj", "{822F885B-83E8-4A9A-B02E-0FEAE444D960}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{B5DD7C4D-D396-4C55-A8D5-DCFE865AA095}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ParallelExtensionsExtras", "Libraries\ParallelExtensionsExtras\ParallelExtensionsExtras.csproj", "{C45218F8-09E7-4F57-85BC-5D8D2AC736A3}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pithos.Core", "Pithos.Core\Pithos.Core.csproj", "{142AF135-DF30-4563-B0AC-B604235AE874}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pithos.Network.Test", "Pithos.Network.Test\Pithos.Network.Test.csproj", "{E027200B-C26A-4877-BFD9-1A18CF5DF2F4}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pithos.Network", "Pithos.Network\Pithos.Network.csproj", "{C8E2BC8B-C7F1-4222-855C-4B04A57FFDFD}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pithos.Core.Test", "Pithos.Core.Test\Pithos.Core.Test.csproj", "{F9AF3E97-BCB7-46B7-8014-7FC858AEE9BA}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Newtonsoft.Json", "Libraries\Json40r2\Source\Src\Newtonsoft.Json\Newtonsoft.Json.csproj", "{A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}"
+EndProject
+Global
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Debug|Any CPU = Debug|Any CPU
+               Debug|Mixed Platforms = Debug|Mixed Platforms
+               Debug|x86 = Debug|x86
+               Release|Any CPU = Release|Any CPU
+               Release|Mixed Platforms = Release|Mixed Platforms
+               Release|x86 = Release|x86
+       EndGlobalSection
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {240B432F-1030-4623-BCC3-FF351D6C1B63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {240B432F-1030-4623-BCC3-FF351D6C1B63}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {240B432F-1030-4623-BCC3-FF351D6C1B63}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+               {240B432F-1030-4623-BCC3-FF351D6C1B63}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+               {240B432F-1030-4623-BCC3-FF351D6C1B63}.Debug|x86.ActiveCfg = Debug|Any CPU
+               {240B432F-1030-4623-BCC3-FF351D6C1B63}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {240B432F-1030-4623-BCC3-FF351D6C1B63}.Release|Any CPU.Build.0 = Release|Any CPU
+               {240B432F-1030-4623-BCC3-FF351D6C1B63}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+               {240B432F-1030-4623-BCC3-FF351D6C1B63}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+               {240B432F-1030-4623-BCC3-FF351D6C1B63}.Release|x86.ActiveCfg = Release|Any CPU
+               {2CFE2DF1-20AE-47E2-B1BB-36B974600BE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {2CFE2DF1-20AE-47E2-B1BB-36B974600BE1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {2CFE2DF1-20AE-47E2-B1BB-36B974600BE1}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+               {2CFE2DF1-20AE-47E2-B1BB-36B974600BE1}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+               {2CFE2DF1-20AE-47E2-B1BB-36B974600BE1}.Debug|x86.ActiveCfg = Debug|Any CPU
+               {2CFE2DF1-20AE-47E2-B1BB-36B974600BE1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {2CFE2DF1-20AE-47E2-B1BB-36B974600BE1}.Release|Any CPU.Build.0 = Release|Any CPU
+               {2CFE2DF1-20AE-47E2-B1BB-36B974600BE1}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+               {2CFE2DF1-20AE-47E2-B1BB-36B974600BE1}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+               {2CFE2DF1-20AE-47E2-B1BB-36B974600BE1}.Release|x86.ActiveCfg = Release|Any CPU
+               {5AC90E5E-60C6-4F53-9444-6088BD7BC929}.Debug|Any CPU.ActiveCfg = Debug|x86
+               {5AC90E5E-60C6-4F53-9444-6088BD7BC929}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
+               {5AC90E5E-60C6-4F53-9444-6088BD7BC929}.Debug|Mixed Platforms.Build.0 = Debug|x86
+               {5AC90E5E-60C6-4F53-9444-6088BD7BC929}.Debug|x86.ActiveCfg = Debug|x86
+               {5AC90E5E-60C6-4F53-9444-6088BD7BC929}.Debug|x86.Build.0 = Debug|x86
+               {5AC90E5E-60C6-4F53-9444-6088BD7BC929}.Release|Any CPU.ActiveCfg = Release|x86
+               {5AC90E5E-60C6-4F53-9444-6088BD7BC929}.Release|Mixed Platforms.ActiveCfg = Release|x86
+               {5AC90E5E-60C6-4F53-9444-6088BD7BC929}.Release|Mixed Platforms.Build.0 = Release|x86
+               {5AC90E5E-60C6-4F53-9444-6088BD7BC929}.Release|x86.ActiveCfg = Release|x86
+               {5AC90E5E-60C6-4F53-9444-6088BD7BC929}.Release|x86.Build.0 = Release|x86
+               {7EEFF32F-CCF8-436A-9E0B-F40434C09AF4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {7EEFF32F-CCF8-436A-9E0B-F40434C09AF4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {7EEFF32F-CCF8-436A-9E0B-F40434C09AF4}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+               {7EEFF32F-CCF8-436A-9E0B-F40434C09AF4}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+               {7EEFF32F-CCF8-436A-9E0B-F40434C09AF4}.Debug|x86.ActiveCfg = Debug|Any CPU
+               {7EEFF32F-CCF8-436A-9E0B-F40434C09AF4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {7EEFF32F-CCF8-436A-9E0B-F40434C09AF4}.Release|Any CPU.Build.0 = Release|Any CPU
+               {7EEFF32F-CCF8-436A-9E0B-F40434C09AF4}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+               {7EEFF32F-CCF8-436A-9E0B-F40434C09AF4}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+               {7EEFF32F-CCF8-436A-9E0B-F40434C09AF4}.Release|x86.ActiveCfg = Release|Any CPU
+               {822F885B-83E8-4A9A-B02E-0FEAE444D960}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {822F885B-83E8-4A9A-B02E-0FEAE444D960}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {822F885B-83E8-4A9A-B02E-0FEAE444D960}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+               {822F885B-83E8-4A9A-B02E-0FEAE444D960}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+               {822F885B-83E8-4A9A-B02E-0FEAE444D960}.Debug|x86.ActiveCfg = Debug|Any CPU
+               {822F885B-83E8-4A9A-B02E-0FEAE444D960}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {822F885B-83E8-4A9A-B02E-0FEAE444D960}.Release|Any CPU.Build.0 = Release|Any CPU
+               {822F885B-83E8-4A9A-B02E-0FEAE444D960}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+               {822F885B-83E8-4A9A-B02E-0FEAE444D960}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+               {822F885B-83E8-4A9A-B02E-0FEAE444D960}.Release|x86.ActiveCfg = Release|Any CPU
+               {C45218F8-09E7-4F57-85BC-5D8D2AC736A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {C45218F8-09E7-4F57-85BC-5D8D2AC736A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {C45218F8-09E7-4F57-85BC-5D8D2AC736A3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+               {C45218F8-09E7-4F57-85BC-5D8D2AC736A3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+               {C45218F8-09E7-4F57-85BC-5D8D2AC736A3}.Debug|x86.ActiveCfg = Debug|Any CPU
+               {C45218F8-09E7-4F57-85BC-5D8D2AC736A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {C45218F8-09E7-4F57-85BC-5D8D2AC736A3}.Release|Any CPU.Build.0 = Release|Any CPU
+               {C45218F8-09E7-4F57-85BC-5D8D2AC736A3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+               {C45218F8-09E7-4F57-85BC-5D8D2AC736A3}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+               {C45218F8-09E7-4F57-85BC-5D8D2AC736A3}.Release|x86.ActiveCfg = Release|Any CPU
+               {142AF135-DF30-4563-B0AC-B604235AE874}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {142AF135-DF30-4563-B0AC-B604235AE874}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {142AF135-DF30-4563-B0AC-B604235AE874}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+               {142AF135-DF30-4563-B0AC-B604235AE874}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+               {142AF135-DF30-4563-B0AC-B604235AE874}.Debug|x86.ActiveCfg = Debug|Any CPU
+               {142AF135-DF30-4563-B0AC-B604235AE874}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {142AF135-DF30-4563-B0AC-B604235AE874}.Release|Any CPU.Build.0 = Release|Any CPU
+               {142AF135-DF30-4563-B0AC-B604235AE874}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+               {142AF135-DF30-4563-B0AC-B604235AE874}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+               {142AF135-DF30-4563-B0AC-B604235AE874}.Release|x86.ActiveCfg = Release|Any CPU
+               {E027200B-C26A-4877-BFD9-1A18CF5DF2F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {E027200B-C26A-4877-BFD9-1A18CF5DF2F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {E027200B-C26A-4877-BFD9-1A18CF5DF2F4}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+               {E027200B-C26A-4877-BFD9-1A18CF5DF2F4}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+               {E027200B-C26A-4877-BFD9-1A18CF5DF2F4}.Debug|x86.ActiveCfg = Debug|Any CPU
+               {E027200B-C26A-4877-BFD9-1A18CF5DF2F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {E027200B-C26A-4877-BFD9-1A18CF5DF2F4}.Release|Any CPU.Build.0 = Release|Any CPU
+               {E027200B-C26A-4877-BFD9-1A18CF5DF2F4}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+               {E027200B-C26A-4877-BFD9-1A18CF5DF2F4}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+               {E027200B-C26A-4877-BFD9-1A18CF5DF2F4}.Release|x86.ActiveCfg = Release|Any CPU
+               {C8E2BC8B-C7F1-4222-855C-4B04A57FFDFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {C8E2BC8B-C7F1-4222-855C-4B04A57FFDFD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {C8E2BC8B-C7F1-4222-855C-4B04A57FFDFD}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+               {C8E2BC8B-C7F1-4222-855C-4B04A57FFDFD}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+               {C8E2BC8B-C7F1-4222-855C-4B04A57FFDFD}.Debug|x86.ActiveCfg = Debug|Any CPU
+               {C8E2BC8B-C7F1-4222-855C-4B04A57FFDFD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {C8E2BC8B-C7F1-4222-855C-4B04A57FFDFD}.Release|Any CPU.Build.0 = Release|Any CPU
+               {C8E2BC8B-C7F1-4222-855C-4B04A57FFDFD}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+               {C8E2BC8B-C7F1-4222-855C-4B04A57FFDFD}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+               {C8E2BC8B-C7F1-4222-855C-4B04A57FFDFD}.Release|x86.ActiveCfg = Release|Any CPU
+               {F9AF3E97-BCB7-46B7-8014-7FC858AEE9BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {F9AF3E97-BCB7-46B7-8014-7FC858AEE9BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {F9AF3E97-BCB7-46B7-8014-7FC858AEE9BA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+               {F9AF3E97-BCB7-46B7-8014-7FC858AEE9BA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+               {F9AF3E97-BCB7-46B7-8014-7FC858AEE9BA}.Debug|x86.ActiveCfg = Debug|Any CPU
+               {F9AF3E97-BCB7-46B7-8014-7FC858AEE9BA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {F9AF3E97-BCB7-46B7-8014-7FC858AEE9BA}.Release|Any CPU.Build.0 = Release|Any CPU
+               {F9AF3E97-BCB7-46B7-8014-7FC858AEE9BA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+               {F9AF3E97-BCB7-46B7-8014-7FC858AEE9BA}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+               {F9AF3E97-BCB7-46B7-8014-7FC858AEE9BA}.Release|x86.ActiveCfg = Release|Any CPU
+               {A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+               {A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+               {A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Debug|x86.ActiveCfg = Debug|Any CPU
+               {A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Release|Any CPU.Build.0 = Release|Any CPU
+               {A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+               {A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+               {A9AE40FF-1A21-414A-9FE7-3BE13644CC6D}.Release|x86.ActiveCfg = Release|Any CPU
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+       GlobalSection(NestedProjects) = preSolution
+               {822F885B-83E8-4A9A-B02E-0FEAE444D960} = {B5DD7C4D-D396-4C55-A8D5-DCFE865AA095}
+               {2CFE2DF1-20AE-47E2-B1BB-36B974600BE1} = {B5DD7C4D-D396-4C55-A8D5-DCFE865AA095}
+               {E027200B-C26A-4877-BFD9-1A18CF5DF2F4} = {B5DD7C4D-D396-4C55-A8D5-DCFE865AA095}
+               {F9AF3E97-BCB7-46B7-8014-7FC858AEE9BA} = {B5DD7C4D-D396-4C55-A8D5-DCFE865AA095}
+       EndGlobalSection
+EndGlobal
diff --git a/trunk/Pithos.sln.docstates b/trunk/Pithos.sln.docstates
new file mode 100644 (file)
index 0000000..40a06d0
Binary files /dev/null and b/trunk/Pithos.sln.docstates differ
diff --git a/trunk/packages/Hammock.1.2.3/Hammock-Binaries.zip b/trunk/packages/Hammock.1.2.3/Hammock-Binaries.zip
new file mode 100644 (file)
index 0000000..f9f6a7f
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/Hammock-Binaries.zip differ
diff --git a/trunk/packages/Hammock.1.2.3/Hammock.1.2.3.nupkg b/trunk/packages/Hammock.1.2.3/Hammock.1.2.3.nupkg
new file mode 100644 (file)
index 0000000..4f476a8
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/Hammock.1.2.3.nupkg differ
diff --git a/trunk/packages/Hammock.1.2.3/LICENSE b/trunk/packages/Hammock.1.2.3/LICENSE
new file mode 100644 (file)
index 0000000..b618fc9
--- /dev/null
@@ -0,0 +1,23 @@
+Hammock (http://github.com/danielcrenna/hammock)
+--------------------------------------
+Copyright (c) 2010 Daniel Crenna and Jason Diller
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
+documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
+the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
+to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Hammock for Silverlight and Windows Phone 7
+--------------------------------------
+This target optionally links to a port of SharpZipLib http://www.icsharpcode.net/opensource/sharpziplib as an independent 
+module that does not derive from, and is not based on, SharpZipLib. As such it is compliant with the special
+exception of SharpZipLib's GNU General Public License and may be used in commercial, closed-source applications.
+As the independent module, this is compliant with Hammock's MIT X11 Licence.
+
+Hammock Extras
+--------------------------------------
+The Extras project in source code provides an example serializer that includes JSON.NET, 
+licensed under the MIT X11 License http://www.opensource.org/licenses/mit-license.php.
\ No newline at end of file
diff --git a/trunk/packages/Hammock.1.2.3/lib/net20/Hammock.dll b/trunk/packages/Hammock.1.2.3/lib/net20/Hammock.dll
new file mode 100644 (file)
index 0000000..dfb690f
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/net20/Hammock.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/net20/LinqBridge.dll b/trunk/packages/Hammock.1.2.3/lib/net20/LinqBridge.dll
new file mode 100644 (file)
index 0000000..bf038c2
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/net20/LinqBridge.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/net35-client/Hammock.ClientProfile.dll b/trunk/packages/Hammock.1.2.3/lib/net35-client/Hammock.ClientProfile.dll
new file mode 100644 (file)
index 0000000..3f0a57c
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/net35-client/Hammock.ClientProfile.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/net35/Hammock.dll b/trunk/packages/Hammock.1.2.3/lib/net35/Hammock.dll
new file mode 100644 (file)
index 0000000..63beb35
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/net35/Hammock.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/net40-client/Hammock.ClientProfile.dll b/trunk/packages/Hammock.1.2.3/lib/net40-client/Hammock.ClientProfile.dll
new file mode 100644 (file)
index 0000000..5ad8033
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/net40-client/Hammock.ClientProfile.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/net40/Hammock.dll b/trunk/packages/Hammock.1.2.3/lib/net40/Hammock.dll
new file mode 100644 (file)
index 0000000..41b6a79
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/net40/Hammock.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/net40/Hammock.dll.CodeAnalysisLog.xml b/trunk/packages/Hammock.1.2.3/lib/net40/Hammock.dll.CodeAnalysisLog.xml
new file mode 100644 (file)
index 0000000..a5a31e0
--- /dev/null
@@ -0,0 +1,700 @@
+<?xml version="1.0" encoding="utf-8"?>
+<?xml-stylesheet type="text/xsl" href="c:\program files (x86)\microsoft visual studio 10.0\team tools\static analysis tools\fxcop\Xml\CodeAnalysisReport.xsl"?>
+<FxCopReport Version="10.0">
+ <Targets>
+  <Target Name="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\bin\lib\net40\Hammock.dll">
+   <Modules>
+    <Module Name="hammock.dll">
+     <Namespaces>
+      <Namespace Name="Hammock">
+       <Types>
+        <Type Name="RestBase" Kind="Class" Accessibility="Public" ExternallyVisible="True">
+         <Members>
+          <Member Name="#.ctor()" Kind="Method" Static="False" Accessibility="Family" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="DoNotCallOverridableMethodsInConstructors" Category="Microsoft.Usage" CheckId="CA2214" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="NonBreaking">
+             <Issue Certainty="95" Level="CriticalWarning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock" File="RestBase.cs" Line="89">'RestBase.RestBase()' contains a call chain that results in a call to a virtual method defined by the class. Review the following call stack for unintended consequences: &#xD;&#xA;&#xD;&#xA;RestBase..ctor()&#xD;&#xA;RestBase.Initialize():Void&#xD;&#xA;RestBase.set_Cookies(WebParameterCollection):Void</Issue>
+             <Issue Certainty="95" Level="CriticalWarning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock" File="RestBase.cs" Line="89">'RestBase.RestBase()' contains a call chain that results in a call to a virtual method defined by the class. Review the following call stack for unintended consequences: &#xD;&#xA;&#xD;&#xA;RestBase..ctor()&#xD;&#xA;RestBase.Initialize():Void&#xD;&#xA;RestBase.set_Headers(NameValueCollection):Void</Issue>
+             <Issue Certainty="95" Level="CriticalWarning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock" File="RestBase.cs" Line="89">'RestBase.RestBase()' contains a call chain that results in a call to a virtual method defined by the class. Review the following call stack for unintended consequences: &#xD;&#xA;&#xD;&#xA;RestBase..ctor()&#xD;&#xA;RestBase.Initialize():Void&#xD;&#xA;RestBase.set_Parameters(WebParameterCollection):Void</Issue>
+             <Issue Certainty="95" Level="CriticalWarning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock" File="RestBase.cs" Line="89">'RestBase.RestBase()' contains a call chain that results in a call to a virtual method defined by the class. Review the following call stack for unintended consequences: &#xD;&#xA;&#xD;&#xA;RestBase..ctor()&#xD;&#xA;RestBase.Initialize():Void&#xD;&#xA;RestBase.set_PostParameters(ICollection&lt;HttpPostParameter&gt;):Void</Issue>
+            </Message>
+           </Messages>
+          </Member>
+         </Members>
+        </Type>
+        <Type Name="RestClient" Kind="Class" Accessibility="Public" ExternallyVisible="True">
+         <Members>
+          <Member Name="#_streamQuery" Kind="Field" Static="False" Accessibility="Private" ExternallyVisible="False">
+           <Messages>
+            <Message TypeName="MarkAllNonSerializableFields" Category="Microsoft.Usage" CheckId="CA2235" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="NonBreaking">
+             <Issue Certainty="95" Level="Error">Field 'RestClient._streamQuery' is a member of type 'RestClient', which is serializable, but is of type 'WebQuery', which is not serializable. Add the NonSerializedAttribute to 'RestClient._streamQuery'.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#BeginRequestWithTask(Hammock.RestRequest,Hammock.RestCallback,Hammock.Web.WebQuery,System.String,Hammock.Web.WebQueryAsyncResult&amp;,System.Object)" Kind="Method" Static="False" Accessibility="Private" ExternallyVisible="False">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="ExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock" File="RestClient.cs" Line="2063">In method 'RestClient.BeginRequestWithTask(RestRequest, RestCallback, WebQuery, string, out WebQueryAsyncResult, object)', object '&lt;&gt;g__initLocal3b' is not disposed along all exception paths. Call System.IDisposable.Dispose on object '&lt;&gt;g__initLocal3b' before all references to it are out of scope.</Issue>
+             <Issue Name="NonExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock" File="RestClient.cs" Line="2031">In method 'RestClient.BeginRequestWithTask(RestRequest, RestCallback, WebQuery, string, out WebQueryAsyncResult, object)', call System.IDisposable.Dispose on object 'task' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#BeginRequestWithTask`1(Hammock.RestRequest,Hammock.RestCallback`1&lt;!!0&gt;,Hammock.Web.WebQuery,System.String,Hammock.Web.WebQueryAsyncResult&amp;,System.Object)" Kind="Method" Static="False" Accessibility="Private" ExternallyVisible="False">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="ExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock" File="RestClient.cs" Line="2125">In method 'RestClient.BeginRequestWithTask&lt;T&gt;(RestRequest, RestCallback&lt;T&gt;, WebQuery, string, out WebQueryAsyncResult, object)', object '&lt;&gt;g__initLocal43' is not disposed along all exception paths. Call System.IDisposable.Dispose on object '&lt;&gt;g__initLocal43' before all references to it are out of scope.</Issue>
+             <Issue Name="NonExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock" File="RestClient.cs" Line="2094">In method 'RestClient.BeginRequestWithTask&lt;T&gt;(RestRequest, RestCallback&lt;T&gt;, WebQuery, string, out WebQueryAsyncResult, object)', call System.IDisposable.Dispose on object 'task' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#BuildBaseResponse(Hammock.Web.WebQueryResult)" Kind="Method" Static="True" Accessibility="Private" ExternallyVisible="False">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="ExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock" File="RestClient.cs" Line="2518">In method 'RestClient.BuildBaseResponse(WebQueryResult)', object 'response' is not disposed along all exception paths. Call System.IDisposable.Dispose on object 'response' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#BuildBaseResponse`1(Hammock.Web.WebQueryResult)" Kind="Method" Static="True" Accessibility="Private" ExternallyVisible="False">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="ExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock" File="RestClient.cs" Line="2527">In method 'RestClient.BuildBaseResponse&lt;T&gt;(WebQueryResult)', object 'response' is not disposed along all exception paths. Call System.IDisposable.Dispose on object 'response' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#BuildRateLimitingTask(Hammock.RestRequest,Hammock.Tasks.ITaskOptions,Hammock.RestCallback,Hammock.Web.WebQuery,System.String,System.Object)" Kind="Method" Static="False" Accessibility="Private" ExternallyVisible="False">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="NonExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock" File="RestClient.cs" Line="2246">In method 'RestClient.BuildRateLimitingTask(RestRequest, ITaskOptions, RestCallback, WebQuery, string, object)', call System.IDisposable.Dispose on object '&lt;&gt;g__initLocal49' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#CompleteWithMockWebResponse(System.IAsyncResult,System.IAsyncResult,Hammock.Web.Triplet`3&lt;Hammock.RestRequest,Hammock.RestCallback,System.Object&gt;)" Kind="Method" Static="False" Accessibility="Private" ExternallyVisible="False">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="ExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock" File="RestClient.cs" Line="1016">In method 'RestClient.CompleteWithMockWebResponse(IAsyncResult, IAsyncResult, Triplet&lt;RestRequest, RestCallback, object&gt;)', object '&lt;&gt;g__initLocale' is not disposed along all exception paths. Call System.IDisposable.Dispose on object '&lt;&gt;g__initLocale' before all references to it are out of scope.</Issue>
+             <Issue Name="ExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock" File="RestClient.cs" Line="1000">In method 'RestClient.CompleteWithMockWebResponse(IAsyncResult, IAsyncResult, Triplet&lt;RestRequest, RestCallback, object&gt;)', object 'm' is not disposed along all exception paths. Call System.IDisposable.Dispose on object 'm' before all references to it are out of scope.</Issue>
+            </Message>
+            <Message TypeName="Do not dispose objects multiple times" Category="Microsoft.Usage" CheckId="CA2202" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock" File="RestClient.cs" Line="1007">Object 'stream' can be disposed more than once in method 'RestClient.CompleteWithMockWebResponse(IAsyncResult, IAsyncResult, Triplet&lt;RestRequest, RestCallback, object&gt;)'. To avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object.: Lines: 1007</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#CompleteWithMockWebResponse`1(System.IAsyncResult,System.IAsyncResult,Hammock.Web.Triplet`3&lt;Hammock.RestRequest,Hammock.RestCallback`1&lt;!!0&gt;,System.Object&gt;)" Kind="Method" Static="False" Accessibility="Private" ExternallyVisible="False">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="ExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock" File="RestClient.cs" Line="952">In method 'RestClient.CompleteWithMockWebResponse&lt;T&gt;(IAsyncResult, IAsyncResult, Triplet&lt;RestRequest, RestCallback&lt;T&gt;, object&gt;)', object '&lt;&gt;g__initLocald' is not disposed along all exception paths. Call System.IDisposable.Dispose on object '&lt;&gt;g__initLocald' before all references to it are out of scope.</Issue>
+             <Issue Name="ExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock" File="RestClient.cs" Line="936">In method 'RestClient.CompleteWithMockWebResponse&lt;T&gt;(IAsyncResult, IAsyncResult, Triplet&lt;RestRequest, RestCallback&lt;T&gt;, object&gt;)', object 'm' is not disposed along all exception paths. Call System.IDisposable.Dispose on object 'm' before all references to it are out of scope.</Issue>
+            </Message>
+            <Message TypeName="Do not dispose objects multiple times" Category="Microsoft.Usage" CheckId="CA2202" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock" File="RestClient.cs" Line="943">Object 'stream' can be disposed more than once in method 'RestClient.CompleteWithMockWebResponse&lt;T&gt;(IAsyncResult, IAsyncResult, Triplet&lt;RestRequest, RestCallback&lt;T&gt;, object&gt;)'. To avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object.: Lines: 943</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#GetQueryFor(Hammock.RestBase,System.Uri)" Kind="Method" Static="False" Accessibility="Public" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="ExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock" File="RestClient.cs" Line="2658">In method 'RestClient.GetQueryFor(RestBase, Uri)', object 'new BasicAuthWebQuery(info)' is not disposed along all exception paths. Call System.IDisposable.Dispose on object 'new BasicAuthWebQuery(info)' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+         </Members>
+        </Type>
+        <Type Name="RestRequest" Kind="Class" Accessibility="Public" ExternallyVisible="True">
+         <Members>
+          <Member Name="#.ctor()" Kind="Method" Static="False" Accessibility="Public" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="DoNotCallOverridableMethodsInConstructors" Category="Microsoft.Usage" CheckId="CA2214" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="NonBreaking">
+             <Issue Certainty="95" Level="CriticalWarning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock" File="RestRequest.cs" Line="27">'RestRequest.RestRequest()' contains a call chain that results in a call to a virtual method defined by the class. Review the following call stack for unintended consequences: &#xD;&#xA;&#xD;&#xA;RestRequest..ctor()&#xD;&#xA;RestRequest.Initialize():Void&#xD;&#xA;RestRequest.set_ExpectHeaders(WebHeaderCollection):Void</Issue>
+            </Message>
+           </Messages>
+          </Member>
+         </Members>
+        </Type>
+        <Type Name="RestResponseBase" Kind="Class" Accessibility="Public" ExternallyVisible="True">
+         <Messages>
+          <Message TypeName="ImplementIDisposableCorrectly" Category="Microsoft.Design" CheckId="CA1063" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="Breaking">
+           <Issue Name="ProvideDisposeBool" Certainty="95" Level="Error">Provide an overridable implementation of Dispose(bool) on 'RestResponseBase' or mark the type as sealed. A call to Dispose(false) should only clean up native resources. A call to Dispose(true) should clean up both managed and native resources.</Issue>
+          </Message>
+         </Messages>
+         <Members>
+          <Member Name="#Dispose()" Kind="Method" Static="False" Accessibility="Public" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="ImplementIDisposableCorrectly" Category="Microsoft.Design" CheckId="CA1063" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="Breaking">
+             <Issue Name="DisposeImplementation" Certainty="95" Level="Error" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock" File="RestResponse.cs" Line="287">Modify 'RestResponseBase.Dispose()' so that it calls Dispose(true), then calls GC.SuppressFinalize on the current object instance ('this' or 'Me' in Visual Basic), and then returns.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#ReplaceContentStreamWithMemoryStream()" Kind="Method" Static="False" Accessibility="Private" ExternallyVisible="False">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="ExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock" File="RestResponse.cs" Line="138">In method 'RestResponseBase.ReplaceContentStreamWithMemoryStream()', object 'stream' is not disposed along all exception paths. Call System.IDisposable.Dispose on object 'stream' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+         </Members>
+        </Type>
+       </Types>
+      </Namespace>
+      <Namespace Name="Hammock.Attributes.Specialized">
+       <Types>
+        <Type Name="EntityAttribute" Kind="Class" Accessibility="Public" ExternallyVisible="True">
+         <Members>
+          <Member Name="#.ctor()" Kind="Method" Static="False" Accessibility="Public" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="DoNotCallOverridableMethodsInConstructors" Category="Microsoft.Usage" CheckId="CA2214" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="NonBreaking">
+             <Issue Certainty="95" Level="CriticalWarning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Attributes\Specialized" File="EntityAttribute.cs" Line="12">'EntityAttribute.EntityAttribute()' contains a call chain that results in a call to a virtual method defined by the class. Review the following call stack for unintended consequences: &#xD;&#xA;&#xD;&#xA;EntityAttribute..ctor()&#xD;&#xA;EntityAttribute.set_ContentEncoding(Encoding):Void</Issue>
+            </Message>
+           </Messages>
+          </Member>
+         </Members>
+        </Type>
+       </Types>
+      </Namespace>
+      <Namespace Name="Hammock.Authentication.OAuth">
+       <Types>
+        <Type Name="OAuthTools" Kind="Class" Accessibility="Public" ExternallyVisible="True">
+         <Members>
+          <Member Name="#GetSignature(Hammock.Authentication.OAuth.OAuthSignatureMethod,Hammock.Authentication.OAuth.OAuthSignatureTreatment,System.String,System.String,System.String)" Kind="Method" Static="True" Accessibility="Public" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="NonExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Authentication\OAuth" File="OAuthTools.cs" Line="292">In method 'OAuthTools.GetSignature(OAuthSignatureMethod, OAuthSignatureTreatment, string, string, string)', call System.IDisposable.Dispose on object 'crypto' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+         </Members>
+        </Type>
+        <Type Name="OAuthWebQuery" Kind="Class" Accessibility="Public" ExternallyVisible="True">
+         <Members>
+          <Member Name="#.ctor(Hammock.Authentication.OAuth.OAuthWebQueryInfo)" Kind="Method" Static="False" Accessibility="Public" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="DoNotCallOverridableMethodsInConstructors" Category="Microsoft.Usage" CheckId="CA2214" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="NonBreaking">
+             <Issue Certainty="95" Level="CriticalWarning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Authentication\OAuth" File="OAuthWebQuery.cs" Line="26">'OAuthWebQuery.OAuthWebQuery(OAuthWebQueryInfo)' contains a call chain that results in a call to a virtual method defined by the class. Review the following call stack for unintended consequences: &#xD;&#xA;&#xD;&#xA;OAuthWebQuery..ctor(OAuthWebQueryInfo)&#xD;&#xA;OAuthWebQuery.Initialize(OAuthWebQueryInfo):Void&#xD;&#xA;WebQuery.set_Method(WebMethod):Void</Issue>
+            </Message>
+           </Messages>
+          </Member>
+         </Members>
+        </Type>
+        <Type Name="OAuthWorkflow" Kind="Class" Accessibility="Public" ExternallyVisible="True">
+         <Members>
+          <Member Name="#.ctor(Hammock.Authentication.OAuth.OAuthCredentials)" Kind="Method" Static="False" Accessibility="Public" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="DoNotCallOverridableMethodsInConstructors" Category="Microsoft.Usage" CheckId="CA2214" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="NonBreaking">
+             <Issue Certainty="95" Level="CriticalWarning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Authentication\OAuth" File="OAuthWorkflow.cs" Line="69">'OAuthWorkflow.OAuthWorkflow(OAuthCredentials)' contains a call chain that results in a call to a virtual method defined by the class. Review the following call stack for unintended consequences: &#xD;&#xA;&#xD;&#xA;OAuthWorkflow..ctor(OAuthCredentials)&#xD;&#xA;OAuthWorkflow.InitializeFromCredentials(OAuthCredentials):Void&#xD;&#xA;OAuthWorkflow.set_CallbackUrl(String):Void</Issue>
+             <Issue Certainty="95" Level="CriticalWarning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Authentication\OAuth" File="OAuthWorkflow.cs" Line="69">'OAuthWorkflow.OAuthWorkflow(OAuthCredentials)' contains a call chain that results in a call to a virtual method defined by the class. Review the following call stack for unintended consequences: &#xD;&#xA;&#xD;&#xA;OAuthWorkflow..ctor(OAuthCredentials)&#xD;&#xA;OAuthWorkflow.InitializeFromCredentials(OAuthCredentials):Void&#xD;&#xA;OAuthWorkflow.set_ClientPassword(String):Void</Issue>
+             <Issue Certainty="95" Level="CriticalWarning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Authentication\OAuth" File="OAuthWorkflow.cs" Line="69">'OAuthWorkflow.OAuthWorkflow(OAuthCredentials)' contains a call chain that results in a call to a virtual method defined by the class. Review the following call stack for unintended consequences: &#xD;&#xA;&#xD;&#xA;OAuthWorkflow..ctor(OAuthCredentials)&#xD;&#xA;OAuthWorkflow.InitializeFromCredentials(OAuthCredentials):Void&#xD;&#xA;OAuthWorkflow.set_ClientUsername(String):Void</Issue>
+             <Issue Certainty="95" Level="CriticalWarning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Authentication\OAuth" File="OAuthWorkflow.cs" Line="69">'OAuthWorkflow.OAuthWorkflow(OAuthCredentials)' contains a call chain that results in a call to a virtual method defined by the class. Review the following call stack for unintended consequences: &#xD;&#xA;&#xD;&#xA;OAuthWorkflow..ctor(OAuthCredentials)&#xD;&#xA;OAuthWorkflow.InitializeFromCredentials(OAuthCredentials):Void&#xD;&#xA;OAuthWorkflow.set_ConsumerKey(String):Void</Issue>
+             <Issue Certainty="95" Level="CriticalWarning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Authentication\OAuth" File="OAuthWorkflow.cs" Line="69">'OAuthWorkflow.OAuthWorkflow(OAuthCredentials)' contains a call chain that results in a call to a virtual method defined by the class. Review the following call stack for unintended consequences: &#xD;&#xA;&#xD;&#xA;OAuthWorkflow..ctor(OAuthCredentials)&#xD;&#xA;OAuthWorkflow.InitializeFromCredentials(OAuthCredentials):Void&#xD;&#xA;OAuthWorkflow.set_ConsumerSecret(String):Void</Issue>
+             <Issue Certainty="95" Level="CriticalWarning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Authentication\OAuth" File="OAuthWorkflow.cs" Line="69">'OAuthWorkflow.OAuthWorkflow(OAuthCredentials)' contains a call chain that results in a call to a virtual method defined by the class. Review the following call stack for unintended consequences: &#xD;&#xA;&#xD;&#xA;OAuthWorkflow..ctor(OAuthCredentials)&#xD;&#xA;OAuthWorkflow.InitializeFromCredentials(OAuthCredentials):Void&#xD;&#xA;OAuthWorkflow.set_ParameterHandling(OAuthParameterHandling):Void</Issue>
+             <Issue Certainty="95" Level="CriticalWarning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Authentication\OAuth" File="OAuthWorkflow.cs" Line="69">'OAuthWorkflow.OAuthWorkflow(OAuthCredentials)' contains a call chain that results in a call to a virtual method defined by the class. Review the following call stack for unintended consequences: &#xD;&#xA;&#xD;&#xA;OAuthWorkflow..ctor(OAuthCredentials)&#xD;&#xA;OAuthWorkflow.InitializeFromCredentials(OAuthCredentials):Void&#xD;&#xA;OAuthWorkflow.set_SessionHandle(String):Void</Issue>
+             <Issue Certainty="95" Level="CriticalWarning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Authentication\OAuth" File="OAuthWorkflow.cs" Line="69">'OAuthWorkflow.OAuthWorkflow(OAuthCredentials)' contains a call chain that results in a call to a virtual method defined by the class. Review the following call stack for unintended consequences: &#xD;&#xA;&#xD;&#xA;OAuthWorkflow..ctor(OAuthCredentials)&#xD;&#xA;OAuthWorkflow.InitializeFromCredentials(OAuthCredentials):Void&#xD;&#xA;OAuthWorkflow.set_SignatureMethod(OAuthSignatureMethod):Void</Issue>
+             <Issue Certainty="95" Level="CriticalWarning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Authentication\OAuth" File="OAuthWorkflow.cs" Line="69">'OAuthWorkflow.OAuthWorkflow(OAuthCredentials)' contains a call chain that results in a call to a virtual method defined by the class. Review the following call stack for unintended consequences: &#xD;&#xA;&#xD;&#xA;OAuthWorkflow..ctor(OAuthCredentials)&#xD;&#xA;OAuthWorkflow.InitializeFromCredentials(OAuthCredentials):Void&#xD;&#xA;OAuthWorkflow.set_SignatureTreatment(OAuthSignatureTreatment):Void</Issue>
+             <Issue Certainty="95" Level="CriticalWarning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Authentication\OAuth" File="OAuthWorkflow.cs" Line="69">'OAuthWorkflow.OAuthWorkflow(OAuthCredentials)' contains a call chain that results in a call to a virtual method defined by the class. Review the following call stack for unintended consequences: &#xD;&#xA;&#xD;&#xA;OAuthWorkflow..ctor(OAuthCredentials)&#xD;&#xA;OAuthWorkflow.InitializeFromCredentials(OAuthCredentials):Void&#xD;&#xA;OAuthWorkflow.set_Token(String):Void</Issue>
+             <Issue Certainty="95" Level="CriticalWarning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Authentication\OAuth" File="OAuthWorkflow.cs" Line="69">'OAuthWorkflow.OAuthWorkflow(OAuthCredentials)' contains a call chain that results in a call to a virtual method defined by the class. Review the following call stack for unintended consequences: &#xD;&#xA;&#xD;&#xA;OAuthWorkflow..ctor(OAuthCredentials)&#xD;&#xA;OAuthWorkflow.InitializeFromCredentials(OAuthCredentials):Void&#xD;&#xA;OAuthWorkflow.set_TokenSecret(String):Void</Issue>
+             <Issue Certainty="95" Level="CriticalWarning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Authentication\OAuth" File="OAuthWorkflow.cs" Line="69">'OAuthWorkflow.OAuthWorkflow(OAuthCredentials)' contains a call chain that results in a call to a virtual method defined by the class. Review the following call stack for unintended consequences: &#xD;&#xA;&#xD;&#xA;OAuthWorkflow..ctor(OAuthCredentials)&#xD;&#xA;OAuthWorkflow.InitializeFromCredentials(OAuthCredentials):Void&#xD;&#xA;OAuthWorkflow.set_Verifier(String):Void</Issue>
+             <Issue Certainty="95" Level="CriticalWarning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Authentication\OAuth" File="OAuthWorkflow.cs" Line="69">'OAuthWorkflow.OAuthWorkflow(OAuthCredentials)' contains a call chain that results in a call to a virtual method defined by the class. Review the following call stack for unintended consequences: &#xD;&#xA;&#xD;&#xA;OAuthWorkflow..ctor(OAuthCredentials)&#xD;&#xA;OAuthWorkflow.InitializeFromCredentials(OAuthCredentials):Void&#xD;&#xA;OAuthWorkflow.set_Version(String):Void</Issue>
+            </Message>
+           </Messages>
+          </Member>
+         </Members>
+        </Type>
+       </Types>
+      </Namespace>
+      <Namespace Name="Hammock.Retries">
+       <Types>
+        <Type Name="RetryPolicy" Kind="Class" Accessibility="Public" ExternallyVisible="True">
+         <Members>
+          <Member Name="#.ctor()" Kind="Method" Static="False" Accessibility="Public" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="DoNotCallOverridableMethodsInConstructors" Category="Microsoft.Usage" CheckId="CA2214" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="NonBreaking">
+             <Issue Certainty="95" Level="CriticalWarning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Retries" File="RetryPolicy.cs" Line="17">'RetryPolicy.RetryPolicy()' contains a call chain that results in a call to a virtual method defined by the class. Review the following call stack for unintended consequences: &#xD;&#xA;&#xD;&#xA;RetryPolicy..ctor()&#xD;&#xA;RetryPolicy.Initialize():Void&#xD;&#xA;RetryPolicy.set_RetryConditions(ICollection&lt;IRetryCondition&gt;):Void</Issue>
+            </Message>
+           </Messages>
+          </Member>
+         </Members>
+        </Type>
+       </Types>
+      </Namespace>
+      <Namespace Name="Hammock.Serialization">
+       <Types>
+        <Type Name="HammockDataContractSerializer" Kind="Class" Accessibility="Public" ExternallyVisible="True">
+         <Members>
+          <Member Name="#Serialize(System.Object,System.Type)" Kind="Method" Static="False" Accessibility="Public" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="Do not dispose objects multiple times" Category="Microsoft.Usage" CheckId="CA2202" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Serialization" File="HammockDataContractSerializer.cs" Line="90">Object 'stream' can be disposed more than once in method 'HammockDataContractSerializer.Serialize(object, Type)'. To avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object.: Lines: 90</Issue>
+            </Message>
+           </Messages>
+          </Member>
+         </Members>
+        </Type>
+        <Type Name="HammockXmlSerializer" Kind="Class" Accessibility="Public" ExternallyVisible="True">
+         <Members>
+          <Member Name="#Serialize(System.Object,System.Type)" Kind="Method" Static="False" Accessibility="Public" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="Do not dispose objects multiple times" Category="Microsoft.Usage" CheckId="CA2202" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Serialization" File="HammockXmlSerializer.cs" Line="58">Object 'stream' can be disposed more than once in method 'HammockXmlSerializer.Serialize(object, Type)'. To avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object.: Lines: 58</Issue>
+            </Message>
+           </Messages>
+          </Member>
+         </Members>
+        </Type>
+        <Type Name="InvalidJsonException" Kind="Class" Accessibility="Public" ExternallyVisible="True">
+         <Messages>
+          <Message TypeName="MarkISerializableTypesWithSerializable" Category="Microsoft.Usage" CheckId="CA2237" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="NonBreaking">
+           <Issue Certainty="95" Level="Error">Add [Serializable] to 'InvalidJsonException' as this type implements ISerializable.</Issue>
+          </Message>
+         </Messages>
+        </Type>
+       </Types>
+      </Namespace>
+      <Namespace Name="Hammock.Tasks">
+       <Types>
+        <Type Name="TimedTask" Kind="Class" Accessibility="Public" ExternallyVisible="True">
+         <Messages>
+          <Message TypeName="ImplementIDisposableCorrectly" Category="Microsoft.Design" CheckId="CA1063" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="Breaking">
+           <Issue Name="ProvideDisposeBool" Certainty="95" Level="Error">Provide an overridable implementation of Dispose(bool) on 'TimedTask' or mark the type as sealed. A call to Dispose(false) should only clean up native resources. A call to Dispose(true) should clean up both managed and native resources.</Issue>
+          </Message>
+         </Messages>
+         <Members>
+          <Member Name="#Dispose()" Kind="Method" Static="False" Accessibility="Public" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="ImplementIDisposableCorrectly" Category="Microsoft.Design" CheckId="CA1063" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="Breaking">
+             <Issue Name="DisposeImplementation" Certainty="95" Level="Error" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Tasks" File="TimedTask.cs" Line="140">Modify 'TimedTask.Dispose()' so that it calls Dispose(true), then calls GC.SuppressFinalize on the current object instance ('this' or 'Me' in Visual Basic), and then returns.</Issue>
+             <Issue Name="DisposeSignature" Certainty="95" Level="Error" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Tasks" File="TimedTask.cs" Line="140">Ensure that 'TimedTask.Dispose()' is declared as public and sealed.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#Stopped" Kind="Event" Static="False" Accessibility="Public" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="DeclareEventHandlersCorrectly" Category="Microsoft.Design" CheckId="CA1009" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="Breaking">
+             <Issue Name="First" Certainty="95" Level="Error">Declare the first parameter of 'Action&lt;TimedTask, EventArgs&gt;' as an object named 'sender'.</Issue>
+             <Issue Name="Second" Certainty="95" Level="Error">Declare the second parameter of 'Action&lt;TimedTask, EventArgs&gt;' as an EventArgs, or an instance of a type that extends EventArgs, named 'e'.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+         </Members>
+        </Type>
+        <Type Name="TimedTask`1" Kind="Class" Accessibility="Public" ExternallyVisible="True">
+         <Members>
+          <Member Name="#Dispose()" Kind="Method" Static="False" Accessibility="Public" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="ImplementIDisposableCorrectly" Category="Microsoft.Design" CheckId="CA1063" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="Breaking">
+             <Issue Name="DisposeImplementation" Certainty="95" Level="Error" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Tasks" File="TimedTask.cs" Line="240">Modify 'TimedTask&lt;T&gt;.Dispose()' so that it calls Dispose(true), then calls GC.SuppressFinalize on the current object instance ('this' or 'Me' in Visual Basic), and then returns.</Issue>
+             <Issue Name="DisposeSignature" Certainty="95" Level="Error" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Tasks" File="TimedTask.cs" Line="240">Ensure that 'TimedTask&lt;T&gt;.Dispose()' is declared as public and sealed.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+         </Members>
+        </Type>
+       </Types>
+      </Namespace>
+      <Namespace Name="Hammock.Web">
+       <Types>
+        <Type Name="WebQuery" Kind="Class" Accessibility="Public" ExternallyVisible="True">
+         <Members>
+          <Member Name="#Dispose()" Kind="Method" Static="False" Accessibility="Public" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="ImplementIDisposableCorrectly" Category="Microsoft.Design" CheckId="CA1063" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="Breaking">
+             <Issue Name="DisposeImplementation" Certainty="95" Level="Error" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web" File="WebQuery.cs" Line="1832">Modify 'WebQuery.Dispose()' so that it calls Dispose(true), then calls GC.SuppressFinalize on the current object instance ('this' or 'Me' in Visual Basic), and then returns.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#ExecuteGetOrDeleteAsync(Hammock.Caching.ICache,System.String,System.String,System.DateTime,System.Net.WebRequest,System.Object)" Kind="Method" Static="False" Accessibility="Private" ExternallyVisible="False">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="ExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web" File="WebQuery.Async.cs" Line="94">In method 'WebQuery.ExecuteGetOrDeleteAsync(ICache, string, string, DateTime, WebRequest, object)', object '&lt;&gt;g__initLocal4a' is not disposed along all exception paths. Call System.IDisposable.Dispose on object '&lt;&gt;g__initLocal4a' before all references to it are out of scope.</Issue>
+             <Issue Name="ExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web" File="WebQuery.Async.cs" Line="123">In method 'WebQuery.ExecuteGetOrDeleteAsync(ICache, string, string, DateTime, WebRequest, object)', object '&lt;&gt;g__initLocal4e' is not disposed along all exception paths. Call System.IDisposable.Dispose on object '&lt;&gt;g__initLocal4e' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#ExecuteGetOrDeleteAsync(Hammock.Caching.ICache,System.String,System.String,System.Net.WebRequest,System.Object)" Kind="Method" Static="False" Accessibility="Private" ExternallyVisible="False">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="ExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web" File="WebQuery.Async.cs" Line="52">In method 'WebQuery.ExecuteGetOrDeleteAsync(ICache, string, string, WebRequest, object)', object '&lt;&gt;g__initLocal46' is not disposed along all exception paths. Call System.IDisposable.Dispose on object '&lt;&gt;g__initLocal46' before all references to it are out of scope.</Issue>
+             <Issue Name="ExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web" File="WebQuery.Async.cs" Line="76">In method 'WebQuery.ExecuteGetOrDeleteAsync(ICache, string, string, WebRequest, object)', object '&lt;&gt;g__initLocal49' is not disposed along all exception paths. Call System.IDisposable.Dispose on object '&lt;&gt;g__initLocal49' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#ExecuteGetOrDeleteAsync(Hammock.Caching.ICache,System.String,System.String,System.TimeSpan,System.Net.WebRequest,System.Object)" Kind="Method" Static="False" Accessibility="Private" ExternallyVisible="False">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="ExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web" File="WebQuery.Async.cs" Line="141">In method 'WebQuery.ExecuteGetOrDeleteAsync(ICache, string, string, TimeSpan, WebRequest, object)', object '&lt;&gt;g__initLocal4f' is not disposed along all exception paths. Call System.IDisposable.Dispose on object '&lt;&gt;g__initLocal4f' before all references to it are out of scope.</Issue>
+             <Issue Name="ExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web" File="WebQuery.Async.cs" Line="169">In method 'WebQuery.ExecuteGetOrDeleteAsync(ICache, string, string, TimeSpan, WebRequest, object)', object '&lt;&gt;g__initLocal53' is not disposed along all exception paths. Call System.IDisposable.Dispose on object '&lt;&gt;g__initLocal53' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#ExecuteGetOrDeleteAsync(Hammock.Web.GetDeleteHeadOptions,System.String,System.Object)" Kind="Method" Static="False" Accessibility="Family" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="ExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web" File="WebQuery.Async.cs" Line="36">In method 'WebQuery.ExecuteGetOrDeleteAsync(GetDeleteHeadOptions, string, object)', object '&lt;&gt;g__initLocal45' is not disposed along all exception paths. Call System.IDisposable.Dispose on object '&lt;&gt;g__initLocal45' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#ExecutePostOrPut(Hammock.Web.PostOrPut,System.String,System.Net.WebException&amp;)" Kind="Method" Static="False" Accessibility="Family" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="Do not dispose objects multiple times" Category="Microsoft.Usage" CheckId="CA2202" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web" File="WebQuery.cs" Line="1135">Object 'stream' can be disposed more than once in method 'WebQuery.ExecutePostOrPut(PostOrPut, string, out WebException)'. To avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object.: Lines: 1135</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#ExecutePostOrPutAsync(Hammock.Web.PostOrPut,System.String,System.Collections.Generic.IEnumerable`1&lt;Hammock.Web.HttpPostParameter&gt;,System.Object)" Kind="Method" Static="False" Accessibility="Family" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="ExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web" File="WebQuery.Async.cs" Line="1074">In method 'WebQuery.ExecutePostOrPutAsync(PostOrPut, string, IEnumerable&lt;HttpPostParameter&gt;, object)', object '&lt;&gt;g__initLocal67' is not disposed along all exception paths. Call System.IDisposable.Dispose on object '&lt;&gt;g__initLocal67' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#ExecutePostOrPutAsync(Hammock.Web.PostOrPut,System.String,System.Object)" Kind="Method" Static="False" Accessibility="Family" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="ExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web" File="WebQuery.Async.cs" Line="1044">In method 'WebQuery.ExecutePostOrPutAsync(PostOrPut, string, object)', object '&lt;&gt;g__initLocal64' is not disposed along all exception paths. Call System.IDisposable.Dispose on object '&lt;&gt;g__initLocal64' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#ExecutePostOrPutAsync(Hammock.Web.PostOrPut,System.String,System.String,Hammock.Caching.ICache,System.DateTime,System.Object)" Kind="Method" Static="False" Accessibility="Family" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="ExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web" File="WebQuery.Async.cs" Line="1143">In method 'WebQuery.ExecutePostOrPutAsync(PostOrPut, string, string, ICache, DateTime, object)', object '&lt;&gt;g__initLocal6e' is not disposed along all exception paths. Call System.IDisposable.Dispose on object '&lt;&gt;g__initLocal6e' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#ExecutePostOrPutAsync(Hammock.Web.PostOrPut,System.String,System.String,Hammock.Caching.ICache,System.Object)" Kind="Method" Static="False" Accessibility="Family" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="ExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web" File="WebQuery.Async.cs" Line="1106">In method 'WebQuery.ExecutePostOrPutAsync(PostOrPut, string, string, ICache, object)', object '&lt;&gt;g__initLocal6a' is not disposed along all exception paths. Call System.IDisposable.Dispose on object '&lt;&gt;g__initLocal6a' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#ExecutePostOrPutAsync(Hammock.Web.PostOrPut,System.String,System.String,Hammock.Caching.ICache,System.TimeSpan,System.Object)" Kind="Method" Static="False" Accessibility="Family" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="ExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web" File="WebQuery.Async.cs" Line="1180">In method 'WebQuery.ExecutePostOrPutAsync(PostOrPut, string, string, ICache, TimeSpan, object)', object '&lt;&gt;g__initLocal72' is not disposed along all exception paths. Call System.IDisposable.Dispose on object '&lt;&gt;g__initLocal72' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#ExecuteStreamGetAsync(System.String,System.TimeSpan,System.Int32)" Kind="Method" Static="False" Accessibility="Public" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="ExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web" File="WebQuery.Async.cs" Line="1203">In method 'WebQuery.ExecuteStreamGetAsync(string, TimeSpan, int)', object '&lt;&gt;g__initLocal73' is not disposed along all exception paths. Call System.IDisposable.Dispose on object '&lt;&gt;g__initLocal73' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#ExecuteStreamPostAsync(System.String,System.TimeSpan,System.Int32)" Kind="Method" Static="False" Accessibility="Public" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="ExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web" File="WebQuery.Async.cs" Line="1261">In method 'WebQuery.ExecuteStreamPostAsync(string, TimeSpan, int)', object '&lt;&gt;g__initLocal78' is not disposed along all exception paths. Call System.IDisposable.Dispose on object '&lt;&gt;g__initLocal78' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#PostAsyncRequestCallback(System.IAsyncResult)" Kind="Method" Static="False" Accessibility="Family" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="NonExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web" File="WebQuery.Async.cs" Line="778">In method 'WebQuery.PostAsyncRequestCallback(IAsyncResult)', call System.IDisposable.Dispose on object '&lt;&gt;g__initLocal5d' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#PostAsyncRequestCallbackMultiPart(System.IAsyncResult)" Kind="Method" Static="False" Accessibility="Family" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="NonExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web" File="WebQuery.Async.cs" Line="949">In method 'WebQuery.PostAsyncRequestCallbackMultiPart(IAsyncResult)', call System.IDisposable.Dispose on object '&lt;&gt;g__initLocal62' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#PostAsyncResponseCallback(System.IAsyncResult)" Kind="Method" Static="False" Accessibility="Family" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="NonExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web" File="WebQuery.Async.cs" Line="973">In method 'WebQuery.PostAsyncResponseCallback(IAsyncResult)', call System.IDisposable.Dispose on object 'new MemoryStream()' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#PostAsyncStreamRequestCallback(System.IAsyncResult)" Kind="Method" Static="False" Accessibility="Family" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="Do not dispose objects multiple times" Category="Microsoft.Usage" CheckId="CA2202" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web" File="WebQuery.Async.cs" Line="642">Object 'stream' can be disposed more than once in method 'WebQuery.PostAsyncStreamRequestCallback(IAsyncResult)'. To avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object.: Lines: 642</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#ProcessBuffer(System.String)" Kind="Method" Static="False" Accessibility="Private" ExternallyVisible="False">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="NonExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web" File="WebQuery.Async.cs" Line="601">In method 'WebQuery.ProcessBuffer(string)', call System.IDisposable.Dispose on object 'new MemoryStream(messageBytes)' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#TimedOutCallback(System.Object,System.Boolean)" Kind="Method" Static="False" Accessibility="Private" ExternallyVisible="False">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="NonExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web" File="WebQuery.Async.cs" Line="234">In method 'WebQuery.TimedOutCallback(object, bool)', call System.IDisposable.Dispose on object '&lt;&gt;g__initLocal55' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#WriteMultiPartImpl(System.Boolean,System.Collections.Generic.IEnumerable`1&lt;Hammock.Web.HttpPostParameter&gt;,System.String,System.Text.Encoding,System.IO.Stream)" Kind="Method" Static="False" Accessibility="Private" ExternallyVisible="False">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="NonExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web" File="WebQuery.cs" Line="1271">In method 'WebQuery.WriteMultiPartImpl(bool, IEnumerable&lt;HttpPostParameter&gt;, string, Encoding, Stream)', call System.IDisposable.Dispose on object 'new FileStream(parameter.FilePath, FileMode.Open, FileAccess.Read)' before all references to it are out of scope.</Issue>
+            </Message>
+            <Message TypeName="Do not dispose objects multiple times" Category="Microsoft.Usage" CheckId="CA2202" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web" File="WebQuery.cs" Line="1346">Object 'new FileStream(parameter.FilePath, FileMode.Open, FileAccess.Read)' can be disposed more than once in method 'WebQuery.WriteMultiPartImpl(bool, IEnumerable&lt;HttpPostParameter&gt;, string, Encoding, Stream)'. To avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object.: Lines: 1346</Issue>
+             <Issue Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web" File="WebQuery.cs" Line="1346">Object 'parameter.FileStream' can be disposed more than once in method 'WebQuery.WriteMultiPartImpl(bool, IEnumerable&lt;HttpPostParameter&gt;, string, Encoding, Stream)'. To avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object.: Lines: 1346</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#NewStreamMessageEvent" Kind="Event" Static="False" Accessibility="Public" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="DeclareEventHandlersCorrectly" Category="Microsoft.Design" CheckId="CA1009" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="Breaking">
+             <Issue Name="First" Certainty="95" Level="Error">Declare the first parameter of 'WebQuery.NewStreamMessage' as an object named 'sender'.</Issue>
+             <Issue Name="Second" Certainty="95" Level="Error">Declare the second parameter of 'WebQuery.NewStreamMessage' as an EventArgs, or an instance of a type that extends EventArgs, named 'e'.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+         </Members>
+        </Type>
+        <Type Name="WebQueryAsyncResult" Kind="Class" Accessibility="Public" ExternallyVisible="True">
+         <Messages>
+          <Message TypeName="ImplementIDisposableCorrectly" Category="Microsoft.Design" CheckId="CA1063" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="Breaking">
+           <Issue Name="ProvideDisposeBool" Certainty="95" Level="Error">Provide an overridable implementation of Dispose(bool) on 'WebQueryAsyncResult' or mark the type as sealed. A call to Dispose(false) should only clean up native resources. A call to Dispose(true) should clean up both managed and native resources.</Issue>
+          </Message>
+         </Messages>
+         <Members>
+          <Member Name="#Dispose()" Kind="Method" Static="False" Accessibility="Public" ExternallyVisible="True">
+           <Messages>
+            <Message Id="_block" TypeName="DisposableFieldsShouldBeDisposed" Category="Microsoft.Usage" CheckId="CA2213" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="NonBreaking">
+             <Issue Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web" File="WebQueryAsyncResult.cs" Line="43">'WebQueryAsyncResult' contains field 'WebQueryAsyncResult._block' that is of IDisposable type: 'AutoResetEvent'. Change the Dispose method on 'WebQueryAsyncResult' to call Dispose or Close on this field.</Issue>
+            </Message>
+            <Message TypeName="ImplementIDisposableCorrectly" Category="Microsoft.Design" CheckId="CA1063" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="Breaking">
+             <Issue Name="DisposeImplementation" Certainty="95" Level="Error" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web" File="WebQueryAsyncResult.cs" Line="43">Modify 'WebQueryAsyncResult.Dispose()' so that it calls Dispose(true), then calls GC.SuppressFinalize on the current object instance ('this' or 'Me' in Visual Basic), and then returns.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+         </Members>
+        </Type>
+       </Types>
+      </Namespace>
+      <Namespace Name="Hammock.Web.Mocks">
+       <Types>
+        <Type Name="MockHttpWebRequest" Kind="Class" Accessibility="Public" ExternallyVisible="True">
+         <Members>
+          <Member Name="#.ctor(System.Uri)" Kind="Method" Static="False" Accessibility="Public" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="DoNotCallOverridableMethodsInConstructors" Category="Microsoft.Usage" CheckId="CA2214" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="NonBreaking">
+             <Issue Certainty="95" Level="CriticalWarning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web\Mocks" File="MockHttpWebRequest.cs" Line="32">'MockHttpWebRequest.MockHttpWebRequest(Uri)' contains a call chain that results in a call to a virtual method defined by the class. Review the following call stack for unintended consequences: &#xD;&#xA;&#xD;&#xA;MockHttpWebRequest..ctor(Uri)&#xD;&#xA;MockHttpWebRequest.Initialize():Void&#xD;&#xA;WebRequest.set_Headers(WebHeaderCollection):Void</Issue>
+             <Issue Certainty="95" Level="CriticalWarning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web\Mocks" File="MockHttpWebRequest.cs" Line="32">'MockHttpWebRequest.MockHttpWebRequest(Uri)' contains a call chain that results in a call to a virtual method defined by the class. Review the following call stack for unintended consequences: &#xD;&#xA;&#xD;&#xA;MockHttpWebRequest..ctor(Uri)&#xD;&#xA;MockHttpWebRequest.Initialize():Void&#xD;&#xA;WebRequest.set_Headers(WebHeaderCollection):Void&#xD;&#xA;MockHttpWebRequest.set_ExpectHeaders(WebHeaderCollection):Void</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#BeginGetResponse(System.AsyncCallback,System.Object)" Kind="Method" Static="False" Accessibility="Public" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="NonExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web\Mocks" File="MockHttpWebRequest.cs" Line="94">In method 'MockHttpWebRequest.BeginGetResponse(AsyncCallback, object)', call System.IDisposable.Dispose on object '&lt;&gt;g__initLocal1' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#CreateResponse()" Kind="Method" Static="False" Accessibility="Private" ExternallyVisible="False">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="ExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web\Mocks" File="MockHttpWebRequest.cs" Line="57">In method 'MockHttpWebRequest.CreateResponse()', object '&lt;&gt;g__initLocal0' is not disposed along all exception paths. Call System.IDisposable.Dispose on object '&lt;&gt;g__initLocal0' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+         </Members>
+        </Type>
+        <Type Name="MockHttpWebResponse" Kind="Class" Accessibility="Public" ExternallyVisible="True">
+         <Members>
+          <Member Name="#GetResponseStream()" Kind="Method" Static="False" Accessibility="Public" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="ExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net35\Hammock\Web\Mocks" File="MockHttpWebResponse.cs" Line="45">In method 'MockHttpWebResponse.GetResponseStream()', object 'stream' is not disposed along all exception paths. Call System.IDisposable.Dispose on object 'stream' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+         </Members>
+        </Type>
+       </Types>
+      </Namespace>
+      <Namespace Name="Mono.Net">
+       <Types>
+        <Type Name="WebHeaderCollection" Kind="Class" Accessibility="Public" ExternallyVisible="True">
+         <Messages>
+          <Message TypeName="ComVisibleTypeBaseTypesShouldBeComVisible" Category="Microsoft.Interoperability" CheckId="CA1405" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+           <Issue Certainty="90" Level="Error">'WebHeaderCollection' is marked ComVisible(true) but has the following ComVisible(false) types in its object hierarchy: 'NameValueCollection', 'NameObjectCollectionBase'</Issue>
+          </Message>
+         </Messages>
+        </Type>
+       </Types>
+      </Namespace>
+      <Namespace Name="System.Compat.Web">
+       <Types>
+        <Type Name="HttpUtility" Kind="Class" Accessibility="Public" ExternallyVisible="True">
+         <Members>
+          <Member Name="#UrlDecode(System.Byte[],System.Int32,System.Int32,System.Text.Encoding)" Kind="Method" Static="True" Accessibility="Public" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="NonExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net40\Hammock\Mono" File="HttpUtility.cs" Line="570">In method 'HttpUtility.UrlDecode(byte[], int, int, Encoding)', call System.IDisposable.Dispose on object 'acc' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#UrlDecode(System.String,System.Text.Encoding)" Kind="Method" Static="True" Accessibility="Public" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="NonExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net40\Hammock\Mono" File="HttpUtility.cs" Line="415">In method 'HttpUtility.UrlDecode(string, Encoding)', call System.IDisposable.Dispose on object 'bytes' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#UrlDecodeToBytes(System.Byte[],System.Int32,System.Int32)" Kind="Method" Static="True" Accessibility="Public" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="NonExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net40\Hammock\Mono" File="HttpUtility.cs" Line="672">In method 'HttpUtility.UrlDecodeToBytes(byte[], int, int)', call System.IDisposable.Dispose on object 'result' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#UrlEncodeToBytes(System.Byte[],System.Int32,System.Int32)" Kind="Method" Static="True" Accessibility="Public" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="NonExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net40\Hammock\Mono" File="HttpUtility.cs" Line="895">In method 'HttpUtility.UrlEncodeToBytes(byte[], int, int)', call System.IDisposable.Dispose on object 'result' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#UrlEncodeUnicodeToBytes(System.String)" Kind="Method" Static="True" Accessibility="Public" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="NonExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net40\Hammock\Mono" File="HttpUtility.cs" Line="928">In method 'HttpUtility.UrlEncodeUnicodeToBytes(string)', call System.IDisposable.Dispose on object 'result' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+          <Member Name="#UrlPathEncode(System.String)" Kind="Method" Static="True" Accessibility="Public" ExternallyVisible="True">
+           <Messages>
+            <Message TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000" Status="Active" Created="2011-04-01 04:51:20Z" FixCategory="DependsOnFix">
+             <Issue Name="NonExceptionEdge" Certainty="75" Level="Warning" Path="D:\My Dropbox\_7_Source_Code\_1_Projects\hammock-codeplex\src\net40\Hammock\Mono" File="HttpUtility.cs" Line="1177">In method 'HttpUtility.UrlPathEncode(string)', call System.IDisposable.Dispose on object 'result' before all references to it are out of scope.</Issue>
+            </Message>
+           </Messages>
+          </Member>
+         </Members>
+        </Type>
+       </Types>
+      </Namespace>
+     </Namespaces>
+    </Module>
+   </Modules>
+  </Target>
+ </Targets>
+ <Rules>
+  <Rule TypeName="ComVisibleTypeBaseTypesShouldBeComVisible" Category="Microsoft.Interoperability" CheckId="CA1405">
+   <Name>COM visible type base types should be COM visible</Name>
+   <Description>COM visible types should have an object hierarchy that is uniformly COM visible.</Description>
+   <Resolution Name="Default">{0} is marked ComVisible(true) but has the following ComVisible(false) types in its object hierarchy: {1}</Resolution>
+   <Owner />
+   <Url>http://msdn.microsoft.com/library/ms182202(VS.100).aspx</Url>
+   <Email>[none]</Email>
+   <MessageLevel Certainty="90">Error</MessageLevel>
+   <File Name="interoperabilityrules.dll" Version="10.0.0.0" />
+  </Rule>
+  <Rule TypeName="DeclareEventHandlersCorrectly" Category="Microsoft.Design" CheckId="CA1009">
+   <Name>Declare event handlers correctly</Name>
+   <Description>By convention, .NET events have two parameters that specify the event sender and event data. Event handler signatures should follow this form: void MyEventHandler(object sender, EventArgs e). The 'sender' parameter is always of type System.Object, even if it is possible to employ a more specific type. The 'e' parameter is always of type System.EventArgs. Events that do not provide event data should use the System.EventHandler delegate type. Event handlers return void so that they can send each event to multiple target methods. Any value returned by a target would be lost after the first call.</Description>
+   <Resolution Name="First">Declare the first parameter of {0} as an object named 'sender'.</Resolution>
+   <Resolution Name="Second">Declare the second parameter of {0} as an EventArgs, or an instance of a type that extends EventArgs, named 'e'.</Resolution>
+   <Owner />
+   <Url>http://msdn.microsoft.com/library/ms182133(VS.100).aspx</Url>
+   <Email>[none]</Email>
+   <MessageLevel Certainty="95">Error</MessageLevel>
+   <File Name="designrules.dll" Version="10.0.0.0" />
+  </Rule>
+  <Rule TypeName="DisposableFieldsShouldBeDisposed" Category="Microsoft.Usage" CheckId="CA2213">
+   <Name>Disposable fields should be disposed</Name>
+   <Description>If a type that implements IDisposable owns fields that also implement IDisposable, the encapsulating type's Dispose() implementation should call Dispose() on each disposable field.</Description>
+   <Resolution Name="Default">{0} contains field {1} that is of IDisposable type: {2}. Change the Dispose method on {0} to call Dispose or Close on this field.</Resolution>
+   <Owner />
+   <Url>http://msdn.microsoft.com/library/ms182328(VS.100).aspx</Url>
+   <Email>[none]</Email>
+   <MessageLevel Certainty="75">Warning</MessageLevel>
+   <File Name="usagerules.dll" Version="10.0.0.0" />
+  </Rule>
+  <Rule TypeName="Dispose objects before losing scope" Category="Microsoft.Reliability" CheckId="CA2000">
+   <Name>Dispose objects before losing scope</Name>
+   <Description>If a disposable object is not explicitly disposed before all references to it are out of scope, the object will be disposed at some indeterminate time when the garbage collector runs the finalizer of the object. Because an exceptional event might occur that will prevent the finalizer of the object from running, the object should be explicitly disposed instead.</Description>
+   <Resolution Name="ExceptionEdge">In method {0}, object {1} is not disposed along all exception paths. Call System.IDisposable.Dispose on object {1} before all references to it are out of scope.</Resolution>
+   <Resolution Name="NonExceptionEdge">In method {0}, call System.IDisposable.Dispose on object {1} before all references to it are out of scope.</Resolution>
+   <Owner>RuleOwner</Owner>
+   <Url>http://msdn.microsoft.com/library/ms182289(VS.100).aspx</Url>
+   <Email />
+   <MessageLevel Certainty="75">Warning</MessageLevel>
+   <File Name="dataflowrules.dll" Version="10.0.0.0" />
+  </Rule>
+  <Rule TypeName="Do not dispose objects multiple times" Category="Microsoft.Usage" CheckId="CA2202">
+   <Name>Do not dispose objects multiple times</Name>
+   <Description>A correctly implemented Dispose method can be called multiple times without throwing an exception. However, this is not guaranteed and to avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object.</Description>
+   <Resolution Name="Default">Object {0} can be disposed more than once in method {1}. To avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object.: Lines: 1007</Resolution>
+   <Owner>RuleOwner</Owner>
+   <Url>http://msdn.microsoft.com/library/ms182334(VS.100).aspx</Url>
+   <Email />
+   <MessageLevel Certainty="75">Warning</MessageLevel>
+   <File Name="dataflowrules.dll" Version="10.0.0.0" />
+  </Rule>
+  <Rule TypeName="DoNotCallOverridableMethodsInConstructors" Category="Microsoft.Usage" CheckId="CA2214">
+   <Name>Do not call overridable methods in constructors</Name>
+   <Description>Virtual methods defined on the class should not be called from constructors. If a derived class has overridden the method, the derived class version will be called (before the derived class constructor is called).</Description>
+   <Resolution Name="Default">{0} contains a call chain that results in a call to a virtual method defined by the class. Review the following call stack for unintended consequences: {1}</Resolution>
+   <Owner />
+   <Url>http://msdn.microsoft.com/library/ms182331(VS.100).aspx</Url>
+   <Email>[none]</Email>
+   <MessageLevel Certainty="95">CriticalWarning</MessageLevel>
+   <File Name="usagerules.dll" Version="10.0.0.0" />
+  </Rule>
+  <Rule TypeName="ImplementIDisposableCorrectly" Category="Microsoft.Design" CheckId="CA1063">
+   <Name>Implement IDisposable correctly</Name>
+   <Description>All IDisposable types should implement the Dispose pattern correctly.</Description>
+   <Resolution Name="DisposeImplementation">Modify {0} so that it calls Dispose(true), then calls GC.SuppressFinalize on the current object instance ('this' or 'Me' in Visual Basic), and then returns.</Resolution>
+   <Resolution Name="DisposeSignature">Ensure that {0} is declared as public and sealed.</Resolution>
+   <Resolution Name="ProvideDisposeBool">Provide an overridable implementation of Dispose(bool) on {0} or mark the type as sealed. A call to Dispose(false) should only clean up native resources. A call to Dispose(true) should clean up both managed and native resources.</Resolution>
+   <Owner />
+   <Url>http://msdn.microsoft.com/library/ms244737(VS.100).aspx</Url>
+   <Email>[none]</Email>
+   <MessageLevel Certainty="95">Error</MessageLevel>
+   <File Name="designrules.dll" Version="10.0.0.0" />
+  </Rule>
+  <Rule TypeName="MarkAllNonSerializableFields" Category="Microsoft.Usage" CheckId="CA2235">
+   <Name>Mark all non-serializable fields</Name>
+   <Description>All fields that cannot be serialized directly should have the NonSerializedAttribute. Types that have the SerializableAttribute should not have fields of types that do not have the SerializableAttribute unless the fields are marked with the NonSerializedAttribute.</Description>
+   <Resolution Name="Default">Field {0} is a member of type {1}, which is serializable, but is of type {2}, which is not serializable. Add the NonSerializedAttribute to {0}.</Resolution>
+   <Owner />
+   <Url>http://msdn.microsoft.com/library/ms182349(VS.100).aspx</Url>
+   <Email>[none]</Email>
+   <MessageLevel Certainty="95">Error</MessageLevel>
+   <File Name="usagerules.dll" Version="10.0.0.0" />
+  </Rule>
+  <Rule TypeName="MarkISerializableTypesWithSerializable" Category="Microsoft.Usage" CheckId="CA2237">
+   <Name>Mark ISerializable types with SerializableAttribute</Name>
+   <Description>The System.Runtime.Serialization.ISerializable interface allows the type to customize its serialization, while the Serializable attribute enables the runtime to recognize the type as being serializable.</Description>
+   <Resolution Name="Default">Add [Serializable] to {0} as this type implements ISerializable.</Resolution>
+   <Owner />
+   <Url>http://msdn.microsoft.com/library/ms182350(VS.100).aspx</Url>
+   <Email>[none]</Email>
+   <MessageLevel Certainty="75">Warning</MessageLevel>
+   <File Name="usagerules.dll" Version="10.0.0.0" />
+  </Rule>
+ </Rules>
+ <Localized>
+  <String Key="Category">Category</String>
+  <String Key="Certainty">Certainty</String>
+  <String Key="CollapseAll">Collapse All</String>
+  <String Key="CheckId">Check Id</String>
+  <String Key="Error">Error</String>
+  <String Key="Errors">error(s)</String>
+  <String Key="ExpandAll">Expand All</String>
+  <String Key="Help">Help</String>
+  <String Key="Line">Line</String>
+  <String Key="Messages">message(s)</String>
+  <String Key="LocationNotStoredInPdb">[Location not stored in Pdb]</String>
+  <String Key="Project">Project</String>
+  <String Key="Resolution">Resolution</String>
+  <String Key="Rule">Rule</String>
+  <String Key="RuleFile">Rule File</String>
+  <String Key="RuleDescription">Rule Description</String>
+  <String Key="Source">Source</String>
+  <String Key="Status">Status</String>
+  <String Key="Target">Target</String>
+  <String Key="Warning">Warning</String>
+  <String Key="Warnings">warning(s)</String>
+  <String Key="ReportTitle">Code Analysis Report</String>
+ </Localized>
+</FxCopReport>
diff --git a/trunk/packages/Hammock.1.2.3/lib/net40/Hammock.dll.lastcodeanalysissucceeded b/trunk/packages/Hammock.1.2.3/lib/net40/Hammock.dll.lastcodeanalysissucceeded
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl3/Hammock.Silverlight.dll b/trunk/packages/Hammock.1.2.3/lib/sl3/Hammock.Silverlight.dll
new file mode 100644 (file)
index 0000000..b0e2303
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl3/Hammock.Silverlight.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl3/ICSharpCode.SharpZipLib.Silverlight.dll b/trunk/packages/Hammock.1.2.3/lib/sl3/ICSharpCode.SharpZipLib.Silverlight.dll
new file mode 100644 (file)
index 0000000..538aea8
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl3/ICSharpCode.SharpZipLib.Silverlight.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl3/System.Runtime.Serialization.Json.dll b/trunk/packages/Hammock.1.2.3/lib/sl3/System.Runtime.Serialization.Json.dll
new file mode 100644 (file)
index 0000000..46b4cfb
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl3/System.Runtime.Serialization.Json.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl3/System.Runtime.Serialization.Json.xml b/trunk/packages/Hammock.1.2.3/lib/sl3/System.Runtime.Serialization.Json.xml
new file mode 100644 (file)
index 0000000..8ebcdbd
--- /dev/null
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<doc>
+  <assembly>
+    <name>System.Runtime.Serialization.Json</name>
+  </assembly>
+  <members>
+    <member name="T:System.Runtime.Serialization.Json.JsonReaderWriterFactory">
+      <summary>Produces instances of <see cref="T:System.Xml.XmlDictionaryReader" /> that can read data encoded with JavaScript Object Notation (JSON) from a stream or buffer and map it to an XML Infoset, and produces instances of <see cref="T:System.Xml.XmlDictionaryWriter" /> that can map an XML Infoset to JSON and write JSON-encoded data to a stream. </summary>
+    </member>
+    <member name="M:System.Runtime.Serialization.Json.JsonReaderWriterFactory.CreateJsonReader(System.Byte[],System.Int32,System.Int32,System.Xml.XmlDictionaryReaderQuotas)">
+      <summary>Creates an <see cref="T:System.Xml.XmlDictionaryReader" /> that can map a buffer encoded with JavaScript Object Notation (JSON), of a specified size and offset, to an XML Infoset.</summary>
+      <returns>An <see cref="T:System.Xml.XmlDictionaryReader" /> that can read JSON.</returns>
+      <param name="buffer">The input <see cref="T:System.Byte" /> buffer array from which to read.</param>
+      <param name="offset">Starting position from which to read in <paramref name="buffer" />.</param>
+      <param name="count">Number of bytes that can be read from <paramref name="buffer" />.</param>
+      <param name="quotas">The <see cref="T:System.Xml.XmlDictionaryReaderQuotas" /> must be set to <see cref="P:System.Xml.XmlDictionaryReaderQuotas.Max" /> in Silverlight version 3 applications.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="stream" /> is null.</exception>
+      <exception cref="T:System.ArgumentOutOfRangeException">
+        <paramref name="offset" /> is negative or exceeds the <paramref name="buffer" /> length.</exception>
+      <exception cref="T:System.ArgumentOutOfRangeException">
+        <paramref name="count" /> is negative or exceeds the <paramref name="buffer" /> length minus the <paramref name="offset" />.</exception>
+    </member>
+    <member name="M:System.Runtime.Serialization.Json.JsonReaderWriterFactory.CreateJsonReader(System.Byte[],System.Xml.XmlDictionaryReaderQuotas)">
+      <summary>Creates an <see cref="T:System.Xml.XmlDictionaryReader" /> that can map a specified buffer encoded with JavaScript Object Notation (JSON) to an XML Infoset.</summary>
+      <returns>An <see cref="T:System.Xml.XmlDictionaryReader" /> that can process JavaScript Object Notation (JSON) data from the buffer specified.</returns>
+      <param name="buffer">The input <see cref="T:System.Byte" /> buffer array from which to read.</param>
+      <param name="quotas">The <see cref="T:System.Xml.XmlDictionaryReaderQuotas" /> must be set to <see cref="P:System.Xml.XmlDictionaryReaderQuotas.Max" /> in Silverlight version 3 applications used to prevent Denial of Service (DoS) attacks when reading untrusted data. </param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="buffer" /> is null.</exception>
+    </member>
+    <member name="M:System.Runtime.Serialization.Json.JsonReaderWriterFactory.CreateJsonReader(System.IO.Stream,System.Xml.XmlDictionaryReaderQuotas)">
+      <summary>Creates an <see cref="T:System.Xml.XmlDictionaryReader" /> that can map a specified stream encoded with JavaScript Object Notation (JSON) to an XML Infoset.</summary>
+      <returns>An <see cref="T:System.Xml.XmlDictionaryReader" /> that can read JSON.</returns>
+      <param name="stream">The input <see cref="T:System.IO.Stream" /> from which to read.</param>
+      <param name="quotas">The <see cref="T:System.Xml.XmlDictionaryReaderQuotas" /> must be set to <see cref="P:System.Xml.XmlDictionaryReaderQuotas.Max" /> in Silverlight version 3 applications. </param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="stream" /> is null.</exception>
+    </member>
+    <member name="M:System.Runtime.Serialization.Json.JsonReaderWriterFactory.CreateJsonWriter(System.IO.Stream)">
+      <summary>Creates an <see cref="T:System.Xml.XmlDictionaryWriter" /> that writes data encoded with JSON to a stream using a UTF-8 character encoding.</summary>
+      <returns>An <see cref="T:System.Xml.XmlDictionaryWriter" /> that writes data encoded with JSON to the stream from an XML Infoset.</returns>
+      <param name="stream">The output <see cref="T:System.IO.Stream" /> for the JSON writer.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="stream" /> is null.</exception>
+    </member>
+    <member name="M:System.Runtime.Serialization.Json.JsonReaderWriterFactory.CreateJsonWriter(System.IO.Stream,System.Text.Encoding)">
+      <summary>Creates an <see cref="T:System.Xml.XmlDictionaryWriter" /> that writes data encoded with JSON to a stream with a specified character encoding.</summary>
+      <returns>An <see cref="T:System.Xml.XmlDictionaryWriter" /> that writes data encoded with JSON to the stream from an XML Infoset.</returns>
+      <param name="stream">The output <see cref="T:System.IO.Stream" /> for the JSON writer.</param>
+      <param name="encoding">The <see cref="T:System.Text.Encoding" /> that specifies the character encoding used by the writer. The default encoding is UTF-8.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="stream" /> or <paramref name="encoding" /> is null.</exception>
+    </member>
+    <member name="M:System.Runtime.Serialization.Json.JsonReaderWriterFactory.CreateJsonWriter(System.IO.Stream,System.Text.Encoding,System.Boolean)">
+      <summary>Creates an <see cref="T:System.Xml.XmlDictionaryWriter" /> that writes data encoded with JSON to a stream with a specified character encoding and that specifies whether the output stream is closed by the writer when it is done.</summary>
+      <returns>An <see cref="T:System.Xml.XmlDictionaryWriter" /> that writes data encoded with JSON to the stream from an XML Infoset.</returns>
+      <param name="stream">The output <see cref="T:System.IO.Stream" /> for the JSON writer.</param>
+      <param name="encoding">The <see cref="T:System.Text.Encoding" /> that specifies the character encoding used by the writer. The default encoding is UTF-8.</param>
+      <param name="ownsStream">If true, the output stream is closed by the writer when done; otherwise, false. The default value is true.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="stream" /> or <paramref name="encoding" /> is null.</exception>
+    </member>
+  </members>
+</doc>
\ No newline at end of file
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl3/System.Xml.Linq.dll b/trunk/packages/Hammock.1.2.3/lib/sl3/System.Xml.Linq.dll
new file mode 100644 (file)
index 0000000..35611d8
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl3/System.Xml.Linq.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl3/System.Xml.Linq.xml b/trunk/packages/Hammock.1.2.3/lib/sl3/System.Xml.Linq.xml
new file mode 100644 (file)
index 0000000..b003380
--- /dev/null
@@ -0,0 +1,1632 @@
+<?xml version="1.0" encoding="utf-8"?>
+<doc>
+  <assembly>
+    <name>System.Xml.Linq</name>
+  </assembly>
+  <members>
+    <member name="T:System.Xml.Linq.Extensions">
+      <summary>Contains the LINQ to XML extension methods.</summary>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.Ancestors``1(System.Collections.Generic.IEnumerable{``0})">
+      <summary>Returns a collection of elements that contains the ancestors of every node in the source collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains the ancestors of every node in the source collection.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XNode" /> that contains the source collection.</param>
+      <typeparam name="T">The type of the objects in <paramref name="source" />, constrained to <see cref="T:System.Xml.Linq.XNode" />.</typeparam>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.Ancestors``1(System.Collections.Generic.IEnumerable{``0},System.Xml.Linq.XName)">
+      <summary>Returns a filtered collection of elements that contains the ancestors of every node in the source collection. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains the ancestors of every node in the source collection. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XNode" /> that contains the source collection.</param>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> to match.</param>
+      <typeparam name="T">The type of the objects in <paramref name="source" />, constrained to <see cref="T:System.Xml.Linq.XNode" />.</typeparam>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.AncestorsAndSelf(System.Collections.Generic.IEnumerable{System.Xml.Linq.XElement})">
+      <summary>Returns a collection of elements that contains every element in the source collection, and the ancestors of every element in the source collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains every element in the source collection, and the ancestors of every element in the source collection.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains the source collection.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.AncestorsAndSelf(System.Collections.Generic.IEnumerable{System.Xml.Linq.XElement},System.Xml.Linq.XName)">
+      <summary>Returns a filtered collection of elements that contains every element in the source collection, and the ancestors of every element in the source collection. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains every element in the source collection, and the ancestors of every element in the source collection. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains the source collection.</param>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> to match.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.Attributes(System.Collections.Generic.IEnumerable{System.Xml.Linq.XElement})">
+      <summary>Returns a collection of the attributes of every element in the source collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XAttribute" /> that contains the attributes of every element in the source collection.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains the source collection.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.Attributes(System.Collections.Generic.IEnumerable{System.Xml.Linq.XElement},System.Xml.Linq.XName)">
+      <summary>Returns a filtered collection of the attributes of every element in the source collection. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XAttribute" /> that contains a filtered collection of the attributes of every element in the source collection. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains the source collection.</param>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> to match.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.DescendantNodes``1(System.Collections.Generic.IEnumerable{``0})">
+      <summary>Returns a collection of the descendant nodes of every document and element in the source collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XNode" /> of the descendant nodes of every document and element in the source collection.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XContainer" /> that contains the source collection.</param>
+      <typeparam name="T">The type of the objects in <paramref name="source" />, constrained to <see cref="T:System.Xml.Linq.XContainer" />.</typeparam>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.DescendantNodesAndSelf(System.Collections.Generic.IEnumerable{System.Xml.Linq.XElement})">
+      <summary>Returns a collection of nodes that contains every element in the source collection, and the descendant nodes of every element in the source collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XNode" /> that contains every element in the source collection, and the descendant nodes of every element in the source collection.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains the source collection.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.Descendants``1(System.Collections.Generic.IEnumerable{``0})">
+      <summary>Returns a collection of elements that contains the descendant elements of every element and document in the source collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains the descendant elements of every element and document in the source collection.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XContainer" /> that contains the source collection.</param>
+      <typeparam name="T">The type of the objects in <paramref name="source" />, constrained to <see cref="T:System.Xml.Linq.XContainer" />.</typeparam>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.Descendants``1(System.Collections.Generic.IEnumerable{``0},System.Xml.Linq.XName)">
+      <summary>Returns a filtered collection of elements that contains the descendant elements of every element and document in the source collection. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains the descendant elements of every element and document in the source collection. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XContainer" /> that contains the source collection.</param>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> to match.</param>
+      <typeparam name="T">The type of the objects in <paramref name="source" />, constrained to <see cref="T:System.Xml.Linq.XContainer" />.</typeparam>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.DescendantsAndSelf(System.Collections.Generic.IEnumerable{System.Xml.Linq.XElement})">
+      <summary>Returns a collection of elements that contains every element in the source collection, and the descendent elements of every element in the source collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains every element in the source collection, and the descendent elements of every element in the source collection.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains the source collection.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.DescendantsAndSelf(System.Collections.Generic.IEnumerable{System.Xml.Linq.XElement},System.Xml.Linq.XName)">
+      <summary>Returns a filtered collection of elements that contains every element in the source collection, and the descendents of every element in the source collection. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains every element in the source collection, and the descendents of every element in the source collection. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains the source collection.</param>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> to match.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.Elements``1(System.Collections.Generic.IEnumerable{``0})">
+      <summary>Returns a collection of the child elements of every element and document in the source collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> of the child elements of every element or document in the source collection.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains the source collection.</param>
+      <typeparam name="T">The type of the objects in <paramref name="source" />, constrained to <see cref="T:System.Xml.Linq.XContainer" />.</typeparam>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.Elements``1(System.Collections.Generic.IEnumerable{``0},System.Xml.Linq.XName)">
+      <summary>Returns a filtered collection of the child elements of every element and document in the source collection. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> of the child elements of every element and document in the source collection. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains the source collection.</param>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> to match.</param>
+      <typeparam name="T">The type of the objects in <paramref name="source" />, constrained to <see cref="T:System.Xml.Linq.XContainer" />.</typeparam>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.InDocumentOrder``1(System.Collections.Generic.IEnumerable{``0})">
+      <summary>Returns a collection of nodes that contains all nodes in the source collection, sorted in document order.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XNode" /> that contains all nodes in the source collection, sorted in document order.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XNode" /> that contains the source collection.</param>
+      <typeparam name="T">The type of the objects in <paramref name="source" />, constrained to <see cref="T:System.Xml.Linq.XNode" />.</typeparam>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.Nodes``1(System.Collections.Generic.IEnumerable{``0})">
+      <summary>Returns a collection of the child nodes of every document and element in the source collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XNode" /> of the child nodes of every document and element in the source collection.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XNode" /> that contains the source collection.</param>
+      <typeparam name="T">The type of the objects in <paramref name="source" />, constrained to <see cref="T:System.Xml.Linq.XContainer" />.</typeparam>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.Remove(System.Collections.Generic.IEnumerable{System.Xml.Linq.XAttribute})">
+      <summary>Removes every attribute in the source collection from its parent element.</summary>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XAttribute" /> that contains the source collection.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.Remove``1(System.Collections.Generic.IEnumerable{``0})">
+      <summary>Removes every node in the source collection from its parent node.</summary>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XNode" /> that contains the source collection.</param>
+      <typeparam name="T">The type of the objects in <paramref name="source" />, constrained to <see cref="T:System.Xml.Linq.XNode" />.</typeparam>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="T:System.Xml.Linq.LoadOptions">
+      <summary>Specifies load options when parsing XML.  </summary>
+    </member>
+    <member name="F:System.Xml.Linq.LoadOptions.None">
+      <summary>Does not preserve insignificant white space or load base URI and line information.</summary>
+    </member>
+    <member name="F:System.Xml.Linq.LoadOptions.PreserveWhitespace">
+      <summary>Preserves insignificant white space while parsing.</summary>
+    </member>
+    <member name="F:System.Xml.Linq.LoadOptions.SetBaseUri">
+      <summary>Requests the base URI information from the <see cref="T:System.Xml.XmlReader" />, and makes it available via the <see cref="P:System.Xml.Linq.XObject.BaseUri" /> property.</summary>
+    </member>
+    <member name="F:System.Xml.Linq.LoadOptions.SetLineInfo">
+      <summary>Requests the line information from the <see cref="T:System.Xml.XmlReader" /> and makes it available via properties on <see cref="T:System.Xml.Linq.XObject" />.</summary>
+    </member>
+    <member name="T:System.Xml.Linq.ReaderOptions">
+      <summary>Specifies whether to omit duplicate namespaces when loading an <see cref="T:System.Xml.Linq.XDocument" /> with an <see cref="T:System.Xml.XmlReader" />.</summary>
+    </member>
+    <member name="F:System.Xml.Linq.ReaderOptions.None">
+      <summary>No reader options specified.</summary>
+    </member>
+    <member name="F:System.Xml.Linq.ReaderOptions.OmitDuplicateNamespaces">
+      <summary>Omit duplicate namespaces when loading the <see cref="T:System.Xml.Linq.XDocument" />.</summary>
+    </member>
+    <member name="T:System.Xml.Linq.SaveOptions">
+      <summary>Specifies serialization options. </summary>
+    </member>
+    <member name="F:System.Xml.Linq.SaveOptions.None">
+      <summary>Formats (indent) the XML while serializing.</summary>
+    </member>
+    <member name="F:System.Xml.Linq.SaveOptions.DisableFormatting">
+      <summary>Preserves all insignificant white space while serializing.</summary>
+    </member>
+    <member name="F:System.Xml.Linq.SaveOptions.OmitDuplicateNamespaces">
+      <summary>Removes duplicate namespace declarations. For the duplicate namespace declarations to be removed, both the prefix and the namespace have to match.</summary>
+    </member>
+    <member name="T:System.Xml.Linq.XAttribute">
+      <summary>Represents an XML attribute.</summary>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.#ctor(System.Xml.Linq.XAttribute)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XAttribute" /> class from another <see cref="T:System.Xml.Linq.XAttribute" /> object. </summary>
+      <param name="other">An <see cref="T:System.Xml.Linq.XAttribute" /> object to copy from.</param>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="other" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.#ctor(System.Xml.Linq.XName,System.Object)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XAttribute" /> class from the specified name and value. </summary>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> of the attribute.</param>
+      <param name="value">An <see cref="T:System.Object" /> containing the value of the attribute.</param>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="name" /> or <paramref name="value" /> parameter is null.</exception>
+    </member>
+    <member name="P:System.Xml.Linq.XAttribute.EmptySequence">
+      <summary>Gets an empty collection of attributes.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XAttribute" /> containing an empty collection.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XAttribute.IsNamespaceDeclaration">
+      <summary>Determines if this attribute is a namespace declaration.</summary>
+      <returns>true if this attribute is a namespace declaration; otherwise false.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XAttribute.Name">
+      <summary>Gets the expanded name of this attribute.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XName" /> containing the name of this attribute.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XAttribute.NextAttribute">
+      <summary>Gets the next attribute of the parent element.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XAttribute" /> containing the next attribute of the parent element.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XAttribute.NodeType">
+      <summary>Gets the node type for this node.</summary>
+      <returns>The node type. For <see cref="T:System.Xml.Linq.XAttribute" /> objects, this value is <see cref="F:System.Xml.XmlNodeType.Attribute" />.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.DateTime">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.DateTime" />.</summary>
+      <returns>A <see cref="T:System.DateTime" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.DateTime" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.DateTime" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="attribute" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Nullable{System.DateTime}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.DateTime" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.DateTime" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.DateTime" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.DateTime" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Nullable{System.Decimal}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Decimal" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.Decimal" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.Nullable`1" /> of <see cref="T:System.Decimal" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.Decimal" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Nullable{System.Double}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Double" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.Double" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.Nullable`1" /> of <see cref="T:System.Double" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.Double" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Decimal">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Decimal" />.</summary>
+      <returns>A <see cref="T:System.Decimal" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.Decimal" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.Decimal" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="attribute" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.DateTimeOffset">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.DateTimeOffset" />.</summary>
+      <returns>A <see cref="T:System.DateTimeOffset" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.DateTimeOffset" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.DateTimeOffset" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="attribute" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Guid">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Guid" />.</summary>
+      <returns>A <see cref="T:System.Guid" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.Guid" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.Guid" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="attribute" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Nullable{System.Guid}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Guid" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.Guid" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Guid" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.Guid" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Nullable{System.TimeSpan}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.TimeSpan" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.TimeSpan" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.TimeSpan" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.TimeSpan" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Nullable{System.DateTimeOffset}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.DateTimeOffset" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.DateTimeOffset" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.DateTimeOffset" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.DateTimeOffset" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.TimeSpan">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.TimeSpan" />.</summary>
+      <returns>A <see cref="T:System.TimeSpan" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.TimeSpan" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.TimeSpan" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="attribute" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Double">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Double" />.</summary>
+      <returns>A <see cref="T:System.Double" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.Double" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.Double" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="attribute" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Int32">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to an <see cref="T:System.Int32" />.</summary>
+      <returns>A <see cref="T:System.Int32" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.Int32" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.Int32" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="attribute" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Nullable{System.Int32}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Int32" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.Int32" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Int32" />.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.UInt32">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.UInt32" />.</summary>
+      <returns>A <see cref="T:System.UInt32" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.UInt32" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.UInt32" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="attribute" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.String">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.String" />.</summary>
+      <returns>A <see cref="T:System.String" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.String" />.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Boolean">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Boolean" />.</summary>
+      <returns>A <see cref="T:System.Boolean" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.Boolean" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.Boolean" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="attribute" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Nullable{System.Boolean}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Boolean" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.Boolean" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.Nullable`1" /> of <see cref="T:System.Boolean" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.Boolean" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Nullable{System.UInt32}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.UInt32" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.UInt32" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.UInt32" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.UInt32" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Nullable{System.UInt64}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.UInt64" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.UInt64" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.UInt64" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.UInt64" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Single">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Single" />.</summary>
+      <returns>A <see cref="T:System.Single" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.Single" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.Single" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="attribute" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Nullable{System.Single}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Single" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.Single" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.Nullable`1" /> of <see cref="T:System.Single" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.Single" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Int64">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to an <see cref="T:System.Int64" />.</summary>
+      <returns>A <see cref="T:System.Int64" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.Int64" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.Int64" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="attribute" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Nullable{System.Int64}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Int64" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.Int64" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Int64" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.Int64" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.UInt64">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.UInt64" />.</summary>
+      <returns>A <see cref="T:System.UInt64" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.UInt64" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.UInt64" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="attribute" /> parameter is null.</exception>
+    </member>
+    <member name="P:System.Xml.Linq.XAttribute.PreviousAttribute">
+      <summary>Gets the previous attribute of the parent element.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XAttribute" /> containing the previous attribute of the parent element.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.Remove">
+      <summary>Removes this attribute from its parent element.</summary>
+      <exception cref="T:System.InvalidOperationException">The parent element is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.SetValue(System.Object)">
+      <summary>Sets the value of this attribute.</summary>
+      <param name="value">The value to assign to this attribute.</param>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="value" /> parameter is null.</exception>
+      <exception cref="T:System.ArgumentException">The <paramref name="value" /> is an <see cref="T:System.Xml.Linq.XObject" />.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.ToString">
+      <summary>Converts the current <see cref="T:System.Xml.Linq.XAttribute" /> object to a string representation.</summary>
+      <returns>A <see cref="T:System.String" /> containing the XML text representation of an attribute and its value.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XAttribute.Value">
+      <summary>Gets or sets the value of this attribute.</summary>
+      <returns>A <see cref="T:System.String" /> containing the value of this attribute.</returns>
+      <exception cref="T:System.ArgumentNullException">When setting, the <paramref name="value" /> is null.</exception>
+    </member>
+    <member name="T:System.Xml.Linq.XCData">
+      <summary>Represents a text node that contains CDATA.  </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XCData.#ctor(System.String)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XCData" /> class. </summary>
+      <param name="value">A string that contains the value of the <see cref="T:System.Xml.Linq.XCData" /> node.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XCData.#ctor(System.Xml.Linq.XCData)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XCData" /> class. </summary>
+      <param name="other">The <see cref="T:System.Xml.Linq.XCData" /> node to copy from.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XCData.NodeType">
+      <summary>Gets the node type for this node.</summary>
+      <returns>The node type. For <see cref="T:System.Xml.Linq.XCData" /> objects, this value is <see cref="F:System.Xml.XmlNodeType.CDATA" />.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XCData.WriteTo(System.Xml.XmlWriter)">
+      <summary>Writes this CDATA object to an <see cref="T:System.Xml.XmlWriter" />.</summary>
+      <param name="writer">An <see cref="T:System.Xml.XmlWriter" /> into which this method will write.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="writer" /> is null.</exception>
+    </member>
+    <member name="T:System.Xml.Linq.XComment">
+      <summary>Represents an XML comment. </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XComment.#ctor(System.String)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XComment" /> class with the specified string content. </summary>
+      <param name="value">A string that contains the contents of the new <see cref="T:System.Xml.Linq.XComment" /> object.</param>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="value" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XComment.#ctor(System.Xml.Linq.XComment)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XComment" /> class from an existing comment node. </summary>
+      <param name="other">The <see cref="T:System.Xml.Linq.XComment" /> node to copy from.</param>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="other" /> parameter is null.</exception>
+    </member>
+    <member name="P:System.Xml.Linq.XComment.NodeType">
+      <summary>Gets the node type for this node.</summary>
+      <returns>The node type. For <see cref="T:System.Xml.Linq.XComment" /> objects, this value is <see cref="F:System.Xml.XmlNodeType.Comment" />.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XComment.Value">
+      <summary>Gets or sets the string value of this comment.</summary>
+      <returns>A <see cref="T:System.String" /> that contains the string value of this comment.</returns>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="value" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XComment.WriteTo(System.Xml.XmlWriter)">
+      <summary>Write this comment to an <see cref="T:System.Xml.XmlWriter" />.</summary>
+      <param name="writer">An <see cref="T:System.Xml.XmlWriter" /> into which this method will write.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="writer" /> is null.</exception>
+    </member>
+    <member name="T:System.Xml.Linq.XContainer">
+      <summary>Represents a node that can contain other nodes.</summary>
+    </member>
+    <member name="M:System.Xml.Linq.XContainer.Add(System.Object)">
+      <summary>Adds the specified content as children of this <see cref="T:System.Xml.Linq.XContainer" />.</summary>
+      <param name="content">A content object containing simple content or a collection of content objects to be added.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XContainer.Add(System.Object[])">
+      <summary>Adds the specified content as children of this <see cref="T:System.Xml.Linq.XContainer" />.</summary>
+      <param name="content">A parameter list of content objects.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XContainer.AddFirst(System.Object)">
+      <summary>Adds the specified content as the first children of this document or element.</summary>
+      <param name="content">A content object containing simple content or a collection of content objects to be added.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XContainer.AddFirst(System.Object[])">
+      <summary>Adds the specified content as the first children of this document or element.</summary>
+      <param name="content">A parameter list of content objects.</param>
+      <exception cref="T:System.InvalidOperationException">The parent is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XContainer.CreateWriter">
+      <summary>Creates an <see cref="T:System.Xml.XmlWriter" /> that can be used to add nodes to the <see cref="T:System.Xml.Linq.XContainer" />.</summary>
+      <returns>An <see cref="T:System.Xml.XmlWriter" /> that is ready to have content written to it.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XContainer.DescendantNodes">
+      <summary>Returns a collection of the descendant nodes for this document or element, in document order.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XNode" /> containing the descendant nodes of the <see cref="T:System.Xml.Linq.XContainer" />, in document order.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XContainer.Descendants">
+      <summary>Returns a collection of the descendant elements for this document or element, in document order.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> containing the descendant elements of the <see cref="T:System.Xml.Linq.XContainer" />.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XContainer.Descendants(System.Xml.Linq.XName)">
+      <summary>Returns a filtered collection of the descendant elements for this document or element, in document order. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> containing the descendant elements of the <see cref="T:System.Xml.Linq.XContainer" /> that match the specified <see cref="T:System.Xml.Linq.XName" />.</returns>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> to match.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XContainer.Element(System.Xml.Linq.XName)">
+      <summary>Gets the first (in document order) child element with the specified <see cref="T:System.Xml.Linq.XName" />.</summary>
+      <returns>A <see cref="T:System.Xml.Linq.XElement" /> that matches the specified <see cref="T:System.Xml.Linq.XName" />, or null.</returns>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> to match.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XContainer.Elements">
+      <summary>Returns a collection of the child elements of this element or document, in document order.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> containing the child elements of this <see cref="T:System.Xml.Linq.XContainer" />, in document order.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XContainer.Elements(System.Xml.Linq.XName)">
+      <summary>Returns a filtered collection of the child elements of this element or document, in document order. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> containing the children of the <see cref="T:System.Xml.Linq.XContainer" /> that have a matching <see cref="T:System.Xml.Linq.XName" />, in document order.</returns>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> to match.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XContainer.FirstNode">
+      <summary>Get the first child node of this node.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XNode" /> containing the first child node of the <see cref="T:System.Xml.Linq.XContainer" />.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XContainer.LastNode">
+      <summary>Get the last child node of this node.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XNode" /> containing the last child node of the <see cref="T:System.Xml.Linq.XContainer" />.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XContainer.Nodes">
+      <summary>Returns a collection of the child nodes of this element or document, in document order.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XNode" /> containing the contents of this <see cref="T:System.Xml.Linq.XContainer" />, in document order.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XContainer.RemoveNodes">
+      <summary>Removes the child nodes from this document or element.</summary>
+    </member>
+    <member name="M:System.Xml.Linq.XContainer.ReplaceNodes(System.Object)">
+      <summary>Replaces the children nodes of this document or element with the specified content.</summary>
+      <param name="content">A content object containing simple content or a collection of content objects that replace the children nodes.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XContainer.ReplaceNodes(System.Object[])">
+      <summary>Replaces the children nodes of this document or element with the specified content.</summary>
+      <param name="content">A parameter list of content objects.</param>
+    </member>
+    <member name="T:System.Xml.Linq.XDeclaration">
+      <summary>Represents an XML declaration. </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XDeclaration.#ctor(System.String,System.String,System.String)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XDeclaration" /> class with the specified version, encoding, and standalone status.</summary>
+      <param name="version">The version of the XML, usually "1.0".</param>
+      <param name="encoding">The encoding for the XML document.</param>
+      <param name="standalone">A string containing "yes" or "no" that specifies whether the XML is standalone or requires external entities to be resolved.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDeclaration.#ctor(System.Xml.Linq.XDeclaration)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XDeclaration" /> class from another <see cref="T:System.Xml.Linq.XDeclaration" /> object. </summary>
+      <param name="other">The <see cref="T:System.Xml.Linq.XDeclaration" /> used to initialize this <see cref="T:System.Xml.Linq.XDeclaration" /> object.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="other" /> is null.</exception>
+    </member>
+    <member name="P:System.Xml.Linq.XDeclaration.Encoding">
+      <summary>Gets or sets the encoding for this document.</summary>
+      <returns>A <see cref="T:System.String" /> containing the code page name for this document.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XDeclaration.Standalone">
+      <summary>Gets or sets the standalone property for this document.</summary>
+      <returns>A <see cref="T:System.String" /> containing the standalone property for this document.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XDeclaration.ToString">
+      <summary>Provides the declaration as a formatted string.</summary>
+      <returns>A <see cref="T:System.String" /> that contains the formatted XML string.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XDeclaration.Version">
+      <summary>Gets or sets the version property for this document.</summary>
+      <returns>A <see cref="T:System.String" /> containing the version property for this document.</returns>
+    </member>
+    <member name="T:System.Xml.Linq.XDocument">
+      <summary>Represents an XML document. </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.#ctor">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XDocument" /> class. </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.#ctor(System.Object[])">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XDocument" /> class with the specified content.</summary>
+      <param name="content">A parameter list of content objects to add to this document.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.#ctor(System.Xml.Linq.XDeclaration,System.Object[])">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XDocument" /> class with the specified <see cref="T:System.Xml.Linq.XDeclaration" /> and content.</summary>
+      <param name="declaration">An <see cref="T:System.Xml.Linq.XDeclaration" /> for the document.</param>
+      <param name="content">The content of the document.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.#ctor(System.Xml.Linq.XDocument)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XDocument" /> class from an existing <see cref="T:System.Xml.Linq.XDocument" /> object.</summary>
+      <param name="other">The <see cref="T:System.Xml.Linq.XDocument" /> object that will be copied.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XDocument.Declaration">
+      <summary>Gets or sets the XML declaration for this document.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XDeclaration" /> that contains the XML declaration for this document.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XDocument.DocumentType">
+      <summary>Gets the Document Type Definition (DTD) for this document.</summary>
+      <returns>A <see cref="T:System.Xml.Linq.XDocumentType" /> that contains the DTD for this document.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.Load(System.IO.Stream)">
+      <summary>Creates a new <see cref="T:System.Xml.Linq.XDocument" /> instance using the specified stream.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XDocument" /> object used to read the data contained in the stream. </returns>
+      <param name="stream">The stream containing the XML data.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.Load(System.IO.Stream,System.Xml.Linq.LoadOptions)">
+      <summary>Creates a new <see cref="T:System.Xml.Linq.XDocument" /> instance using the specified stream, optionally preserving white space, setting the base URI, and retaining line information.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XDocument" /> object used to read the data contained in the stream.</returns>
+      <param name="stream">The stream containing the XML data.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.LoadOptions" /> that specifies whether to load base URI and line information.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.Load(System.IO.TextReader)">
+      <summary>Creates a new <see cref="T:System.Xml.Linq.XDocument" /> from a <see cref="T:System.IO.TextReader" />. </summary>
+      <returns>An <see cref="T:System.Xml.Linq.XDocument" /> that contains the contents of the specified <see cref="T:System.IO.TextReader" />.</returns>
+      <param name="textReader">A <see cref="T:System.IO.TextReader" /> that contains the content for the <see cref="T:System.Xml.Linq.XDocument" />.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.Load(System.IO.TextReader,System.Xml.Linq.LoadOptions)">
+      <summary>Creates a new <see cref="T:System.Xml.Linq.XDocument" /> from a <see cref="T:System.IO.TextReader" />, optionally preserving white space, setting the base URI, and retaining line information.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XDocument" /> that contains the XML that was read from the specified <see cref="T:System.IO.TextReader" />.</returns>
+      <param name="textReader">A <see cref="T:System.IO.TextReader" /> that contains the content for the <see cref="T:System.Xml.Linq.XDocument" />.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.LoadOptions" /> that specifies white space behavior, and whether to load base URI and line information.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.Load(System.String)">
+      <summary>Creates a new <see cref="T:System.Xml.Linq.XDocument" /> from a file located in the application's XAP package.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XDocument" /> that contains the contents of the specified file.</returns>
+      <param name="uri">A URI string that references the file to be loaded into a new <see cref="T:System.Xml.Linq.XDocument" />. This file is located in the application's XAP package. If you want to download a file from some other location, follow the steps described in How to: Load an XML File from an Arbitrary URI Location with LINQ to XML.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.Load(System.String,System.Xml.Linq.LoadOptions)">
+      <summary>Creates a new <see cref="T:System.Xml.Linq.XDocument" /> from a file located in the application's XAP package, optionally preserving white space, setting the base URI, and retaining line information.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XDocument" /> that contains the contents of the specified file.</returns>
+      <param name="uri">A URI string that references the file to be loaded into a new <see cref="T:System.Xml.Linq.XDocument" />. This file is located in the application's XAP package. If you want to download a file from some other location, follow the steps described in How to: Load an XML File from an Arbitrary URI Location with LINQ to XML.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.LoadOptions" /> that specifies how white space is handled and whether to load base URI and line information.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.Load(System.Xml.XmlReader)">
+      <summary>Creates a new <see cref="T:System.Xml.Linq.XDocument" /> from an <see cref="T:System.Xml.XmlReader" />. </summary>
+      <returns>An <see cref="T:System.Xml.Linq.XDocument" /> that contains the contents of the specified <see cref="T:System.Xml.XmlReader" />.</returns>
+      <param name="reader">A <see cref="T:System.Xml.XmlReader" /> that contains the content for the <see cref="T:System.Xml.Linq.XDocument" />.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.Load(System.Xml.XmlReader,System.Xml.Linq.LoadOptions)">
+      <summary>Creates a new <see cref="T:System.Xml.Linq.XDocument" /> from an <see cref="T:System.Xml.XmlReader" />, optionally setting the base URI, and retaining line information.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XDocument" /> that contains the XML that was read from the specified <see cref="T:System.Xml.XmlReader" />.</returns>
+      <param name="reader">A <see cref="T:System.Xml.XmlReader" /> that will be read for the content of the <see cref="T:System.Xml.Linq.XDocument" />.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.LoadOptions" /> that specifies whether to load base URI and line information.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XDocument.NodeType">
+      <summary>Gets the node type for this node.</summary>
+      <returns>The node type. For <see cref="T:System.Xml.Linq.XDocument" /> objects, this value is <see cref="F:System.Xml.XmlNodeType.Document" />.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.Parse(System.String)">
+      <summary>Creates a new <see cref="T:System.Xml.Linq.XDocument" /> from a string.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XDocument" /> populated from the string that contains XML.</returns>
+      <param name="text">A string that contains XML.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.Parse(System.String,System.Xml.Linq.LoadOptions)">
+      <summary>Creates a new <see cref="T:System.Xml.Linq.XDocument" /> from a string, optionally preserving white space, setting the base URI, and retaining line information.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XDocument" /> populated from the string that contains XML.</returns>
+      <param name="text">A string that contains XML.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.LoadOptions" /> that specifies white space behavior, and whether to load base URI and line information.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XDocument.Root">
+      <summary>Gets the root element of the XML Tree for this document.</summary>
+      <returns>The root <see cref="T:System.Xml.Linq.XElement" /> of the XML tree.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.Save(System.IO.Stream)">
+      <summary>Outputs this <see cref="T:System.Xml.Linq.XDocument" /> to the specified <see cref="T:System.IO.Stream" />.</summary>
+      <param name="stream">The stream to output this <see cref="T:System.Xml.Linq.XDocument" /> to.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.Save(System.IO.Stream,System.Xml.Linq.SaveOptions)">
+      <summary>Outputs this <see cref="T:System.Xml.Linq.XDocument" /> to the specified <see cref="T:System.IO.Stream" />, optionally specifying formatting behavior.</summary>
+      <param name="stream">The stream to output this <see cref="T:System.Xml.Linq.XDocument" /> to.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.SaveOptions" /> that specifies formatting behavior.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.Save(System.IO.TextWriter)">
+      <summary>Serialize this <see cref="T:System.Xml.Linq.XDocument" /> to a <see cref="T:System.IO.TextWriter" />.</summary>
+      <param name="textWriter">A <see cref="T:System.IO.TextWriter" /> that the <see cref="T:System.Xml.Linq.XDocument" /> will be written to.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.Save(System.IO.TextWriter,System.Xml.Linq.SaveOptions)">
+      <summary>Serialize this <see cref="T:System.Xml.Linq.XDocument" /> to a <see cref="T:System.IO.TextWriter" />, optionally disabling formatting.</summary>
+      <param name="textWriter">The <see cref="T:System.IO.TextWriter" /> to output the XML to.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.SaveOptions" /> that specifies formatting behavior.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.Save(System.Xml.XmlWriter)">
+      <summary>Serialize this <see cref="T:System.Xml.Linq.XDocument" /> to an <see cref="T:System.Xml.XmlWriter" />.</summary>
+      <param name="writer">A <see cref="T:System.Xml.XmlWriter" /> that the <see cref="T:System.Xml.Linq.XDocument" /> will be written to.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.WriteTo(System.Xml.XmlWriter)">
+      <summary>Write this document to an <see cref="T:System.Xml.XmlWriter" />.</summary>
+      <param name="writer">An <see cref="T:System.Xml.XmlWriter" /> into which this method will write.</param>
+    </member>
+    <member name="T:System.Xml.Linq.XDocumentType">
+      <summary>Represents an XML Document Type Definition (DTD).  </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XDocumentType.#ctor(System.String,System.String,System.String,System.String)">
+      <summary>Initializes an instance of the <see cref="T:System.Xml.Linq.XDocumentType" /> class. </summary>
+      <param name="name">A <see cref="T:System.String" /> that contains the qualified name of the DTD, which is the same as the qualified name of the root element of the XML document.</param>
+      <param name="publicId">A <see cref="T:System.String" /> that contains the public identifier of an external public DTD.</param>
+      <param name="systemId">A <see cref="T:System.String" /> that contains the system identifier of an external private DTD.</param>
+      <param name="internalSubset">A <see cref="T:System.String" /> that contains the internal subset for an internal DTD.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocumentType.#ctor(System.Xml.Linq.XDocumentType)">
+      <summary>Initializes an instance of the <see cref="T:System.Xml.Linq.XDocumentType" /> class from another <see cref="T:System.Xml.Linq.XDocumentType" /> object.</summary>
+      <param name="other">An <see cref="T:System.Xml.Linq.XDocumentType" /> object to copy from.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XDocumentType.InternalSubset">
+      <summary>Gets or sets the internal subset for this Document Type Definition (DTD).</summary>
+      <returns>A <see cref="T:System.String" /> that contains the internal subset for this Document Type Definition (DTD).</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XDocumentType.Name">
+      <summary>Gets or sets the name for this Document Type Definition (DTD).</summary>
+      <returns>A <see cref="T:System.String" /> that contains the name for this Document Type Definition (DTD).</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XDocumentType.NodeType">
+      <summary>Gets the node type for this node.</summary>
+      <returns>The node type. For <see cref="T:System.Xml.Linq.XDocumentType" /> objects, this value is <see cref="F:System.Xml.XmlNodeType.DocumentType" />.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XDocumentType.PublicId">
+      <summary>Gets or sets the public identifier for this Document Type Definition (DTD).</summary>
+      <returns>A <see cref="T:System.String" /> that contains the public identifier for this Document Type Definition (DTD).</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XDocumentType.SystemId">
+      <summary>Gets or sets the system identifier for this Document Type Definition (DTD).</summary>
+      <returns>A <see cref="T:System.String" /> that contains the system identifier for this Document Type Definition (DTD).</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XDocumentType.WriteTo(System.Xml.XmlWriter)">
+      <summary>Write this <see cref="T:System.Xml.Linq.XDocumentType" /> to an <see cref="T:System.Xml.XmlWriter" />.</summary>
+      <param name="writer">An <see cref="T:System.Xml.XmlWriter" /> into which this method will write.</param>
+    </member>
+    <member name="T:System.Xml.Linq.XElement">
+      <summary>Represents an XML element.</summary>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.#ctor(System.Xml.Linq.XElement)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XElement" /> class from another <see cref="T:System.Xml.Linq.XElement" /> object.</summary>
+      <param name="other">An <see cref="T:System.Xml.Linq.XElement" /> object to copy from.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.#ctor(System.Xml.Linq.XName)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XElement" /> class with the specified name. </summary>
+      <param name="name">An <see cref="T:System.Xml.Linq.XName" /> that contains the name of the element.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.#ctor(System.Xml.Linq.XName,System.Object)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XElement" /> class with the specified name and content.</summary>
+      <param name="name">An <see cref="T:System.Xml.Linq.XName" /> that contains the element name.</param>
+      <param name="content">The contents of the element.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.#ctor(System.Xml.Linq.XName,System.Object[])">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XElement" /> class with the specified name and content.</summary>
+      <param name="name">An <see cref="T:System.Xml.Linq.XName" /> that contains the element name.</param>
+      <param name="content">The initial content of the element.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.#ctor(System.Xml.Linq.XStreamingElement)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XElement" /> class from an <see cref="T:System.Xml.Linq.XStreamingElement" /> object.</summary>
+      <param name="other">An <see cref="T:System.Xml.Linq.XStreamingElement" /> that contains unevaluated queries that will be iterated for the contents of this <see cref="T:System.Xml.Linq.XElement" />.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.AncestorsAndSelf">
+      <summary>Returns a collection of elements that contain this element, and the ancestors of this element. </summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> of elements that contain this element, and the ancestors of this element. </returns>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.AncestorsAndSelf(System.Xml.Linq.XName)">
+      <summary>Returns a filtered collection of elements that contain this element, and the ancestors of this element. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contain this element, and the ancestors of this element. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</returns>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> to match.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Attribute(System.Xml.Linq.XName)">
+      <summary>Returns the <see cref="T:System.Xml.Linq.XAttribute" /> of this <see cref="T:System.Xml.Linq.XElement" /> that has the specified <see cref="T:System.Xml.Linq.XName" />.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XAttribute" /> that has the specified <see cref="T:System.Xml.Linq.XName" />; null if there is no attribute with the specified name.</returns>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> of the <see cref="T:System.Xml.Linq.XAttribute" /> to get.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Attributes">
+      <summary>Returns a collection of attributes of this element.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XAttribute" /> of attributes of this element.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Attributes(System.Xml.Linq.XName)">
+      <summary>Returns a filtered collection of attributes of this element. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XAttribute" /> that contains the attributes of this element. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</returns>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> to match.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.DescendantNodesAndSelf">
+      <summary>Returns a collection of nodes that contain this element, and all descendant nodes of this element, in document order.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XNode" /> that contain this element, and all descendant nodes of this element, in document order.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.DescendantsAndSelf">
+      <summary>Returns a collection of elements that contain this element, and all descendant elements of this element, in document order.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> of elements that contain this element, and all descendant elements of this element, in document order.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.DescendantsAndSelf(System.Xml.Linq.XName)">
+      <summary>Returns a filtered collection of elements that contain this element, and all descendant elements of this element, in document order. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contain this element, and all descendant elements of this element, in document order. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</returns>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> to match.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XElement.EmptySequence">
+      <summary>Gets an empty collection of elements.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains an empty collection.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XElement.FirstAttribute">
+      <summary>Gets the first attribute of this element.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XAttribute" /> that contains the first attribute of this element.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.GetDefaultNamespace">
+      <summary>Gets the default <see cref="T:System.Xml.Linq.XNamespace" /> of this <see cref="T:System.Xml.Linq.XElement" />.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XNamespace" /> that contains the default namespace of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.GetNamespaceOfPrefix(System.String)">
+      <summary>Gets the namespace associated with a particular prefix for this <see cref="T:System.Xml.Linq.XElement" />.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XNamespace" /> for the namespace associated with the prefix for this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="prefix">A string that contains the namespace prefix to look up.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.GetPrefixOfNamespace(System.Xml.Linq.XNamespace)">
+      <summary>Gets the prefix associated with a namespace for this <see cref="T:System.Xml.Linq.XElement" />.</summary>
+      <returns>A <see cref="T:System.String" /> that contains the namespace prefix.</returns>
+      <param name="ns">An <see cref="T:System.Xml.Linq.XNamespace" /> to look up.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XElement.HasAttributes">
+      <summary>Gets a value indicating whether this element as at least one attribute.</summary>
+      <returns>true if this element has at least one attribute; otherwise false.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XElement.HasElements">
+      <summary>Gets a value indicating whether this element has at least one child element.</summary>
+      <returns>true if this element has at least one child element; otherwise false.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XElement.IsEmpty">
+      <summary>Gets a value indicating whether this element contains no content.</summary>
+      <returns>true if this element contains no content; otherwise false.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XElement.LastAttribute">
+      <summary>Gets the last attribute of this element.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XAttribute" /> that contains the last attribute of this element.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Load(System.IO.Stream)">
+      <summary>Creates a new <see cref="T:System.Xml.Linq.XElement" /> instance using the specified stream.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XElement" /> object used to read the data contained in the stream.</returns>
+      <param name="stream">The stream containing the XML data.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Load(System.IO.Stream,System.Xml.Linq.LoadOptions)">
+      <summary>Creates a new <see cref="T:System.Xml.Linq.XElement" /> instance using the specified stream, optionally preserving white space, setting the base URI, and retaining line information.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XElement" /> object used to read the data contained in the stream.</returns>
+      <param name="stream">The stream containing the XML data.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.LoadOptions" /> that specifies whether to load base URI and line information.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Load(System.IO.TextReader)">
+      <summary>Loads an <see cref="T:System.Xml.Linq.XElement" /> from a <see cref="T:System.IO.TextReader" />. </summary>
+      <returns>An <see cref="T:System.Xml.Linq.XElement" /> that contains the XML that was read from the specified <see cref="T:System.IO.TextReader" />.</returns>
+      <param name="textReader">A <see cref="T:System.IO.TextReader" /> that will be read for the <see cref="T:System.Xml.Linq.XElement" /> content.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Load(System.IO.TextReader,System.Xml.Linq.LoadOptions)">
+      <summary>Loads an <see cref="T:System.Xml.Linq.XElement" /> from a <see cref="T:System.IO.TextReader" />, optionally preserving white space and retaining line information. </summary>
+      <returns>An <see cref="T:System.Xml.Linq.XElement" /> that contains the XML that was read from the specified <see cref="T:System.IO.TextReader" />.</returns>
+      <param name="textReader">A <see cref="T:System.IO.TextReader" /> that will be read for the <see cref="T:System.Xml.Linq.XElement" /> content.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.LoadOptions" /> that specifies white space behavior, and whether to load base URI and line information.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Load(System.String)">
+      <summary>Loads an <see cref="T:System.Xml.Linq.XElement" /> from a file located in the applications' XAP package.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XElement" /> that contains the contents of the specified file.</returns>
+      <param name="uri">A URI string that references the file to be loaded into a new <see cref="T:System.Xml.Linq.XElement" />. This file is located in the application's XAP package. If you want to download a file from some other location, follow the steps described in How to: Load an XML File from an Arbitrary URI Location with LINQ to XML.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Load(System.String,System.Xml.Linq.LoadOptions)">
+      <summary>Loads an <see cref="T:System.Xml.Linq.XElement" /> from a file located in the application's XAP package, optionally preserving white space, setting the base URI, and retaining line information.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XElement" /> that contains the contents of the specified file.</returns>
+      <param name="uri">A URI string that references the file to be loaded into a new <see cref="T:System.Xml.Linq.XElement" />. This file is located in the application's XAP package. If you want to download a file from some other location, follow the steps described in How to: Load an XML File from an Arbitrary URI Location with LINQ to XML.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.LoadOptions" /> that specifies white space behavior, and whether to load base URI and line information.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Load(System.Xml.XmlReader)">
+      <summary>Loads an <see cref="T:System.Xml.Linq.XElement" /> from an <see cref="T:System.Xml.XmlReader" />. </summary>
+      <returns>An <see cref="T:System.Xml.Linq.XElement" /> that contains the XML that was read from the specified <see cref="T:System.Xml.XmlReader" />.</returns>
+      <param name="reader">A <see cref="T:System.Xml.XmlReader" /> that will be read for the content of the <see cref="T:System.Xml.Linq.XElement" />.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Load(System.Xml.XmlReader,System.Xml.Linq.LoadOptions)">
+      <summary>Loads an <see cref="T:System.Xml.Linq.XElement" /> from an <see cref="T:System.Xml.XmlReader" />, optionally preserving white space, setting the base URI, and retaining line information.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XElement" /> that contains the XML that was read from the specified <see cref="T:System.Xml.XmlReader" />.</returns>
+      <param name="reader">A <see cref="T:System.Xml.XmlReader" /> that will be read for the content of the <see cref="T:System.Xml.Linq.XElement" />.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.LoadOptions" /> that specifies white space behavior, and whether to load base URI and line information.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XElement.Name">
+      <summary>Gets the name of this element.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XName" /> that contains the name of this element.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XElement.NodeType">
+      <summary>Gets the node type for this node.</summary>
+      <returns>The node type. For <see cref="T:System.Xml.Linq.XElement" /> objects, this value is <see cref="F:System.Xml.XmlNodeType.Element" />.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.DateTime">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.DateTime" />.</summary>
+      <returns>A <see cref="T:System.DateTime" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.DateTime" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.DateTime" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="element" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Decimal">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Decimal" />.</summary>
+      <returns>A <see cref="T:System.Decimal" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Decimal" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.Decimal" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="element" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Nullable{System.Decimal}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Decimal" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.Decimal" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Nullable`1" /> of <see cref="T:System.Decimal" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.Decimal" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Nullable{System.Single}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Single" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.Single" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Nullable`1" /> of <see cref="T:System.Single" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.Single" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.TimeSpan">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.TimeSpan" />.</summary>
+      <returns>A <see cref="T:System.TimeSpan" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.TimeSpan" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.TimeSpan" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="element" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Nullable{System.Double}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Double" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.Double" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Nullable`1" /> of <see cref="T:System.Double" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.Double" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Double">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Double" />.</summary>
+      <returns>A <see cref="T:System.Double" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Double" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.Double" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="element" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Single">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Single" />.</summary>
+      <returns>A <see cref="T:System.Single" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Single" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.Single" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="element" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Guid">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Guid" />.</summary>
+      <returns>A <see cref="T:System.Guid" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Guid" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.Guid" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="element" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Nullable{System.Guid}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Guid" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.Guid" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Nullable`1" /> of <see cref="T:System.Guid" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.Guid" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Nullable{System.TimeSpan}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.TimeSpan" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.TimeSpan" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Nullable`1" /> of <see cref="T:System.TimeSpan" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.TimeSpan" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Nullable{System.DateTime}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.DateTime" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.DateTime" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Nullable`1" /> of <see cref="T:System.DateTime" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.DateTime" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.DateTimeOffset">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.DateTimeOffset" />.</summary>
+      <returns>A <see cref="T:System.DateTimeOffset" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.DateTimeOffset" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.DateTimeOffset" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="element" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Nullable{System.DateTimeOffset}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.DateTimeOffset" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.DateTimeOffset" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to an <see cref="T:System.Nullable`1" /> of <see cref="T:System.DateTimeOffset" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.DateTimeOffset" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Int32">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to an <see cref="T:System.Int32" />.</summary>
+      <returns>A <see cref="T:System.Int32" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Int32" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.Int32" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="element" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Nullable{System.Int32}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Int32" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.Int32" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Nullable`1" /> of <see cref="T:System.Int32" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.Int32" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Nullable{System.Boolean}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Boolean" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.Boolean" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Nullable`1" /> of <see cref="T:System.Boolean" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.Boolean" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.String">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.String" />.</summary>
+      <returns>A <see cref="T:System.String" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.String" />.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Boolean">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Boolean" />.</summary>
+      <returns>A <see cref="T:System.Boolean" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Boolean" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.Boolean" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="element" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.UInt32">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.UInt32" />.</summary>
+      <returns>A <see cref="T:System.UInt32" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.UInt32" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.UInt32" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="element" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.UInt64">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.UInt64" />.</summary>
+      <returns>A <see cref="T:System.UInt64" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.UInt64" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.UInt64" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="element" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Nullable{System.UInt64}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.UInt64" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.UInt64" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Nullable`1" /> of <see cref="T:System.UInt64" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.UInt64" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Nullable{System.Int64}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Int64" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.Int64" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Nullable`1" /> of <see cref="T:System.Int64" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.Int64" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Nullable{System.UInt32}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.UInt32" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.UInt32" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Nullable`1" /> of <see cref="T:System.UInt32" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.UInt32" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Int64">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to an <see cref="T:System.Int64" />.</summary>
+      <returns>A <see cref="T:System.Int64" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Int64" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.Int64" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="element" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Parse(System.String)">
+      <summary>Load an <see cref="T:System.Xml.Linq.XElement" /> from a string that contains XML.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XElement" /> populated from the string that contains XML.</returns>
+      <param name="text">A <see cref="T:System.String" /> that contains XML.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Parse(System.String,System.Xml.Linq.LoadOptions)">
+      <summary>Load an <see cref="T:System.Xml.Linq.XElement" /> from a string that contains XML, optionally preserving white space and retaining line information.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XElement" /> populated from the string that contains XML.</returns>
+      <param name="text">A <see cref="T:System.String" /> that contains XML.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.LoadOptions" /> that specifies white space behavior, and whether to load base URI and line information.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.RemoveAll">
+      <summary>Removes nodes and attributes from this <see cref="T:System.Xml.Linq.XElement" />.</summary>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.RemoveAttributes">
+      <summary>Removes the attributes of this <see cref="T:System.Xml.Linq.XElement" />.</summary>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.ReplaceAll(System.Object)">
+      <summary>Replaces the child nodes and the attributes of this element with the specified content.</summary>
+      <param name="content">The content that will replace the child nodes and attributes of this element.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.ReplaceAll(System.Object[])">
+      <summary>Replaces the child nodes and the attributes of this element with the specified content.</summary>
+      <param name="content">A parameter list of content objects.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.ReplaceAttributes(System.Object)">
+      <summary>Replaces the attributes of this element with the specified content.</summary>
+      <param name="content">The content that will replace the attributes of this element.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.ReplaceAttributes(System.Object[])">
+      <summary>Replaces the attributes of this element with the specified content.</summary>
+      <param name="content">A parameter list of content objects.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Save(System.IO.Stream)">
+      <summary>Outputs this <see cref="T:System.Xml.Linq.XElement" /> to the specified <see cref="T:System.IO.Stream" />.</summary>
+      <param name="stream">The stream to output this <see cref="T:System.Xml.Linq.XElement" /> to.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Save(System.IO.Stream,System.Xml.Linq.SaveOptions)">
+      <summary>Outputs this <see cref="T:System.Xml.Linq.XElement" /> to the specified <see cref="T:System.IO.Stream" />, optionally specifying formatting behavior.</summary>
+      <param name="stream">The stream to output this <see cref="T:System.Xml.Linq.XElement" /> to.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.SaveOptions" /> that specifies formatting behavior.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Save(System.IO.TextWriter)">
+      <summary>Serialize this element to a <see cref="T:System.IO.TextWriter" />.</summary>
+      <param name="textWriter">A <see cref="T:System.IO.TextWriter" /> that the <see cref="T:System.Xml.Linq.XElement" /> will be written to.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Save(System.IO.TextWriter,System.Xml.Linq.SaveOptions)">
+      <summary>Serialize this element to a <see cref="T:System.IO.TextWriter" />, optionally disabling formatting.</summary>
+      <param name="textWriter">The <see cref="T:System.IO.TextWriter" /> to output the XML to.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.SaveOptions" /> that specifies formatting behavior.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Save(System.Xml.XmlWriter)">
+      <summary>Serialize this element to an <see cref="T:System.Xml.XmlWriter" />.</summary>
+      <param name="writer">A <see cref="T:System.Xml.XmlWriter" /> that the <see cref="T:System.Xml.Linq.XElement" /> will be written to.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.SetAttributeValue(System.Xml.Linq.XName,System.Object)">
+      <summary>Sets the value of an attribute, adds an attribute, or removes an attribute. </summary>
+      <param name="name">An <see cref="T:System.Xml.Linq.XName" /> that contains the name of the attribute to change.</param>
+      <param name="value">The value to assign to the attribute. The attribute is removed if the value is null. Otherwise, the value is converted to its string representation and assigned to the <see cref="P:System.Xml.Linq.XAttribute.Value" /> property of the attribute.</param>
+      <exception cref="T:System.ArgumentException">The <paramref name="value" /> is an instance of <see cref="T:System.Xml.Linq.XObject" />.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.SetElementValue(System.Xml.Linq.XName,System.Object)">
+      <summary>Sets the value of a child element, adds a child element, or removes a child element.</summary>
+      <param name="name">An <see cref="T:System.Xml.Linq.XName" /> that contains the name of the child element to change.</param>
+      <param name="value">The value to assign to the child element. The child element is removed if the value is null. Otherwise, the value is converted to its string representation and assigned to the <see cref="P:System.Xml.Linq.XElement.Value" /> property of the child element.</param>
+      <exception cref="T:System.ArgumentException">The <paramref name="value" /> is an instance of <see cref="T:System.Xml.Linq.XObject" />.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.SetValue(System.Object)">
+      <summary>Sets the value of this element.</summary>
+      <param name="value">The value to assign to this element. The value is converted to its string representation and assigned to the <see cref="P:System.Xml.Linq.XElement.Value" /> property.</param>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="value" /> is null.</exception>
+      <exception cref="T:System.ArgumentException">The <paramref name="value" /> is an <see cref="T:System.Xml.Linq.XObject" />.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.System#Xml#Serialization#IXmlSerializable#GetSchema">
+      <summary>Gets an XML schema definition that describes the XML representation of this object.</summary>
+      <returns>An <see cref="T:System.Xml.Schema.XmlSchema" /> that describes the XML representation of the object that is produced by the <see cref="M:System.Xml.Serialization.IXmlSerializable.WriteXml(System.Xml.XmlWriter)" /> method and consumed by the <see cref="M:System.Xml.Serialization.IXmlSerializable.ReadXml(System.Xml.XmlReader)" /> method.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.System#Xml#Serialization#IXmlSerializable#ReadXml(System.Xml.XmlReader)">
+      <summary>Generates an object from its XML representation.</summary>
+      <param name="reader">The <see cref="T:System.Xml.XmlReader" /> from which the object is deserialized.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.System#Xml#Serialization#IXmlSerializable#WriteXml(System.Xml.XmlWriter)">
+      <summary>Converts an object into its XML representation.</summary>
+      <param name="writer">The <see cref="T:System.Xml.XmlWriter" /> to which this object is serialized.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XElement.Value">
+      <summary>Gets the concatenated text contents of this element.</summary>
+      <returns>A <see cref="T:System.String" /> that contains all of the text content of this element. If there are multiple text nodes, they will be concatenated.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.WriteTo(System.Xml.XmlWriter)">
+      <summary>Write this element to an <see cref="T:System.Xml.XmlWriter" />.</summary>
+      <param name="writer">An <see cref="T:System.Xml.XmlWriter" /> into which this method will write.</param>
+    </member>
+    <member name="T:System.Xml.Linq.XName">
+      <summary>Represents a name of an XML element or attribute. </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XName.Equals(System.Object)">
+      <summary>Determines whether the specified <see cref="T:System.Xml.Linq.XName" /> is equal to this <see cref="T:System.Xml.Linq.XName" />.</summary>
+      <returns>true if the specified <see cref="T:System.Xml.Linq.XName" /> is equal to the current <see cref="T:System.Xml.Linq.XName" />; otherwise false.</returns>
+      <param name="obj">The <see cref="T:System.Xml.Linq.XName" /> to compare to the current <see cref="T:System.Xml.Linq.XName" />.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XName.Get(System.String)">
+      <summary>Gets an <see cref="T:System.Xml.Linq.XName" /> object from an expanded name.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XName" /> object constructed from the expanded name.</returns>
+      <param name="expandedName">A <see cref="T:System.String" /> that contains an expanded XML name in the format {namespace}localname.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XName.Get(System.String,System.String)">
+      <summary>Gets an <see cref="T:System.Xml.Linq.XName" /> object from a local name and a namespace.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XName" /> object created from the specified local name and namespace.</returns>
+      <param name="localName">A local (unqualified) name.</param>
+      <param name="namespaceName">An XML namespace.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XName.GetHashCode">
+      <summary>Gets a hash code for this <see cref="T:System.Xml.Linq.XName" />.</summary>
+      <returns>An <see cref="T:System.Int32" /> that contains the hash code for the <see cref="T:System.Xml.Linq.XName" />.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XName.LocalName">
+      <summary>Gets the local (unqualified) part of the name.</summary>
+      <returns>A <see cref="T:System.String" /> that contains the local (unqualified) part of the name.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XName.Namespace">
+      <summary>Gets the namespace part of the fully qualified name.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XNamespace" /> that contains the namespace part of the name.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XName.NamespaceName">
+      <summary>Returns the URI of the <see cref="T:System.Xml.Linq.XNamespace" /> for this <see cref="T:System.Xml.Linq.XName" />.</summary>
+      <returns>The URI of the <see cref="T:System.Xml.Linq.XNamespace" /> for this <see cref="T:System.Xml.Linq.XName" />.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XName.op_Equality(System.Xml.Linq.XName,System.Xml.Linq.XName)">
+      <summary>Returns a value indicating whether two instances of <see cref="T:System.Xml.Linq.XName" /> are equal.</summary>
+      <returns>true if <paramref name="left" /> and <paramref name="right" /> are equal; otherwise false.</returns>
+      <param name="left">The first <see cref="T:System.Xml.Linq.XName" /> to compare.</param>
+      <param name="right">The second <see cref="T:System.Xml.Linq.XName" /> to compare.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XName.op_Implicit(System.String)~System.Xml.Linq.XName">
+      <summary>Converts a string formatted as an expanded XML name (that is,{namespace}localname) to an <see cref="T:System.Xml.Linq.XName" /> object.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XName" /> object constructed from the expanded name.</returns>
+      <param name="expandedName">A string that contains an expanded XML name in the format {namespace}localname.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XName.op_Inequality(System.Xml.Linq.XName,System.Xml.Linq.XName)">
+      <summary>Returns a value indicating whether two instances of <see cref="T:System.Xml.Linq.XName" /> are not equal.</summary>
+      <returns>true if <paramref name="left" /> and <paramref name="right" /> are not equal; otherwise false.</returns>
+      <param name="left">The first <see cref="T:System.Xml.Linq.XName" /> to compare.</param>
+      <param name="right">The second <see cref="T:System.Xml.Linq.XName" /> to compare.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XName.System#IEquatable{T}#Equals(System.Xml.Linq.XName)">
+      <summary>Indicates whether the current <see cref="T:System.Xml.Linq.XName" /> is equal to the specified <see cref="T:System.Xml.Linq.XName" />.</summary>
+      <returns>true if this <see cref="T:System.Xml.Linq.XName" /> is equal to the specified <see cref="T:System.Xml.Linq.XName" />, otherwise false.</returns>
+      <param name="other">The <see cref="T:System.Xml.Linq.XName" /> to compare with this <see cref="T:System.Xml.Linq.XName" />.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XName.ToString">
+      <summary>Returns the expanded XML name in the format {namespace}localname.</summary>
+      <returns>A <see cref="T:System.String" /> that contains the expanded XML name in the format {namespace}localname.</returns>
+    </member>
+    <member name="T:System.Xml.Linq.XNamespace">
+      <summary>Represents an XML namespace. This class cannot be inherited. </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XNamespace.Equals(System.Object)">
+      <summary>Determines whether the specified <see cref="T:System.Xml.Linq.XNamespace" /> is equal to the current <see cref="T:System.Xml.Linq.XNamespace" />.</summary>
+      <returns>A <see cref="T:System.Boolean" /> that indicates whether the specified <see cref="T:System.Xml.Linq.XNamespace" /> is equal to the current <see cref="T:System.Xml.Linq.XNamespace" />.</returns>
+      <param name="obj">The <see cref="T:System.Xml.Linq.XNamespace" /> to compare to the current <see cref="T:System.Xml.Linq.XNamespace" />.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XNamespace.Get(System.String)">
+      <summary>Gets an <see cref="T:System.Xml.Linq.XNamespace" /> for the specified Uniform Resource Identifier (URI).</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XNamespace" /> created from the specified URI.</returns>
+      <param name="namespaceName">A <see cref="T:System.String" /> that contains a namespace URI.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XNamespace.GetHashCode">
+      <summary>Gets a hash code for this <see cref="T:System.Xml.Linq.XNamespace" />.</summary>
+      <returns>An <see cref="T:System.Int32" /> that contains the hash code for the <see cref="T:System.Xml.Linq.XNamespace" />.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XNamespace.GetName(System.String)">
+      <summary>Returns an <see cref="T:System.Xml.Linq.XName" /> object created from this <see cref="T:System.Xml.Linq.XNamespace" /> and the specified local name.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XName" /> created from this <see cref="T:System.Xml.Linq.XNamespace" /> and the specified local name.</returns>
+      <param name="localName">A <see cref="T:System.String" /> that contains a local name.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XNamespace.NamespaceName">
+      <summary>Gets the Uniform Resource Identifier (URI) of this namespace.</summary>
+      <returns>A <see cref="T:System.String" /> that contains the URI of the namespace.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XNamespace.None">
+      <summary>Gets the <see cref="T:System.Xml.Linq.XNamespace" /> object that corresponds to no namespace.</summary>
+      <returns>The <see cref="T:System.Xml.Linq.XNamespace" /> that corresponds to no namespace.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XNamespace.op_Addition(System.Xml.Linq.XNamespace,System.String)">
+      <summary>Combines an <see cref="T:System.Xml.Linq.XNamespace" /> object with a local name to create an <see cref="T:System.Xml.Linq.XName" />.</summary>
+      <returns>The new <see cref="T:System.Xml.Linq.XName" /> constructed from the namespace and local name.</returns>
+      <param name="ns">An <see cref="T:System.Xml.Linq.XNamespace" /> that contains the namespace.</param>
+      <param name="localName">A <see cref="T:System.String" /> that contains the local name.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XNamespace.op_Equality(System.Xml.Linq.XNamespace,System.Xml.Linq.XNamespace)">
+      <summary>Returns a value indicating whether two instances of <see cref="T:System.Xml.Linq.XNamespace" /> are equal.</summary>
+      <returns>A <see cref="T:System.Boolean" /> that indicates whether <paramref name="left" /> and <paramref name="right" /> are equal.</returns>
+      <param name="left">The first <see cref="T:System.Xml.Linq.XNamespace" /> to compare.</param>
+      <param name="right">The second <see cref="T:System.Xml.Linq.XNamespace" /> to compare.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XNamespace.op_Implicit(System.String)~System.Xml.Linq.XNamespace">
+      <summary>Converts a string containing a Uniform Resource Identifier (URI) to an <see cref="T:System.Xml.Linq.XNamespace" />.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XNamespace" /> constructed from the URI string.</returns>
+      <param name="namespaceName">A <see cref="T:System.String" /> that contains the namespace URI.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XNamespace.op_Inequality(System.Xml.Linq.XNamespace,System.Xml.Linq.XNamespace)">
+      <summary>Returns a value indicating whether two instances of <see cref="T:System.Xml.Linq.XNamespace" /> are not equal.</summary>
+      <returns>A <see cref="T:System.Boolean" /> that indicates whether <paramref name="left" /> and <paramref name="right" /> are not equal.</returns>
+      <param name="left">The first <see cref="T:System.Xml.Linq.XNamespace" /> to compare.</param>
+      <param name="right">The second <see cref="T:System.Xml.Linq.XNamespace" /> to compare.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XNamespace.ToString">
+      <summary>Returns the URI of this <see cref="T:System.Xml.Linq.XNamespace" />.</summary>
+      <returns>The URI of this <see cref="T:System.Xml.Linq.XNamespace" />.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XNamespace.Xml">
+      <summary>Gets the <see cref="T:System.Xml.Linq.XNamespace" /> object that corresponds to the XML URI (http://www.w3.org/XML/1998/namespace).</summary>
+      <returns>The <see cref="T:System.Xml.Linq.XNamespace" /> that corresponds to the XML URI (http://www.w3.org/XML/1998/namespace).</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XNamespace.Xmlns">
+      <summary>Gets the <see cref="T:System.Xml.Linq.XNamespace" /> object that corresponds to the xmlns URI (http://www.w3.org/2000/xmlns/).</summary>
+      <returns>The <see cref="T:System.Xml.Linq.XNamespace" /> that corresponds to the xmlns URI (http://www.w3.org/2000/xmlns/).</returns>
+    </member>
+    <member name="T:System.Xml.Linq.XNode">
+      <summary>Represents the abstract concept of a node (one of: element, comment, document type, processing instruction, or text node) in the XML tree.  </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.AddAfterSelf(System.Object)">
+      <summary>Adds the specified content immediately after this node.</summary>
+      <param name="content">A content object that contains simple content or a collection of content objects to be added after this node.</param>
+      <exception cref="T:System.InvalidOperationException">The parent is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.AddAfterSelf(System.Object[])">
+      <summary>Adds the specified content immediately after this node.</summary>
+      <param name="content">A parameter list of content objects.</param>
+      <exception cref="T:System.InvalidOperationException">The parent is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.AddBeforeSelf(System.Object)">
+      <summary>Adds the specified content immediately before this node.</summary>
+      <param name="content">A content object that contains simple content or a collection of content objects to be added before this node.</param>
+      <exception cref="T:System.InvalidOperationException">The parent is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.AddBeforeSelf(System.Object[])">
+      <summary>Adds the specified content immediately before this node.</summary>
+      <param name="content">A parameter list of content objects.</param>
+      <exception cref="T:System.InvalidOperationException">The parent is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.Ancestors">
+      <summary>Returns a collection of the ancestor elements of this node.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> of the ancestor elements of this node.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.Ancestors(System.Xml.Linq.XName)">
+      <summary>Returns a filtered collection of the ancestor elements of this node. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> of the ancestor elements of this node. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.The nodes in the returned collection are in reverse document order.This method uses deferred execution.</returns>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> to match.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.CompareDocumentOrder(System.Xml.Linq.XNode,System.Xml.Linq.XNode)">
+      <summary>Compares two nodes to determine their relative XML document order.</summary>
+      <returns>An int containing 0 if the nodes are equal; -1 if <paramref name="n1" /> is before <paramref name="n2" />; 1 if <paramref name="n1" /> is after <paramref name="n2" />.</returns>
+      <param name="n1">First <see cref="T:System.Xml.Linq.XNode" /> to compare.</param>
+      <param name="n2">Second <see cref="T:System.Xml.Linq.XNode" /> to compare.</param>
+      <exception cref="T:System.InvalidOperationException">The two nodes do not share a common ancestor.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.CreateReader">
+      <summary>Creates an <see cref="T:System.Xml.XmlReader" /> for this node.</summary>
+      <returns>An <see cref="T:System.Xml.XmlReader" /> that can be used to read this node and its descendants.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.CreateReader(System.Xml.Linq.ReaderOptions)"></member>
+    <member name="M:System.Xml.Linq.XNode.DeepEquals(System.Xml.Linq.XNode,System.Xml.Linq.XNode)">
+      <summary>Compares the values of two nodes, including the values of all descendant nodes.</summary>
+      <returns>true if the nodes are equal; otherwise false.</returns>
+      <param name="n1">The first <see cref="T:System.Xml.Linq.XNode" /> to compare.</param>
+      <param name="n2">The second <see cref="T:System.Xml.Linq.XNode" /> to compare.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XNode.DocumentOrderComparer">
+      <summary>Gets a comparer that can compare the relative position of two nodes.</summary>
+      <returns>A <see cref="T:System.Xml.Linq.XNodeDocumentOrderComparer" /> that can compare the relative position of two nodes.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.ElementsAfterSelf">
+      <summary>Returns a collection of the sibling elements after this node, in document order.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> of the sibling elements after this node, in document order.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.ElementsAfterSelf(System.Xml.Linq.XName)">
+      <summary>Returns a filtered collection of the sibling elements after this node, in document order. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> of the sibling elements after this node, in document order. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</returns>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> to match.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.ElementsBeforeSelf">
+      <summary>Returns a collection of the sibling elements before this node, in document order.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> of the sibling elements before this node, in document order.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.ElementsBeforeSelf(System.Xml.Linq.XName)">
+      <summary>Returns a filtered collection of the sibling elements before this node, in document order. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> of the sibling elements before this node, in document order. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</returns>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> to match.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XNode.EqualityComparer">
+      <summary>Gets a comparer that can compare two nodes for value equality.</summary>
+      <returns>A <see cref="T:System.Xml.Linq.XNodeEqualityComparer" /> that can compare two nodes for value equality.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.IsAfter(System.Xml.Linq.XNode)">
+      <summary>Determines if the current node appears after a specified node in terms of document order.</summary>
+      <returns>true if this node appears after the specified node; otherwise false.</returns>
+      <param name="node">The <see cref="T:System.Xml.Linq.XNode" /> to compare for document order.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.IsBefore(System.Xml.Linq.XNode)">
+      <summary>Determines if the current node appears before a specified node in terms of document order.</summary>
+      <returns>true if this node appears before the specified node; otherwise false.</returns>
+      <param name="node">The <see cref="T:System.Xml.Linq.XNode" /> to compare for document order.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XNode.NextNode">
+      <summary>Gets the next sibling node of this node.</summary>
+      <returns>The <see cref="T:System.Xml.Linq.XNode" /> that contains the next sibling node.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.NodesAfterSelf">
+      <summary>Returns a collection of the sibling nodes after this node, in document order.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XNode" /> of the sibling nodes after this node, in document order.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.NodesBeforeSelf">
+      <summary>Returns a collection of the sibling nodes before this node, in document order.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XNode" /> of the sibling nodes before this node, in document order.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XNode.PreviousNode">
+      <summary>Gets the previous sibling node of this node.</summary>
+      <returns>The <see cref="T:System.Xml.Linq.XNode" /> that contains the previous sibling node.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.ReadFrom(System.Xml.XmlReader)">
+      <summary>Creates an <see cref="T:System.Xml.Linq.XNode" /> from an <see cref="T:System.Xml.XmlReader" />.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XNode" /> that contains the node and its descendant nodes that were read from the reader. The runtime type of the node is determined by the node type (<see cref="P:System.Xml.Linq.XObject.NodeType" />) of the first node encountered in the reader.</returns>
+      <param name="reader">An <see cref="T:System.Xml.XmlReader" /> positioned at the node to read into this <see cref="T:System.Xml.Linq.XNode" />.</param>
+      <exception cref="T:System.InvalidOperationException">The <see cref="T:System.Xml.XmlReader" /> is not positioned on a recognized node type.</exception>
+      <exception cref="T:System.Xml.XmlException">The underlying <see cref="T:System.Xml.XmlReader" /> throws an exception.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.Remove">
+      <summary>Removes this node from its parent.</summary>
+      <exception cref="T:System.InvalidOperationException">The parent is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.ReplaceWith(System.Object)">
+      <summary>Replaces this node with the specified content.</summary>
+      <param name="content">Content that replaces this node.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.ReplaceWith(System.Object[])">
+      <summary>Replaces this node with the specified content.</summary>
+      <param name="content">A parameter list of the new content.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.ToString">
+      <summary>Returns the indented XML for this node.</summary>
+      <returns>A <see cref="T:System.String" /> containing the indented XML.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.ToString(System.Xml.Linq.SaveOptions)">
+      <summary>Returns the XML for this node, optionally disabling formatting.</summary>
+      <returns>A <see cref="T:System.String" /> containing the XML.</returns>
+      <param name="options">A <see cref="T:System.Xml.Linq.SaveOptions" /> that specifies formatting behavior.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.WriteTo(System.Xml.XmlWriter)">
+      <summary>Writes this node to an <see cref="T:System.Xml.XmlWriter" />.</summary>
+      <param name="writer">An <see cref="T:System.Xml.XmlWriter" /> into which this method will write.</param>
+    </member>
+    <member name="T:System.Xml.Linq.XNodeDocumentOrderComparer">
+      <summary>Contains functionality to compare nodes for their document order. This class cannot be inherited.  </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XNodeDocumentOrderComparer.#ctor">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XNodeDocumentOrderComparer" /> class. </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XNodeDocumentOrderComparer.Compare(System.Xml.Linq.XNode,System.Xml.Linq.XNode)">
+      <summary>Compares two nodes to determine their relative document order.</summary>
+      <returns>An <see cref="T:System.Int32" /> that contains 0 if the nodes are equal; -1 if <paramref name="x" /> is before <paramref name="y" />; 1 if <paramref name="x" /> is after <paramref name="y" />.</returns>
+      <param name="x">The first <see cref="T:System.Xml.Linq.XNode" /> to compare.</param>
+      <param name="y">The second <see cref="T:System.Xml.Linq.XNode" /> to compare.</param>
+      <exception cref="T:System.InvalidOperationException">The two nodes do not share a common ancestor.</exception>
+    </member>
+    <member name="T:System.Xml.Linq.XNodeEqualityComparer">
+      <summary>Compares nodes to determine whether they are equal. This class cannot be inherited. </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XNodeEqualityComparer.#ctor">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XNodeEqualityComparer" /> class. </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XNodeEqualityComparer.Equals(System.Xml.Linq.XNode,System.Xml.Linq.XNode)">
+      <summary>Compares the values of two nodes.</summary>
+      <returns>A <see cref="T:System.Boolean" /> indicating if the nodes are equal.</returns>
+      <param name="x">The first <see cref="T:System.Xml.Linq.XNode" /> to compare.</param>
+      <param name="y">The second <see cref="T:System.Xml.Linq.XNode" /> to compare.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XNodeEqualityComparer.GetHashCode(System.Xml.Linq.XNode)">
+      <summary>Returns a hash code based on an <see cref="T:System.Xml.Linq.XNode" />.</summary>
+      <returns>A <see cref="T:System.Int32" /> that contains a value-based hash code for the node.</returns>
+      <param name="obj">The <see cref="T:System.Xml.Linq.XNode" /> to hash.</param>
+    </member>
+    <member name="T:System.Xml.Linq.XObject">
+      <summary>Represents a node or an attribute in an XML tree. </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XObject.AddAnnotation(System.Object)">
+      <summary>Adds an object to the annotation list of this <see cref="T:System.Xml.Linq.XObject" />.</summary>
+      <param name="annotation">An <see cref="T:System.Object" /> that contains the annotation to add.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XObject.Annotation``1">
+      <summary>Get the first annotation object of the specified type from this <see cref="T:System.Xml.Linq.XObject" />. </summary>
+      <returns>The first annotation object that matches the specified type, or null if no annotation is of the specified type.</returns>
+      <typeparam name="T">The type of the annotation to retrieve.</typeparam>
+    </member>
+    <member name="M:System.Xml.Linq.XObject.Annotation(System.Type)">
+      <summary>Gets the first annotation object of the specified type from this <see cref="T:System.Xml.Linq.XObject" />.</summary>
+      <returns>The <see cref="T:System.Object" /> that contains the first annotation object that matches the specified type, or null if no annotation is of the specified type.</returns>
+      <param name="type">The <see cref="T:System.Type" /> of the annotation to retrieve.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XObject.Annotations``1">
+      <summary>Gets a collection of annotations of the specified type for this <see cref="T:System.Xml.Linq.XObject" />.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> that contains the annotations for this <see cref="T:System.Xml.Linq.XObject" />.</returns>
+      <typeparam name="T">The type of the annotations to retrieve.</typeparam>
+    </member>
+    <member name="M:System.Xml.Linq.XObject.Annotations(System.Type)">
+      <summary>Gets a collection of annotations of the specified type for this <see cref="T:System.Xml.Linq.XObject" />.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Object" /> that contains the annotations that match the specified type for this <see cref="T:System.Xml.Linq.XObject" />.</returns>
+      <param name="type">The <see cref="T:System.Type" /> of the annotations to retrieve.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XObject.BaseUri">
+      <summary>Gets the base URI for this <see cref="T:System.Xml.Linq.XObject" />.</summary>
+      <returns>A <see cref="T:System.String" /> that contains the base URI for this <see cref="T:System.Xml.Linq.XObject" />.</returns>
+    </member>
+    <member name="E:System.Xml.Linq.XObject.Changed">
+      <summary>Raised when this <see cref="T:System.Xml.Linq.XObject" /> or any of its descendants have changed.</summary>
+    </member>
+    <member name="E:System.Xml.Linq.XObject.Changing">
+      <summary>Raised when this <see cref="T:System.Xml.Linq.XObject" /> or any of its descendants are about to change.</summary>
+    </member>
+    <member name="P:System.Xml.Linq.XObject.Document">
+      <summary>Gets the <see cref="T:System.Xml.Linq.XDocument" /> for this <see cref="T:System.Xml.Linq.XObject" />.</summary>
+      <returns>The <see cref="T:System.Xml.Linq.XDocument" /> for this <see cref="T:System.Xml.Linq.XObject" />. </returns>
+    </member>
+    <member name="P:System.Xml.Linq.XObject.NodeType">
+      <summary>Gets the node type for this <see cref="T:System.Xml.Linq.XObject" />.</summary>
+      <returns>The node type for this <see cref="T:System.Xml.Linq.XObject" />. </returns>
+    </member>
+    <member name="P:System.Xml.Linq.XObject.Parent">
+      <summary>Gets the parent <see cref="T:System.Xml.Linq.XElement" /> of this <see cref="T:System.Xml.Linq.XObject" />.</summary>
+      <returns>The parent <see cref="T:System.Xml.Linq.XElement" /> of this <see cref="T:System.Xml.Linq.XObject" />.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XObject.RemoveAnnotations``1">
+      <summary>Removes the annotations of the specified type from this <see cref="T:System.Xml.Linq.XObject" />.</summary>
+      <typeparam name="T">The type of annotations to remove.</typeparam>
+    </member>
+    <member name="M:System.Xml.Linq.XObject.RemoveAnnotations(System.Type)">
+      <summary>Removes the annotations of the specified type from this <see cref="T:System.Xml.Linq.XObject" />.</summary>
+      <param name="type">The <see cref="T:System.Type" /> of annotations to remove.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XObject.System#Xml#IXmlLineInfo#HasLineInfo">
+      <summary>Gets a value indicating whether or not this <see cref="T:System.Xml.Linq.XObject" /> has line information.</summary>
+      <returns>true if the <see cref="T:System.Xml.Linq.XObject" /> has line information, otherwise false.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XObject.System#Xml#IXmlLineInfo#LineNumber">
+      <summary>Gets the line number that the underlying <see cref="T:System.Xml.XmlReader" /> reported for this <see cref="T:System.Xml.Linq.XObject" />.</summary>
+      <returns>An <see cref="T:System.Int32" /> that contains the line number reported by the <see cref="T:System.Xml.XmlReader" /> for this <see cref="T:System.Xml.Linq.XObject" />.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XObject.System#Xml#IXmlLineInfo#LinePosition">
+      <summary>Gets the line position that the underlying <see cref="T:System.Xml.XmlReader" /> reported for this <see cref="T:System.Xml.Linq.XObject" />.</summary>
+      <returns>An <see cref="T:System.Int32" /> that contains the line position reported by the <see cref="T:System.Xml.XmlReader" /> for this <see cref="T:System.Xml.Linq.XObject" />.</returns>
+    </member>
+    <member name="T:System.Xml.Linq.XObjectChange">
+      <summary>Specifies the event type when an event is raised for an <see cref="T:System.Xml.Linq.XObject" />.</summary>
+    </member>
+    <member name="F:System.Xml.Linq.XObjectChange.Add">
+      <summary>An <see cref="T:System.Xml.Linq.XObject" /> has been or will be added to an <see cref="T:System.Xml.Linq.XContainer" />.</summary>
+    </member>
+    <member name="F:System.Xml.Linq.XObjectChange.Remove">
+      <summary>An <see cref="T:System.Xml.Linq.XObject" /> has been or will be removed from an <see cref="T:System.Xml.Linq.XContainer" />.</summary>
+    </member>
+    <member name="F:System.Xml.Linq.XObjectChange.Name">
+      <summary>An <see cref="T:System.Xml.Linq.XObject" /> has been or will be renamed.</summary>
+    </member>
+    <member name="F:System.Xml.Linq.XObjectChange.Value">
+      <summary>The value of an <see cref="T:System.Xml.Linq.XObject" /> has been or will be changed. In addition, a change in the serialization of an empty element (either from an empty tag to start/end tag pair or vice versa) raises this event.</summary>
+    </member>
+    <member name="T:System.Xml.Linq.XObjectChangeEventArgs">
+      <summary>Provides data for the <see cref="E:System.Xml.Linq.XObject.Changing" /> and <see cref="E:System.Xml.Linq.XObject.Changed" /> events.</summary>
+    </member>
+    <member name="M:System.Xml.Linq.XObjectChangeEventArgs.#ctor(System.Xml.Linq.XObjectChange)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XObjectChangeEventArgs" /> class. </summary>
+      <param name="objectChange">An <see cref="T:System.Xml.Linq.XObjectChange" /> that contains the event arguments for LINQ to XML events.</param>
+    </member>
+    <member name="F:System.Xml.Linq.XObjectChangeEventArgs.Add">
+      <summary>Event argument for an <see cref="F:System.Xml.Linq.XObjectChange.Add" /> change event.</summary>
+    </member>
+    <member name="F:System.Xml.Linq.XObjectChangeEventArgs.Name">
+      <summary>Event argument for a <see cref="F:System.Xml.Linq.XObjectChange.Name" /> change event.</summary>
+    </member>
+    <member name="P:System.Xml.Linq.XObjectChangeEventArgs.ObjectChange">
+      <summary>Gets the type of change.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XObjectChange" /> that contains the type of change.</returns>
+    </member>
+    <member name="F:System.Xml.Linq.XObjectChangeEventArgs.Remove">
+      <summary>Event argument for a <see cref="F:System.Xml.Linq.XObjectChange.Remove" /> change event.</summary>
+    </member>
+    <member name="F:System.Xml.Linq.XObjectChangeEventArgs.Value">
+      <summary>Event argument for a <see cref="F:System.Xml.Linq.XObjectChange.Value" /> change event.</summary>
+    </member>
+    <member name="T:System.Xml.Linq.XProcessingInstruction">
+      <summary>Represents an XML processing instruction. </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XProcessingInstruction.#ctor(System.String,System.String)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XProcessingInstruction" /> class. </summary>
+      <param name="target">A <see cref="T:System.String" /> containing the target application for this <see cref="T:System.Xml.Linq.XProcessingInstruction" />.</param>
+      <param name="data">The string data for this <see cref="T:System.Xml.Linq.XProcessingInstruction" />.</param>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="target" /> or <paramref name="data" /> parameter is null.</exception>
+      <exception cref="T:System.ArgumentException">The <paramref name="target" /> does not follow the constraints of an XML name.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XProcessingInstruction.#ctor(System.Xml.Linq.XProcessingInstruction)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XProcessingInstruction" /> class. </summary>
+      <param name="other">The <see cref="T:System.Xml.Linq.XProcessingInstruction" /> node to copy from.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XProcessingInstruction.Data">
+      <summary>Gets or sets the string value of this processing instruction.</summary>
+      <returns>A <see cref="T:System.String" /> that contains the string value of this processing instruction.</returns>
+      <exception cref="T:System.ArgumentNullException">The string <paramref name="value" /> is null.</exception>
+    </member>
+    <member name="P:System.Xml.Linq.XProcessingInstruction.NodeType">
+      <summary>Gets the node type for this node.</summary>
+      <returns>The node type. For <see cref="T:System.Xml.Linq.XProcessingInstruction" /> objects, this value is <see cref="F:System.Xml.XmlNodeType.ProcessingInstruction" />.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XProcessingInstruction.Target">
+      <summary>Gets or sets a string containing the target application for this processing instruction.</summary>
+      <returns>A <see cref="T:System.String" /> containing the target application for this processing instruction.</returns>
+      <exception cref="T:System.ArgumentNullException">The string <paramref name="value" /> is null.</exception>
+      <exception cref="T:System.ArgumentException">The <paramref name="target" /> does not follow the constraints of an XML name.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XProcessingInstruction.WriteTo(System.Xml.XmlWriter)">
+      <summary>Writes this processing instruction to an <see cref="T:System.Xml.XmlWriter" />.</summary>
+      <param name="writer">The <see cref="T:System.Xml.XmlWriter" /> to write this processing instruction to.</param>
+    </member>
+    <member name="T:System.Xml.Linq.XStreamingElement">
+      <summary>Represents elements in an XML tree that supports deferred streaming output.</summary>
+    </member>
+    <member name="M:System.Xml.Linq.XStreamingElement.#ctor(System.Xml.Linq.XName)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XElement" /> class from the specified <see cref="T:System.Xml.Linq.XName" />.</summary>
+      <param name="name">An <see cref="T:System.Xml.Linq.XName" /> that contains the name of the element.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XStreamingElement.#ctor(System.Xml.Linq.XName,System.Object)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XStreamingElement" /> class with the specified name and content.</summary>
+      <param name="name">An <see cref="T:System.Xml.Linq.XName" /> that contains the element name.</param>
+      <param name="content">The contents of the element.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XStreamingElement.#ctor(System.Xml.Linq.XName,System.Object[])">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XStreamingElement" /> class with the specified name and content.</summary>
+      <param name="name">An <see cref="T:System.Xml.Linq.XName" /> that contains the element name.</param>
+      <param name="content">The contents of the element.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XStreamingElement.Add(System.Object)">
+      <summary>Adds the specified content as children to this <see cref="T:System.Xml.Linq.XStreamingElement" />.</summary>
+      <param name="content">Content to be added to the streaming element.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XStreamingElement.Add(System.Object[])">
+      <summary>Adds the specified content as children to this <see cref="T:System.Xml.Linq.XStreamingElement" />.</summary>
+      <param name="content">Content to be added to the streaming element.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XStreamingElement.Name">
+      <summary>Gets or sets the name of this streaming element.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XName" /> that contains the name of this streaming element.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XStreamingElement.Save(System.IO.Stream)">
+      <summary>Outputs this <see cref="T:System.Xml.Linq.XStreamingElement" /> to the specified <see cref="T:System.IO.Stream" />.</summary>
+      <param name="stream">The stream to output this <see cref="T:System.Xml.Linq.XDocument" /> to.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XStreamingElement.Save(System.IO.Stream,System.Xml.Linq.SaveOptions)">
+      <summary>Outputs this <see cref="T:System.Xml.Linq.XStreamingElement" /> to the specified <see cref="T:System.IO.Stream" />, optionally specifying formatting behavior.</summary>
+      <param name="stream">The stream to output this <see cref="T:System.Xml.Linq.XDocument" /> to.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.SaveOptions" /> that specifies formatting behavior.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XStreamingElement.Save(System.IO.TextWriter)">
+      <summary>Serialize this streaming element to a <see cref="T:System.IO.TextWriter" />.</summary>
+      <param name="textWriter">A <see cref="T:System.IO.TextWriter" /> that the <see cref="T:System.Xml.Linq.XStreamingElement" /> will be written to.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XStreamingElement.Save(System.IO.TextWriter,System.Xml.Linq.SaveOptions)">
+      <summary>Serialize this streaming element to a <see cref="T:System.IO.TextWriter" />, optionally disabling formatting.</summary>
+      <param name="textWriter">The <see cref="T:System.IO.TextWriter" /> to output the XML to.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.SaveOptions" /> that specifies formatting behavior.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XStreamingElement.Save(System.Xml.XmlWriter)">
+      <summary>Serialize this streaming element to an <see cref="T:System.Xml.XmlWriter" />.</summary>
+      <param name="writer">A <see cref="T:System.Xml.XmlWriter" /> that the <see cref="T:System.Xml.Linq.XElement" /> will be written to.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XStreamingElement.ToString">
+      <summary>Returns the formatted (indented) XML for this streaming element.</summary>
+      <returns>A <see cref="T:System.String" /> containing the indented XML.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XStreamingElement.ToString(System.Xml.Linq.SaveOptions)">
+      <summary>Returns the XML for this streaming element, optionally disabling formatting.</summary>
+      <returns>A <see cref="T:System.String" /> containing the XML.</returns>
+      <param name="options">A <see cref="T:System.Xml.Linq.SaveOptions" /> that specifies formatting behavior.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XStreamingElement.WriteTo(System.Xml.XmlWriter)">
+      <summary>Writes this streaming element to an <see cref="T:System.Xml.XmlWriter" />.</summary>
+      <param name="writer">An <see cref="T:System.Xml.XmlWriter" /> into which this method will write.</param>
+    </member>
+    <member name="T:System.Xml.Linq.XText">
+      <summary>Represents a text node.  </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XText.#ctor(System.String)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XText" /> class. </summary>
+      <param name="value">The <see cref="T:System.String" /> that contains the value of the <see cref="T:System.Xml.Linq.XText" /> node.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XText.#ctor(System.Xml.Linq.XText)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XText" /> class from another <see cref="T:System.Xml.Linq.XText" /> object.</summary>
+      <param name="other">The <see cref="T:System.Xml.Linq.XText" /> node to copy from.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XText.NodeType">
+      <summary>Gets the node type for this node.</summary>
+      <returns>The node type. For <see cref="T:System.Xml.Linq.XText" /> objects, this value is <see cref="F:System.Xml.XmlNodeType.Text" />.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XText.Value">
+      <summary>Gets or sets the value of this node.</summary>
+      <returns>A <see cref="T:System.String" /> that contains the value of this node.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XText.WriteTo(System.Xml.XmlWriter)">
+      <summary>Writes this node to an <see cref="T:System.Xml.XmlWriter" />.</summary>
+      <param name="writer">An <see cref="T:System.Xml.XmlWriter" /> into which this method will write.</param>
+    </member>
+  </members>
+</doc>
\ No newline at end of file
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl3/de/System.Runtime.Serialization.Json.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl3/de/System.Runtime.Serialization.Json.resources.dll
new file mode 100644 (file)
index 0000000..0dbc0ab
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl3/de/System.Runtime.Serialization.Json.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl3/de/System.Xml.Linq.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl3/de/System.Xml.Linq.resources.dll
new file mode 100644 (file)
index 0000000..a88de0e
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl3/de/System.Xml.Linq.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl3/es/System.Runtime.Serialization.Json.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl3/es/System.Runtime.Serialization.Json.resources.dll
new file mode 100644 (file)
index 0000000..d68a035
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl3/es/System.Runtime.Serialization.Json.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl3/es/System.Xml.Linq.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl3/es/System.Xml.Linq.resources.dll
new file mode 100644 (file)
index 0000000..2bf0bc9
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl3/es/System.Xml.Linq.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl3/fr/System.Runtime.Serialization.Json.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl3/fr/System.Runtime.Serialization.Json.resources.dll
new file mode 100644 (file)
index 0000000..4710166
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl3/fr/System.Runtime.Serialization.Json.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl3/fr/System.Xml.Linq.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl3/fr/System.Xml.Linq.resources.dll
new file mode 100644 (file)
index 0000000..5990df6
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl3/fr/System.Xml.Linq.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl3/it/System.Runtime.Serialization.Json.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl3/it/System.Runtime.Serialization.Json.resources.dll
new file mode 100644 (file)
index 0000000..f854209
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl3/it/System.Runtime.Serialization.Json.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl3/it/System.Xml.Linq.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl3/it/System.Xml.Linq.resources.dll
new file mode 100644 (file)
index 0000000..e3610cf
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl3/it/System.Xml.Linq.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl3/ja/System.Runtime.Serialization.Json.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl3/ja/System.Runtime.Serialization.Json.resources.dll
new file mode 100644 (file)
index 0000000..eaa69c0
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl3/ja/System.Runtime.Serialization.Json.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl3/ja/System.Xml.Linq.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl3/ja/System.Xml.Linq.resources.dll
new file mode 100644 (file)
index 0000000..2b03196
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl3/ja/System.Xml.Linq.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl3/ko/System.Runtime.Serialization.Json.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl3/ko/System.Runtime.Serialization.Json.resources.dll
new file mode 100644 (file)
index 0000000..1b6377e
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl3/ko/System.Runtime.Serialization.Json.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl3/ko/System.Xml.Linq.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl3/ko/System.Xml.Linq.resources.dll
new file mode 100644 (file)
index 0000000..364886b
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl3/ko/System.Xml.Linq.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl3/zh-Hans/System.Runtime.Serialization.Json.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl3/zh-Hans/System.Runtime.Serialization.Json.resources.dll
new file mode 100644 (file)
index 0000000..e9cfcaa
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl3/zh-Hans/System.Runtime.Serialization.Json.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl3/zh-Hans/System.Xml.Linq.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl3/zh-Hans/System.Xml.Linq.resources.dll
new file mode 100644 (file)
index 0000000..4c73ad6
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl3/zh-Hans/System.Xml.Linq.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl3/zh-Hant/System.Runtime.Serialization.Json.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl3/zh-Hant/System.Runtime.Serialization.Json.resources.dll
new file mode 100644 (file)
index 0000000..8d2eb89
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl3/zh-Hant/System.Runtime.Serialization.Json.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl3/zh-Hant/System.Xml.Linq.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl3/zh-Hant/System.Xml.Linq.resources.dll
new file mode 100644 (file)
index 0000000..8c91e9d
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl3/zh-Hant/System.Xml.Linq.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4-wp/Hammock.WindowsPhone.dll b/trunk/packages/Hammock.1.2.3/lib/sl4-wp/Hammock.WindowsPhone.dll
new file mode 100644 (file)
index 0000000..a5df487
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4-wp/Hammock.WindowsPhone.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4-wp/ICSharpCode.SharpZipLib.WindowsPhone.dll b/trunk/packages/Hammock.1.2.3/lib/sl4-wp/ICSharpCode.SharpZipLib.WindowsPhone.dll
new file mode 100644 (file)
index 0000000..98b6900
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4-wp/ICSharpCode.SharpZipLib.WindowsPhone.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/Hammock.Silverlight.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/Hammock.Silverlight.dll
new file mode 100644 (file)
index 0000000..9a56e56
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/Hammock.Silverlight.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/ICSharpCode.SharpZipLib.Silverlight.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/ICSharpCode.SharpZipLib.Silverlight.dll
new file mode 100644 (file)
index 0000000..9bbd479
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/ICSharpCode.SharpZipLib.Silverlight.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/Microsoft.CSharp.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/Microsoft.CSharp.dll
new file mode 100644 (file)
index 0000000..8cb4b2f
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/Microsoft.CSharp.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/Microsoft.CSharp.xml b/trunk/packages/Hammock.1.2.3/lib/sl4/Microsoft.CSharp.xml
new file mode 100644 (file)
index 0000000..8f9dc37
--- /dev/null
@@ -0,0 +1,190 @@
+<?xml version="1.0" encoding="utf-8"?>
+<doc>
+  <assembly>
+    <name>Microsoft.CSharp</name>
+  </assembly>
+  <members>
+    <member name="T:Microsoft.CSharp.RuntimeBinder.Binder">
+      <summary>Contains factory methods to create dynamic call site binders for CSharp.</summary>
+    </member>
+    <member name="M:Microsoft.CSharp.RuntimeBinder.Binder.BinaryOperation(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.Linq.Expressions.ExpressionType,System.Type,System.Collections.Generic.IEnumerable{Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo})">
+      <summary>Initializes a new CSharp binary operation binder.</summary>
+      <returns>Returns a new CSharp binary operation binder.</returns>
+      <param name="flags">The flags with which to initialize the binder.</param>
+      <param name="operation">The binary operation kind.</param>
+      <param name="context">The <see cref="T:System.Type" /> object that indicates where this operation is used.</param>
+      <param name="argumentInfo">The sequence of <see cref="T:Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo" /> instances for the arguments to this operation.</param>
+    </member>
+    <member name="M:Microsoft.CSharp.RuntimeBinder.Binder.Convert(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.Type,System.Type)">
+      <summary>Initializes a new CSharp convert binder.</summary>
+      <returns>Returns a new CSharp convert binder.</returns>
+      <param name="flags">The flags with which to initialize the binder.</param>
+      <param name="type">The type to convert to.</param>
+      <param name="context">The <see cref="T:System.Type" /> object that indicates where this operation is used.</param>
+    </member>
+    <member name="M:Microsoft.CSharp.RuntimeBinder.Binder.GetIndex(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.Type,System.Collections.Generic.IEnumerable{Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo})">
+      <summary>Initializes a new CSharp get index binder.</summary>
+      <returns>Returns a new CSharp get index binder.</returns>
+      <param name="flags">The flags with which to initialize the binder.</param>
+      <param name="context">The <see cref="T:System.Type" /> that indicates where this operation is used.</param>
+      <param name="argumentInfo">The sequence of <see cref="T:Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo" /> instances for the arguments to this operation.</param>
+    </member>
+    <member name="M:Microsoft.CSharp.RuntimeBinder.Binder.GetMember(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.String,System.Type,System.Collections.Generic.IEnumerable{Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo})">
+      <summary>Initializes a new CSharp get member binder.</summary>
+      <returns>Returns a new CSharp get member binder.</returns>
+      <param name="flags">The flags with which to initialize the binder.</param>
+      <param name="name">The name of the member to get.</param>
+      <param name="context">The <see cref="T:System.Type" /> that indicates where this operation is used.</param>
+      <param name="argumentInfo">The sequence of <see cref="T:Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo" /> instances for the arguments to this operation.</param>
+    </member>
+    <member name="M:Microsoft.CSharp.RuntimeBinder.Binder.Invoke(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.Type,System.Collections.Generic.IEnumerable{Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo})">
+      <summary>Initializes a new CSharp invoke binder.</summary>
+      <returns>Returns a new CSharp invoke binder.</returns>
+      <param name="flags">The flags with which to initialize the binder.</param>
+      <param name="context">The <see cref="T:System.Type" /> that indicates where this operation is used.</param>
+      <param name="argumentInfo">The sequence of <see cref="T:Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo" /> instances for the arguments to this operation.</param>
+    </member>
+    <member name="M:Microsoft.CSharp.RuntimeBinder.Binder.InvokeConstructor(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.Type,System.Collections.Generic.IEnumerable{Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo})">
+      <summary>Initializes a new CSharp invoke constructor binder.</summary>
+      <returns>Returns a new CSharp invoke constructor binder.</returns>
+      <param name="flags">The flags with which to initialize the binder.</param>
+      <param name="context">The <see cref="T:System.Type" /> that indicates where this operation is used.</param>
+      <param name="argumentInfo">The sequence of <see cref="T:Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo" /> instances for the arguments to this operation.</param>
+    </member>
+    <member name="M:Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.String,System.Collections.Generic.IEnumerable{System.Type},System.Type,System.Collections.Generic.IEnumerable{Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo})">
+      <summary>Initializes a new CSharp invoke member binder.</summary>
+      <returns>Returns a new CSharp invoke member binder.</returns>
+      <param name="flags">The flags with which to initialize the binder.</param>
+      <param name="name">The name of the member to invoke.</param>
+      <param name="typeArguments">The list of type arguments specified for this invoke.</param>
+      <param name="context">The <see cref="T:System.Type" /> that indicates where this operation is used.</param>
+      <param name="argumentInfo">The sequence of <see cref="T:Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo" /> instances for the arguments to this operation.</param>
+    </member>
+    <member name="M:Microsoft.CSharp.RuntimeBinder.Binder.IsEvent(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.String,System.Type)">
+      <summary>Initializes a new CSharp is event binder.</summary>
+      <returns>Returns a new CSharp is event binder.</returns>
+      <param name="flags">The flags with which to initialize the binder.</param>
+      <param name="name">The name of the event to look for.</param>
+      <param name="context">The <see cref="T:System.Type" /> that indicates where this operation is used.</param>
+    </member>
+    <member name="M:Microsoft.CSharp.RuntimeBinder.Binder.SetIndex(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.Type,System.Collections.Generic.IEnumerable{Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo})">
+      <summary>Initializes a new CSharp set index binder.</summary>
+      <returns>Returns a new CSharp set index binder.</returns>
+      <param name="flags">The flags with which to initialize the binder.</param>
+      <param name="context">The <see cref="T:System.Type" /> that indicates where this operation is used.</param>
+      <param name="argumentInfo">The sequence of <see cref="T:Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo" /> instances for the arguments to this operation.</param>
+    </member>
+    <member name="M:Microsoft.CSharp.RuntimeBinder.Binder.SetMember(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.String,System.Type,System.Collections.Generic.IEnumerable{Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo})">
+      <summary>Initializes a new CSharp set member binder.</summary>
+      <returns>Returns a new CSharp set member binder.</returns>
+      <param name="flags">The flags with which to initialize the binder.</param>
+      <param name="name">The name of the member to set.</param>
+      <param name="context">The <see cref="T:System.Type" /> that indicates where this operation is used.</param>
+      <param name="argumentInfo">The sequence of <see cref="T:Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo" /> instances for the arguments to this operation.</param>
+    </member>
+    <member name="M:Microsoft.CSharp.RuntimeBinder.Binder.UnaryOperation(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.Linq.Expressions.ExpressionType,System.Type,System.Collections.Generic.IEnumerable{Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo})">
+      <summary>Initializes a new CSharp unary operation binder.</summary>
+      <returns>Returns a new CSharp unary operation binder.</returns>
+      <param name="flags">The flags with which to initialize the binder.</param>
+      <param name="operation">The unary operation kind.</param>
+      <param name="context">The <see cref="T:System.Type" /> object that indicates where this operation is used.</param>
+      <param name="argumentInfo">The sequence of <see cref="T:Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo" /> instances for the arguments to this operation.</param>
+    </member>
+    <member name="T:Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo">
+      <summary>Represents information about C# dynamic operations that are specific to particular arguments at a call site. Instances of this class are generated by the C# compiler.</summary>
+    </member>
+    <member name="M:Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags,System.String)">
+      <summary>Initializes a new instance of the <see cref="T:Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo" /> class.</summary>
+      <returns>A new instance of the <see cref="T:Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo" /> class.</returns>
+      <param name="flags">The flags for the argument.</param>
+      <param name="name">The name of the argument, if named; otherwise null.</param>
+    </member>
+    <member name="T:Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags">
+      <summary>Represents information about C# dynamic operations that are specific to particular arguments at a call site. Instances of this class are generated by the C# compiler.</summary>
+    </member>
+    <member name="F:Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags.None">
+      <summary>No additional information to represent.</summary>
+    </member>
+    <member name="F:Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags.UseCompileTimeType">
+      <summary>The argument's compile-time type should be considered during binding.</summary>
+    </member>
+    <member name="F:Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags.Constant">
+      <summary>The argument is a constant.</summary>
+    </member>
+    <member name="F:Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags.NamedArgument">
+      <summary>The argument is a named argument.</summary>
+    </member>
+    <member name="F:Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags.IsRef">
+      <summary>The argument is passed to a ref parameter.</summary>
+    </member>
+    <member name="F:Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags.IsOut">
+      <summary>The argument is passed to an out parameter.</summary>
+    </member>
+    <member name="F:Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags.IsStaticType">
+      <summary>The argument is a <see cref="T:System.Type" /> indicating an actual type name used in source. Used only for target objects in static calls.</summary>
+    </member>
+    <member name="T:Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags">
+      <summary>Represents information about C# dynamic operations that are not specific to particular arguments at a call site. Instances of this class are generated by the C# compiler.</summary>
+    </member>
+    <member name="F:Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags.None">
+      <summary>There is no additional information required for this binder.</summary>
+    </member>
+    <member name="F:Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags.CheckedContext">
+      <summary>The evaluation of this binder happens in a checked context.</summary>
+    </member>
+    <member name="F:Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags.InvokeSimpleName">
+      <summary>The binder represents an invoke on a simple name.</summary>
+    </member>
+    <member name="F:Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags.InvokeSpecialName">
+      <summary>The binder represents an invoke on a specialname.</summary>
+    </member>
+    <member name="F:Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags.BinaryOperationLogical">
+      <summary>The binder represents a logical AND or logical OR that is part of a conditional logical operator evaluation.</summary>
+    </member>
+    <member name="F:Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags.ConvertExplicit">
+      <summary>The binder represents an explicit conversion.</summary>
+    </member>
+    <member name="F:Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags.ConvertArrayIndex">
+      <summary>The binder represents an implicit conversion for use in an array creation expression.</summary>
+    </member>
+    <member name="F:Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags.ResultIndexed">
+      <summary>The result of any bind is going to be indexed get a set index or get index binder.</summary>
+    </member>
+    <member name="F:Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags.ValueFromCompoundAssignment">
+      <summary>The value in this set index or set member comes a compound assignment operator.</summary>
+    </member>
+    <member name="F:Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags.ResultDiscarded">
+      <summary>The binder is used in a position that does not require a result, and can therefore bind to a void returning method.</summary>
+    </member>
+    <member name="T:Microsoft.CSharp.RuntimeBinder.RuntimeBinderException">
+      <summary>Represents an error that occurs when a dynamic bind in the C# runtime binder is processed.</summary>
+    </member>
+    <member name="M:Microsoft.CSharp.RuntimeBinder.RuntimeBinderException.#ctor">
+      <summary>Initializes a new instance of the <see cref="T:Microsoft.CSharp.RuntimeBinder.RuntimeBinderException" /> class.</summary>
+    </member>
+    <member name="M:Microsoft.CSharp.RuntimeBinder.RuntimeBinderException.#ctor(System.String)">
+      <summary>Initializes a new instance of the <see cref="T:Microsoft.CSharp.RuntimeBinder.RuntimeBinderException" /> class that has a specified error message.</summary>
+      <param name="message">The message that describes the exception. The caller of this constructor is required to ensure that this string has been localized for the current system culture.The error message that explains the reason for the exception.</param>
+    </member>
+    <member name="M:Microsoft.CSharp.RuntimeBinder.RuntimeBinderException.#ctor(System.String,System.Exception)">
+      <summary>Initializes a new instance of the <see cref="T:Microsoft.CSharp.RuntimeBinder.RuntimeBinderException" /> class that has a specified error message and a reference to the inner exception that is the cause of this exception.</summary>
+      <param name="message">The error message that explains the reason for the exception.</param>
+      <param name="innerException">The exception that is the cause of the current exception, or a null reference if no inner exception is specified.</param>
+    </member>
+    <member name="T:Microsoft.CSharp.RuntimeBinder.RuntimeBinderInternalCompilerException">
+      <summary>Represents an error that occurs when a dynamic bind in the C# runtime binder is processed.</summary>
+    </member>
+    <member name="M:Microsoft.CSharp.RuntimeBinder.RuntimeBinderInternalCompilerException.#ctor">
+      <summary>Initializes a new instance of the <see cref="T:Microsoft.CSharp.RuntimeBinder.RuntimeBinderInternalCompilerException" /> class with a system-supplied message that describes the error.</summary>
+    </member>
+    <member name="M:Microsoft.CSharp.RuntimeBinder.RuntimeBinderInternalCompilerException.#ctor(System.String)">
+      <summary>Initializes a new instance of the <see cref="T:Microsoft.CSharp.RuntimeBinder.RuntimeBinderInternalCompilerException" /> class with a specified message that describes the error.</summary>
+      <param name="message">The message that describes the exception. The caller of this constructor is required to ensure that this string has been localized for the current system culture.</param>
+    </member>
+    <member name="M:Microsoft.CSharp.RuntimeBinder.RuntimeBinderInternalCompilerException.#ctor(System.String,System.Exception)">
+      <summary>Initializes a new instance of the <see cref="T:Microsoft.CSharp.RuntimeBinder.RuntimeBinderInternalCompilerException" /> class that has a specified error message and a reference to the inner exception that is the cause of this exception.</summary>
+      <param name="message">The error message that explains the reason for the exception.</param>
+      <param name="innerException">The exception that is the cause of the current exception, or a null reference if no inner exception is specified.</param>
+    </member>
+  </members>
+</doc>
\ No newline at end of file
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/System.Json.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/System.Json.dll
new file mode 100644 (file)
index 0000000..dc9eb76
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/System.Json.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/System.Json.xml b/trunk/packages/Hammock.1.2.3/lib/sl4/System.Json.xml
new file mode 100644 (file)
index 0000000..8a736f4
--- /dev/null
@@ -0,0 +1,632 @@
+<?xml version="1.0" encoding="utf-8"?>
+<doc>
+  <assembly>
+    <name>System.Json</name>
+  </assembly>
+  <members>
+    <member name="T:System.Json.JsonArray">
+      <summary>A <see cref="T:System.Json.JsonArray" /> is an ordered sequence of zero or more <see cref="T:System.Json.JsonValue" /> objects.</summary>
+    </member>
+    <member name="M:System.Json.JsonArray.#ctor(System.Collections.Generic.IEnumerable{System.Json.JsonValue})">
+      <summary>Creates an instance of the <see cref="T:System.Json.JsonArray" /> class initialized by an <see cref="T:System.Collections.Generic.IEnumerable`1" /> enumeration of objects of type <see cref="T:System.Json.JsonValue" />.</summary>
+      <param name="items">The <see cref="T:System.Collections.Generic.IEnumerable`1" /> enumeration of objects of type <see cref="T:System.Json.JsonValue" /> used to initialize the JavaScript Object Notation (JSON) array.</param>
+    </member>
+    <member name="M:System.Json.JsonArray.#ctor(System.Json.JsonValue[])">
+      <summary>Creates an instance of the <see cref="T:System.Json.JsonArray" /> class, initialized by an array of type <see cref="T:System.Json.JsonValue" />.</summary>
+      <param name="items">The array of type <see cref="T:System.Json.JsonValue" /> used to initialize the JavaScript Object Notation (JSON) array.</param>
+    </member>
+    <member name="M:System.Json.JsonArray.Add(System.Json.JsonValue)">
+      <summary>Adds a <see cref="T:System.Json.JsonValue" /> object to the end of the array.</summary>
+      <param name="item">The <see cref="T:System.Json.JsonValue" /> object to add.</param>
+    </member>
+    <member name="M:System.Json.JsonArray.AddRange(System.Collections.Generic.IEnumerable{System.Json.JsonValue})">
+      <summary>Adds the elements from a collection of type <see cref="T:System.Json.JsonValue" /> to the <see cref="T:System.Json.Array" />.</summary>
+      <param name="items">Collection of types to add.</param>
+    </member>
+    <member name="M:System.Json.JsonArray.AddRange(System.Json.JsonValue[])">
+      <summary>Adds the elements from an array of type <see cref="T:System.Json.JsonValue" /> to the <see cref="T:System.Json.Array" />.</summary>
+      <param name="items">The array of type <see cref="T:System.Json.JsonValue" /> to be added to the <see cref="T:System.Json.Array" />.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="items" /> is null.</exception>
+    </member>
+    <member name="M:System.Json.JsonArray.Clear">
+      <summary>Removes all JSON CLR types from the <see cref="T:System.Json.JsonArray" />.</summary>
+    </member>
+    <member name="M:System.Json.JsonArray.Contains(System.Json.JsonValue)">
+      <summary>Checks whether a specified JSON CLR type is in the <see cref="T:System.Json.JsonArray" />.</summary>
+      <returns>true if <paramref name="item" /> is found in the <see cref="T:System.Json.JsonArray" />; otherwise, false.</returns>
+      <param name="item">The <see cref="T:System.Json.JsonValue" /> to check for in the array. </param>
+    </member>
+    <member name="M:System.Json.JsonArray.CopyTo(System.Json.JsonValue[],System.Int32)">
+      <summary>Copies the contents of the current JSON CLR array instance into a specified destination array beginning at the specified index.</summary>
+      <param name="array">The destination <see cref="T:System.Json.JsonArray" /> to which the elements of the current <see cref="T:System.Json.JsonArray" /> object are copied</param>
+      <param name="arrayIndex">The zero-based index in the destination array at which the copying of the elements of the JSON CLR array begins.</param>
+    </member>
+    <member name="P:System.Json.JsonArray.Count">
+      <summary>Returns the number of <see cref="T:System.Json.JsonValue" /> elements in the array.</summary>
+      <returns>The number of <see cref="T:System.Json.JsonValue" /> objects in the <see cref="T:System.Json.JsonArray" />.
+</returns>
+    </member>
+    <member name="M:System.Json.JsonArray.IndexOf(System.Json.JsonValue)">
+      <summary>Searches for a specified object and returns the zero-based index of its first occurrence within the <see cref="T:System.Json.JsonArray" />.</summary>
+      <returns>The zero-based index of the first occurrence of <paramref name="item" /> within the <see cref="T:System.Json.JsonArray" />, if found; otherwise, –1.</returns>
+      <param name="item">The <see cref="T:System.Json.JsonValue" /> object to look up. </param>
+    </member>
+    <member name="M:System.Json.JsonArray.Insert(System.Int32,System.Json.JsonValue)">
+      <summary>Insert a JSON CLR type into the array at a specified index.</summary>
+      <param name="index">The zero-based index at which the item should be inserted.</param>
+      <param name="item">The <see cref="T:System.Json.JsonValue" /> object to insert.</param>
+      <exception cref="T:System.ArgumentOutOfRangeException">
+        <paramref name="items" /> is less than zero or larger than the size of the array.</exception>
+    </member>
+    <member name="P:System.Json.JsonArray.IsReadOnly">
+      <summary>Gets a value that indicates whether the <see cref="T:System.Json.JsonArray" /> is read-only.</summary>
+      <returns>true if the <see cref="T:System.Json.JsonArray" />is read-only; otherwise, false.</returns>
+    </member>
+    <member name="P:System.Json.JsonArray.Item(System.Int32)">
+      <summary>Gets or sets the JSON value at a specified index.</summary>
+      <returns>The <see cref="T:System.Json.JsonValue" /> at the specified index.</returns>
+      <param name="index">The zero-based index of the element to get or set.</param>
+      <exception cref="T:System.ArgumentOutOfRangeException">
+        <paramref name="index" /> is not a valid index for the array.</exception>
+      <exception cref="T:System.ArgumentException">The property is set and the <paramref name="value" /> is of a type that is not assignable to the array.</exception>
+    </member>
+    <member name="P:System.Json.JsonArray.JsonType">
+      <summary>Gets the JSON type of the <see cref="T:System.Json.JsonArray" />.</summary>
+      <returns>Returns <see cref="F:System.Json.JsonType.Array" />.</returns>
+    </member>
+    <member name="M:System.Json.JsonArray.Remove(System.Json.JsonValue)">
+      <summary>Removes the first occurrence of the specified JSON value from the array.</summary>
+      <returns>true if <paramref name="item" /> is successfully removed; otherwise, false. This method also returns false if <paramref name="item" /> was not found in the <see cref="T:System.Json.JsonArray" />.</returns>
+      <param name="item">The <see cref="T:System.Json.JsonValue" /> to remove from the <see cref="T:System.Json.JsonArray" />.</param>
+    </member>
+    <member name="M:System.Json.JsonArray.RemoveAt(System.Int32)">
+      <summary>Remove the JSON value at a specified index of <see cref="T:System.Json.JsonArray" />.</summary>
+      <param name="index">The zero-based index at which to remove the <see cref="T:System.Json.JsonValue" />.</param>
+      <exception cref="T:System.ArgumentOutOfRangeException">
+        <paramref name="index" /> is less than zero or <paramref name="index" /> is equal or larger than the size of the array.</exception>
+    </member>
+    <member name="M:System.Json.JsonArray.Save(System.IO.Stream)">
+      <summary>Serializes a JSON CLR array type into a stream of text-based JSON.</summary>
+      <param name="stream">The stream to which the text-based JSON is written.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="stream" /> is null.</exception>
+    </member>
+    <member name="M:System.Json.JsonArray.System#Collections#Generic#IEnumerable{T}#GetEnumerator">
+      <summary>Returns an enumerator that iterates through the <see cref="T:System.Json.JsonValue" /> objects in the array.</summary>
+      <returns>Returns an <see cref="T:System.Collections.Generic.IEnumerator`1" /> object that iterates through the <see cref="T:System.Json.JsonValue" /> elements in the <see cref="T:System.Json.JsonArray" />.</returns>
+    </member>
+    <member name="M:System.Json.JsonArray.System#Collections#IEnumerable#GetEnumerator">
+      <summary>Returns an enumerator that iterates through the <see cref="T:System.Json.JsonValue" /> objects in the array.</summary>
+      <returns>Returns an <see cref="T:System.Collections.IEnumerator" /> object that iterates through the <see cref="T:System.Json.JsonValue" /> elements in the <see cref="T:System.Json.JsonArray" />.
+</returns>
+    </member>
+    <member name="T:System.Json.JsonObject">
+      <summary>A <see cref="T:System.Json.JsonObject" /> is an unordered collection of zero or more key/value pairs.</summary>
+    </member>
+    <member name="M:System.Json.JsonObject.#ctor(System.Collections.Generic.IEnumerable{System.Collections.Generic.KeyValuePair{System.String,System.Json.JsonValue}})">
+      <summary>Creates an instance of the <see cref="T:System.Json.JsonObject" /> class initialized with a <see cref="T:System.Collections.Generic.IEnumerable`1" /> collection of key/value pairs.</summary>
+      <param name="items">The <see cref="T:System.Collections.Generic.IEnumerable`1" /> collection of <see cref="T:System.Collections.Generic.KeyValuePair`2" /> used to initialize the key/value pairs</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="items" /> is null.</exception>
+    </member>
+    <member name="M:System.Json.JsonObject.#ctor(System.Collections.Generic.KeyValuePair{System.String,System.Json.JsonValue}[])">
+      <summary>Creates an instance of the <see cref="T:System.Json.JsonObject" /> class initialized with a collection of key/value pairs.</summary>
+      <param name="items">The <see cref="T:System.Collections.Generic.KeyValuePair`2" /> object used to initialize the key/value pairs.</param>
+    </member>
+    <member name="M:System.Json.JsonObject.#ctor(System.DateTimeOffset)">
+      <summary>Creates an instance of the <see cref="T:System.Json.JsonObject" /> class initialized with a <see cref="T:System.DateTimeOffset" />.</summary>
+      <param name="dto">The <see cref="T:System.DateTimeOffset" /> used to initialize the object.</param>
+    </member>
+    <member name="M:System.Json.JsonObject.Add(System.Collections.Generic.KeyValuePair{System.String,System.Json.JsonValue})">
+      <summary>Adds a key/value pair to the JSON CLR object.</summary>
+      <param name="item">The <see cref="T:System.Collections.Generic.KeyValuePair`2" /> to add.</param>
+    </member>
+    <member name="M:System.Json.JsonObject.Add(System.String,System.Json.JsonValue)">
+      <summary>Adds a key/value pair to the JSON CLR object type.</summary>
+      <param name="key">The key for the element added.</param>
+      <param name="value">The <see cref="T:System.Json.JsonValue" /> for the element added.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="key" /> is null.</exception>
+    </member>
+    <member name="M:System.Json.JsonObject.AddRange(System.Collections.Generic.IEnumerable{System.Collections.Generic.KeyValuePair{System.String,System.Json.JsonValue}})">
+      <summary>Adds a specified collection of key/value pairs to the current instance of the <see cref="T:System.Json.JsonObject" />.</summary>
+      <param name="items">The <see cref="T:System.Collections.Generic.IEnumerable`1" /> collection of key/value pairs to add.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="items" /> is null.</exception>
+    </member>
+    <member name="M:System.Json.JsonObject.AddRange(System.Collections.Generic.KeyValuePair{System.String,System.Json.JsonValue}[])">
+      <summary>Adds a specified array of key/value pairs to the current instance of <see cref="T:System.Json.JsonObject" />.</summary>
+      <param name="items">Collection of key/value pairs.</param>
+    </member>
+    <member name="M:System.Json.JsonObject.Clear">
+      <summary>Removes all key/value pairs from the JSON CLR object.</summary>
+    </member>
+    <member name="M:System.Json.JsonObject.ContainsKey(System.String)">
+      <summary>Checks whether a key/value pair with a specified key exists in the JSON CLR object type.</summary>
+      <returns>true if the JSON CLR object contains the <paramref name="key" />; otherwise, false.
+</returns>
+      <param name="key">The key to check for.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="key" /> is null.</exception>
+    </member>
+    <member name="M:System.Json.JsonObject.CopyTo(System.Collections.Generic.KeyValuePair{System.String,System.Json.JsonValue}[],System.Int32)">
+      <summary>Copies the contents of the JSON CLR object into a specified key/value destination array beginning at a specified index.</summary>
+      <param name="array">The destination array of type <see cref="T:System.Collections.Generic.KeyValuePair`2" /> to which the elements of the <see cref="T:System.Json.JsonObject" /> are copied</param>
+      <param name="arrayIndex">The zero-based index at which to begin the insertion of the contents from the JSON CLR object type.</param>
+    </member>
+    <member name="P:System.Json.JsonObject.Count">
+      <summary>Returns the number of key/value pairs in the <see cref="T:System.Json.JsonObject" />.</summary>
+      <returns>The number of key/value pairs in the JSON CLR object.</returns>
+    </member>
+    <member name="M:System.Json.JsonObject.GetEnumerator">
+      <summary>Returns an enumerator over the key/value pairs contained in the JSON CLR object type.</summary>
+      <returns>
+        <see cref="T:System.Collections.Generic.IEnumerator`1" />.</returns>
+    </member>
+    <member name="P:System.Json.JsonObject.Item(System.String)">
+      <summary>Gets or sets an indexer used to look up a key/value pair based on a specified key.</summary>
+      <returns>The <see cref="T:System.Json.JsonValue" /> that contains the key/value pair looked up.</returns>
+      <param name="key">The key of the pair to look up.</param>
+    </member>
+    <member name="P:System.Json.JsonObject.JsonType">
+      <summary>Gets the JSON type of the <see cref="T:System.Json.JsonObject" />.</summary>
+      <returns>Returns <see cref="F:System.Json.JsonType.Object" />.</returns>
+    </member>
+    <member name="P:System.Json.JsonObject.Keys">
+      <summary>Returns a collection that contains the keys in the <see cref="T:System.Json.JsonObject" />.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.ICollection`1" /> that contains the keys from the JSON CLR object.</returns>
+    </member>
+    <member name="M:System.Json.JsonObject.Remove(System.String)">
+      <summary>Removes the key/value pair with a specified key from the JSON CLR object type.</summary>
+      <returns>true if the element is successfully found and removed; otherwise, false. This method returns false if <paramref name="key" /> is not found in the JSON CLR object.</returns>
+      <param name="key">The key of the item to remove.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="key" /> is null.</exception>
+    </member>
+    <member name="M:System.Json.JsonObject.Save(System.IO.Stream)">
+      <summary>Serializes a JSON CLR object into text-based JSON.</summary>
+      <param name="stream">The stream to which the text-based JSON is written.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="stream" /> is null.</exception>
+    </member>
+    <member name="M:System.Json.JsonObject.System#Collections#Generic#ICollection{T}#Contains(System.Collections.Generic.KeyValuePair{System.String,System.Json.JsonValue})">
+      <summary>Checks whether the <see cref="T:System.Json.JsonObject" /> contains a specified key/value pair.</summary>
+      <returns>true if the <paramref name="item" /> is contained in the instance of the <see cref="T:System.Json.JsonObject" />; otherwise, false.</returns>
+      <param name="item">The key/value pair to check for.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="key" /> is null.</exception>
+    </member>
+    <member name="P:System.Json.JsonObject.System#Collections#Generic#ICollection{T}#IsReadOnly">
+      <summary>Gets a value that indicates whether this JSON CLR object is read-only.</summary>
+      <returns>true if it is read-only; otherwise, false.</returns>
+    </member>
+    <member name="M:System.Json.JsonObject.System#Collections#Generic#ICollection{T}#Remove(System.Collections.Generic.KeyValuePair{System.String,System.Json.JsonValue})">
+      <summary>Removes the first occurrence of a specified key/value pair from the <see cref="T:System.Json.JsonObject" />.</summary>
+      <returns>true if <paramref name="item" /> was successfully removed from the <see cref="T:System.Json.JsonObject" />; otherwise, false. This method also returns false if <paramref name="item" /> is not found in the <see cref="T:System.Json.JsonObject" />.</returns>
+      <param name="item">The key/value pair to remove.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="item" /> is null.</exception>
+    </member>
+    <member name="M:System.Json.JsonObject.System#Collections#IEnumerable#GetEnumerator">
+      <summary>Returns an enumerator that iterates through the key/value pairs in the <see cref="T:System.Json.JsonObject" />.</summary>
+      <returns>
+an <see cref="T:System.Collections.IEnumerator" /> object that iterates through the key/value pairs in the <see cref="T:System.Json.JsonObject" />.
+</returns>
+    </member>
+    <member name="M:System.Json.JsonObject.TryGetValue(System.String,System.Json.JsonValue@)">
+      <summary>Attempts to get the value that corresponds to the specified key.</summary>
+      <returns>true if the instance of the <see cref="T:System.Json.JsonObject" /> contains an element with the specified <paramref name="key" />; otherwise, false.</returns>
+      <param name="key">The key of the value to retrieve.</param>
+      <param name="value">The primitive or structured <see cref="T:System.Json.JsonValue" /> object that has the <paramref name="key" /> specified. This parameter is passed uninitialized. </param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="key" /> is null.</exception>
+    </member>
+    <member name="P:System.Json.JsonObject.Values">
+      <summary>Returns a collection that contains the values in the <see cref="T:System.Json.JsonObject" />.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.ICollection`1" /> that contains the set of <see cref="T:System.Json.JsonValues" /> from the JSON CLR object.</returns>
+    </member>
+    <member name="T:System.Json.JsonPrimitive">
+      <summary>Represents a JavaScript Object Notation (JSON) primitive type in the common language runtime (CLR).</summary>
+    </member>
+    <member name="M:System.Json.JsonPrimitive.#ctor(System.Boolean)">
+      <summary>Initializes a new instance of a <see cref="T:System.Json.JsonPrimitive" /> type with a <see cref="T:System.Boolean" /> type.</summary>
+      <param name="value">The <see cref="T:System.Boolean" /> object that initializes the new instance.</param>
+    </member>
+    <member name="M:System.Json.JsonPrimitive.#ctor(System.Byte)">
+      <summary>Initializes a new instance of a <see cref="T:System.Json.JsonPrimitive" /> type with a <see cref="T:System.Byte" /> type.</summary>
+      <param name="value">The <see cref="T:System.Byte" /> object that initializes the new instance.</param>
+    </member>
+    <member name="M:System.Json.JsonPrimitive.#ctor(System.Char)">
+      <summary>Initializes a new instance of a <see cref="T:System.Json.JsonPrimitive" /> type with a <see cref="T:System.Char" /> type.</summary>
+      <param name="value">The <see cref="T:System.Char" /> object that initializes the new instance.</param>
+    </member>
+    <member name="M:System.Json.JsonPrimitive.#ctor(System.DateTime)">
+      <summary>Initializes a new instance of a <see cref="T:System.Json.JsonPrimitive" /> type with a <see cref="T:System.DateTime" /> type.</summary>
+      <param name="value">The <see cref="T:System.DateTime" /> object that initializes the new instance.</param>
+    </member>
+    <member name="M:System.Json.JsonPrimitive.#ctor(System.Decimal)">
+      <summary>Initializes a new instance of a <see cref="T:System.Json.JsonPrimitive" /> type with a <see cref="T:System.Decimal" /> type.</summary>
+      <param name="value">The <see cref="T:System.Decimal" /> object that initializes the new instance.</param>
+    </member>
+    <member name="M:System.Json.JsonPrimitive.#ctor(System.Double)">
+      <summary>Initializes a new instance of a <see cref="T:System.Json.JsonPrimitive" /> type with a <see cref="T:System.Double" /> type.</summary>
+      <param name="value">The <see cref="T:System.Double" /> object that initializes the new instance.</param>
+    </member>
+    <member name="M:System.Json.JsonPrimitive.#ctor(System.Guid)">
+      <summary>Initializes a new instance of a <see cref="T:System.Json.JsonPrimitive" /> type with a <see cref="T:System.Guid" /> type.</summary>
+      <param name="value">The <see cref="T:System.Guid" /> object that initializes the new instance.</param>
+    </member>
+    <member name="M:System.Json.JsonPrimitive.#ctor(System.Int16)">
+      <summary>Initializes a new instance of a <see cref="T:System.Json.JsonPrimitive" /> type with a <see cref="T:System.Int16" /> type.</summary>
+      <param name="value">The <see cref="T:System.Int16" /> object that initializes the new instance.</param>
+    </member>
+    <member name="M:System.Json.JsonPrimitive.#ctor(System.Int32)">
+      <summary>Initializes a new instance of a <see cref="T:System.Json.JsonPrimitive" /> type with a <see cref="T:System.Int32" /> type.</summary>
+      <param name="value">The <see cref="T:System.Int32" /> object that initializes the new instance.</param>
+    </member>
+    <member name="M:System.Json.JsonPrimitive.#ctor(System.Int64)">
+      <summary>Initializes a new instance of a <see cref="T:System.Json.JsonPrimitive" /> type with a <see cref="T:System.Int64" /> type.</summary>
+      <param name="value">The <see cref="T:System.Int64" /> object that initializes the new instance.</param>
+    </member>
+    <member name="M:System.Json.JsonPrimitive.#ctor(System.SByte)">
+      <summary>Initializes a new instance of a <see cref="T:System.Json.JsonPrimitive" /> type with a <see cref="T:System.SByte" /> type.</summary>
+      <param name="value">The <see cref="T:System.SByte" /> object that initializes the new instance.</param>
+    </member>
+    <member name="M:System.Json.JsonPrimitive.#ctor(System.Single)">
+      <summary>Initializes a new instance of a <see cref="T:System.Json.JsonPrimitive" /> type with a <see cref="T:System.Single" /> type.</summary>
+      <param name="value">The <see cref="T:System.Single" /> object that initializes the new instance.</param>
+    </member>
+    <member name="M:System.Json.JsonPrimitive.#ctor(System.String)">
+      <summary>Initializes a new instance of a <see cref="T:System.Json.JsonPrimitive" /> type with a <see cref="T:System.String" /> type.</summary>
+      <param name="value">The <see cref="T:System.String" /> object that initializes the new instance.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="value" /> is null.</exception>
+    </member>
+    <member name="M:System.Json.JsonPrimitive.#ctor(System.TimeSpan)">
+      <summary>Initializes a new instance of a <see cref="T:System.Json.JsonPrimitive" /> type with a <see cref="T:System.TimeSpan" /> type.</summary>
+      <param name="value">The <see cref="T:System.TimeSpan" /> object that initializes the new instance.</param>
+    </member>
+    <member name="M:System.Json.JsonPrimitive.#ctor(System.UInt16)">
+      <summary>Initializes a new instance of a <see cref="T:System.Json.JsonPrimitive" /> type with a <see cref="T:System.UInt16" /> type.</summary>
+      <param name="value">The <see cref="T:System.UInt16" /> object that initializes the new instance.</param>
+    </member>
+    <member name="M:System.Json.JsonPrimitive.#ctor(System.UInt32)">
+      <summary>Initializes a new instance of a <see cref="T:System.Json.JsonPrimitive" /> type with a <see cref="T:System.UInt32" /> type.</summary>
+      <param name="value">The <see cref="T:System.UInt32" /> object that initializes the new instance.</param>
+    </member>
+    <member name="M:System.Json.JsonPrimitive.#ctor(System.UInt64)">
+      <summary>Initializes a new instance of a <see cref="T:System.Json.JsonPrimitive" /> type with a <see cref="T:System.UInt64" /> type.</summary>
+      <param name="value">The <see cref="T:System.UInt64" /> object that initializes the new instance.</param>
+    </member>
+    <member name="M:System.Json.JsonPrimitive.#ctor(System.Uri)">
+      <summary>Initializes a new instance of a <see cref="T:System.Json.JsonPrimitive" /> type with a <see cref="T:System.Uri" /> type.</summary>
+      <param name="value">The <see cref="T:System.Uri" /> object that initializes the new instance.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="value" /> is null.</exception>
+    </member>
+    <member name="P:System.Json.JsonPrimitive.JsonType">
+      <summary>Gets the <see cref="T:System.JsonType" /> that is associated with this <see cref="T:System.Json.JsonPrimitive" /> object.</summary>
+      <returns>Each <see cref="T:System.Json.JsonPrimitive" /> object is associated with a <see cref="T:System.JsonType" /> that is determined by the type of common language runtime (CLR) object used to initiate it.
+</returns>
+    </member>
+    <member name="M:System.Json.JsonPrimitive.Save(System.IO.Stream)">
+      <summary>Serializes the <see cref="T:System.Json.JsonPrimitive" /> object into text-based JSON.</summary>
+      <param name="stream">The stream to which the text-based JSON is written.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="stream" /> is null.</exception>
+    </member>
+    <member name="T:System.Json.JsonType">
+      <summary>An enumeration that specifies primitive and structured JavaScript Object Notation (JSON) common language runtime (CLR) types.</summary>
+    </member>
+    <member name="F:System.Json.JsonType.String">
+      <summary>Specifies the JSON string CLR type.</summary>
+    </member>
+    <member name="F:System.Json.JsonType.Number">
+      <summary>Specifies the JSON number CLR type.</summary>
+    </member>
+    <member name="F:System.Json.JsonType.Object">
+      <summary>Specifies the JSON object CLR type that consists of an unordered collection of key/value pairs, where the key is of type <see cref="T:System.String" /> and the value is of type <see cref="T:System.Json.JsonValue" />, which can, in turn, be either a primitive or a structured JSON type. </summary>
+    </member>
+    <member name="F:System.Json.JsonType.Array">
+      <summary>Specifies the JSON array CLR type that consists of an ordered collection of <see cref="T:System.Json.JsonValue" /> types, which can, in turn, be either primitive or structured JSON types.</summary>
+    </member>
+    <member name="F:System.Json.JsonType.Boolean">
+      <summary>Specifies the JSON Boolean CLR type.</summary>
+    </member>
+    <member name="T:System.Json.JsonValue">
+      <summary>This is the abstract base class for JavaScript Object Notation (JSON) common language runtime (CLR) types. </summary>
+    </member>
+    <member name="M:System.Json.JsonValue.ContainsKey(System.String)">
+      <summary>Throws an <see cref="T:System.InvalidOperationException" />.</summary>
+      <returns>
+Returns <see cref="T:System.Boolean" />.
+</returns>
+      <param name="key">The key to check.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="key" /> is null.</exception>
+    </member>
+    <member name="P:System.Json.JsonValue.Count">
+      <summary>This method is not supported and throws an exception when called.</summary>
+      <returns>
+Returns <see cref="T:System.Int32" />. 
+</returns>
+    </member>
+    <member name="P:System.Json.JsonValue.Item(System.Int32)">
+      <summary>This indexer is not supported for this base class and throws an exception.</summary>
+      <returns>
+A <see cref="T:System.Json.JsonValue" />.
+</returns>
+      <param name="index">The zero-based index of the element to get or set.</param>
+    </member>
+    <member name="P:System.Json.JsonValue.Item(System.String)">
+      <summary>This indexer is not supported for this base class and throws an exception.</summary>
+      <returns>
+Returns <see cref="T:System.Json.JsonValue" />.
+</returns>
+      <param name="key">The key of the element to get or set.</param>
+    </member>
+    <member name="P:System.Json.JsonValue.JsonType">
+      <summary>When implemented in a derived class, indicates the JSON CLR type represented by the derived type.</summary>
+      <returns>
+Returns <see cref="T:System.Json.JsonType" /> .
+</returns>
+    </member>
+    <member name="M:System.Json.JsonValue.Load(System.IO.Stream)">
+      <summary>Deserializes text-based JSON from a stream into a JSON CLR type.</summary>
+      <returns>
+Returns a class derived from <see cref="T:System.Json.JsonValue" /> that contains the deserialized text-based JSON.</returns>
+      <param name="stream">A <see cref="T:System.IO.Stream" /> that contains text-based JSON content.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="stream" /> is null.</exception>
+    </member>
+    <member name="M:System.Json.JsonValue.Load(System.IO.TextReader)">
+      <summary>Deserializes text-based JSON from a text reader into a JSON CLR type.</summary>
+      <returns>
+Returns a class derived from <see cref="T:System.Json.JsonValue" /> that contains the deserialized text-based JSON.</returns>
+      <param name="textReader">A <see cref="T:System.IO.TextReader" /> over text-based JSON content.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="textReader" /> is null.</exception>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.Boolean)~System.Json.JsonValue">
+      <summary>Enables implicit casts from type <see cref="T:System.Boolean" /> to a <see cref="T:System.JsonPrimitive" />.</summary>
+      <returns>The <see cref="T:System.Json.JsonValue" /> initialized with the <see cref="T:System.Boolean" /> specified.</returns>
+      <param name="value">The <see cref="T:System.Boolean" /> instance used to initialize the <see cref="T:System.JsonPrimitive" />.</param>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.Byte)~System.Json.JsonValue">
+      <summary>Enables implicit casts from type <see cref="T:System.Byte" /> to a <see cref="T:System.JsonPrimitive" />.</summary>
+      <returns>The <see cref="T:System.Json.JsonValue" /> initialized with the <see cref="T:System.Byte" /> specified.
+</returns>
+      <param name="value">The <see cref="T:System.Byte" /> instance used to initialize the <see cref="T:System.JsonPrimitive" />.</param>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.Char)~System.Json.JsonValue">
+      <summary>Enables implicit casts from type <see cref="T:System.Char" /> to a <see cref="T:System.JsonPrimitive" />.</summary>
+      <returns>The <see cref="T:System.Json.JsonValue" /> initialized with the <see cref="T:System.Char" /> specified.
+</returns>
+      <param name="value">The <see cref="T:System.Char" /> instance used to initialize the <see cref="T:System.JsonPrimitive" />.</param>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.DateTime)~System.Json.JsonValue">
+      <summary>Enables implicit casts from type <see cref="T:System.DateTime" /> to a <see cref="T:System.JsonPrimitive" />.</summary>
+      <returns>The <see cref="T:System.Json.JsonValue" /> initialized with the <see cref="T:System.DateTime" /> specified.</returns>
+      <param name="value">The <see cref="T:System.DateTime" /> instance used to initialize the <see cref="T:System.JsonPrimitive" />.</param>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.DateTimeOffset)~System.Json.JsonValue">
+      <summary>Enables implicit casts from type <see cref="T:System.DateTimeOffset" /> to a <see cref="T:System.JsonObject" />.</summary>
+      <returns>The <see cref="T:System.Json.JsonObject" /> initialized with the <see cref="T:System.DateTimeOffset" /> specified.</returns>
+      <param name="value">The <see cref="T:System.DateTimeOffset" /> instance used to initialize the <see cref="T:System.JsonObject" />.</param>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.Decimal)~System.Json.JsonValue">
+      <summary>Enables implicit casts from type <see cref="T:System.Decimal" /> to a <see cref="T:System.JsonPrimitive" />.</summary>
+      <returns>The <see cref="T:System.Json.JsonValue" /> initialized with the <see cref="T:System.Decimal" /> specified.</returns>
+      <param name="value">The <see cref="T:System.Decimal" /> instance used to initialize the <see cref="T:System.JsonPrimitive" />.</param>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.Double)~System.Json.JsonValue">
+      <summary>Enables implicit casts from type <see cref="T:System.Double" /> to a <see cref="T:System.JsonPrimitive" />.</summary>
+      <returns>The <see cref="T:System.Json.JsonValue" /> initialized with the <see cref="T:System.Double" /> specified.</returns>
+      <param name="value">The <see cref="T:System.Double" /> instance used to initialize the <see cref="T:System.JsonPrimitive" />.</param>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.Guid)~System.Json.JsonValue">
+      <summary>Enables implicit casts from type <see cref="T:System.Guid" /> to a <see cref="T:System.JsonPrimitive" />.</summary>
+      <returns>The <see cref="T:System.Json.JsonValue" /> initialized with the <see cref="T:System.Guid" /> specified.</returns>
+      <param name="value">The <see cref="T:System.Guid" /> instance used to initialize the <see cref="T:System.JsonPrimitive" />.</param>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.Int16)~System.Json.JsonValue">
+      <summary>Enables implicit casts from type <see cref="T:System.Int16" /> to a <see cref="T:System.JsonPrimitive" />.</summary>
+      <returns>The <see cref="T:System.Json.JsonValue" /> initialized with the <see cref="T:System.Int16" /> specified.</returns>
+      <param name="value">The <see cref="T:System.Int16" /> instance used to initialize the <see cref="T:System.JsonPrimitive" />.</param>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.Int32)~System.Json.JsonValue">
+      <summary>Enables implicit casts from type <see cref="T:System.Int32" /> to a <see cref="T:System.JsonPrimitive" />.</summary>
+      <returns>The <see cref="T:System.Json.JsonValue" /> initialized with the <see cref="T:System.Int32" /> specified.</returns>
+      <param name="value">The <see cref="T:System.Int32" /> instance used to initialize the <see cref="T:System.JsonPrimitive" />.</param>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.Int64)~System.Json.JsonValue">
+      <summary>Enables implicit casts from type <see cref="T:System.Int64" /> to a <see cref="T:System.JsonPrimitive" />.</summary>
+      <returns>The <see cref="T:System.Json.JsonValue" /> initialized with the <see cref="T:System.Int64" /> specified.</returns>
+      <param name="value">The <see cref="T:System.Int64" /> instance used to initialize the <see cref="T:System.JsonPrimitive" />.</param>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.Json.JsonValue)~System.DateTime">
+      <summary>Enables implicit casts from an instance of type <see cref="T:System.Json.JsonValue" /> to a <see cref="T:System.Datetime" /> object.</summary>
+      <returns>The <see cref="T:System.DateTime" /> initialized with the <see cref="T:System.Json.JsonValue" /> value specified.</returns>
+      <param name="value">The instance of <see cref="T:System.Json.JsonValue" /> used to initialize the <see cref="T:System.DateTime" /> object. </param>
+      <exception cref="T:System.InvalidCastException">The <see cref="P:System.Json.JsonValue.JsonType" /> of <paramref name="value" /> is not a <see cref="F:System.Json.JsonType.String" /> and so cannot be cast to <see cref="T:System.DateTime" />.</exception>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.Json.JsonValue)~System.TimeSpan">
+      <summary>Enables implicit casts from an instance of type <see cref="T:System.Json.JsonValue" /> to a <see cref="T:System.TimeSpan" /> object.</summary>
+      <returns>The <see cref="T:System.TimeSpan" /> initialized with the <see cref="T:System.Json.JsonValue" /> value specified.</returns>
+      <param name="value">The instance of <see cref="T:System.Json.JsonValue" /> used to initialize the <see cref="T:System.TimeSpan" /> object.</param>
+      <exception cref="T:System.InvalidCastException">The <see cref="P:System.Json.JsonValue.JsonType" /> of <paramref name="value" /> is not a <see cref="F:System.Json.JsonType.String" /> and so cannot be cast to <see cref="T:System.TimeSpan" />.</exception>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.Json.JsonValue)~System.Boolean">
+      <summary>Enables implicit casts from an instance of type <see cref="T:System.Json.JsonValue" /> to a <see cref="T:System.Boolean" /> object.</summary>
+      <returns>The <see cref="T:System.Boolean" /> initialized with the <see cref="T:System.Json.JsonValue" /> value specified.</returns>
+      <param name="value">The instance of <see cref="T:System.Json.JsonValue" /> used to initialize the <see cref="T:System.Boolean" /> object. </param>
+      <exception cref="T:System.InvalidCastException">The <see cref="P:System.Json.JsonValue.JsonType" /> of <paramref name="value" /> is not a <see cref="F:System.Json.JsonType.Boolean" /> and so cannot be cast to <see cref="T:System.Boolean" />.</exception>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.Json.JsonValue)~System.Char">
+      <summary>Enables implicit casts from an instance of type <see cref="T:System.Json.JsonValue" /> to a <see cref="T:System.Char" /> object.</summary>
+      <returns>The <see cref="T:System.Char" /> initialized with the <see cref="T:System.Json.JsonValue" /> value specified.</returns>
+      <param name="value">The instance of <see cref="T:System.Json.JsonValue" /> used to initialize the <see cref="T:System.Char" /> object. </param>
+      <exception cref="T:System.InvalidCastException">The <see cref="P:System.Json.JsonValue.JsonType" /> of <paramref name="value" /> is not a <see cref="F:System.Json.JsonType.String" /> and so cannot be cast to <see cref="T:System.Boolean" />, or there is not exactly one character in the <paramref name="value" /> parameter.</exception>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.Json.JsonValue)~System.Int64">
+      <summary>Enables implicit casts from an instance of type <see cref="T:System.Json.JsonValue" /> to a <see cref="T:System.Int64" /> object.</summary>
+      <returns>The <see cref="T:System.Int64" /> initialized with the <see cref="T:System.Json.JsonValue" /> value specified.</returns>
+      <param name="value">The instance of <see cref="T:System.Json.JsonValue" /> used to initialize the <see cref="T:System.Int64" /> object. </param>
+      <exception cref="T:System.InvalidCastException">The <see cref="P:System.Json.JsonValue.JsonType" /> of <paramref name="value" /> is not a <see cref="F:System.Json.JsonType.Number" /> and so cannot be cast to <see cref="T:System.Int64" />.</exception>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.Json.JsonValue)~System.Decimal">
+      <summary>Enables implicit casts from an instance of type <see cref="T:System.Json.JsonValue" /> to a <see cref="T:System.Decimal" /> object.</summary>
+      <returns>The <see cref="T:System.Decimal" /> initialized with the <see cref="T:System.Json.JsonValue" /> value specified.</returns>
+      <param name="value">The instance of <see cref="T:System.Json.JsonValue" /> used to initialize the <see cref="T:System.Decimal" /> object. </param>
+      <exception cref="T:System.InvalidCastException">The <see cref="P:System.Json.JsonValue.JsonType" /> of <paramref name="value" /> is not a <see cref="F:System.Json.JsonType.Number" /> and so cannot be cast to <see cref="T:System.Decimal" />.</exception>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.Json.JsonValue)~System.Int32">
+      <summary>Enables implicit casts from an instance of type <see cref="T:System.Json.JsonValue" /> to a <see cref="T:System.Int32" /> object.</summary>
+      <returns>The <see cref="T:System.Int32" /> initialized with the <see cref="T:System.Json.JsonValue" /> value specified.</returns>
+      <param name="value">The instance of <see cref="T:System.Json.JsonValue" /> used to initialize the <see cref="T:System.Int32" /> object. </param>
+      <exception cref="T:System.InvalidCastException">The <see cref="P:System.Json.JsonValue.JsonType" /> of <paramref name="value" /> is not a <see cref="F:System.Json.JsonType.Number" /> and so cannot be cast to <see cref="T:System.Int32" />.</exception>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.Json.JsonValue)~System.UInt64">
+      <summary>Enables implicit casts from an instance of type <see cref="T:System.Json.JsonValue" /> to a <see cref="T:System.UInt64" /> object.</summary>
+      <returns>The <see cref="T:System.UInt64" /> initialized with the <see cref="T:System.Json.JsonValue" /> value specified.</returns>
+      <param name="value">The instance of <see cref="T:System.Json.JsonValue" /> used to initialize the <see cref="T:System.UInt64" /> object. </param>
+      <exception cref="T:System.InvalidCastException">The <see cref="P:System.Json.JsonValue.JsonType" /> of <paramref name="value" /> is not a <see cref="F:System.Json.JsonType.Number" /> and so cannot be cast to <see cref="T:System.UInt64" />.</exception>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.Json.JsonValue)~System.String">
+      <summary>Enables implicit casts from an instance of type <see cref="T:System.Json.JsonValue" /> to a <see cref="T:System.String" /> object.</summary>
+      <returns>The <see cref="T:System.String" /> initialized with the <see cref="T:System.Json.JsonValue" /> value specified or null if <paramref name="value" /> is null.</returns>
+      <param name="value">The instance of <see cref="T:System.Json.JsonValue" /> used to initialize the <see cref="T:System.String" /> object.</param>
+      <exception cref="T:System.InvalidCastException">The <see cref="P:System.Json.JsonValue.JsonType" /> of <paramref name="value" /> is not a <see cref="F:System.Json.JsonType.String" /> and so cannot be cast to <see cref="T:System.String" />.</exception>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.Json.JsonValue)~System.DateTimeOffset">
+      <summary>Enables implicit casts from an instance of type <see cref="T:System.Json.JsonValue" /> to a <see cref="T:System.DateTimeOffset" /> object.</summary>
+      <returns>The <see cref="T:System.DateTimeOffset" /> initialized with the <see cref="T:System.Json.JsonValue" /> value specified.</returns>
+      <param name="value">The instance of <see cref="T:System.Json.JsonValue" /> used to initialize the <see cref="T:System.DateTimeOffset" /> object. </param>
+      <exception cref="T:System.InvalidCastException">The <see cref="P:System.Json.JsonValue.JsonType" /> of <paramref name="value" /> is not a <see cref="F:System.Json.JsonType.Object" /> and the object does not contain two fields that are called “DateTime” and “OffsetMinutes”. </exception>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.Json.JsonValue)~System.Single">
+      <summary>Enables implicit casts from an instance of type <see cref="T:System.Json.JsonValue" /> to a <see cref="T:System.Single" /> object.</summary>
+      <returns>The <see cref="T:System.Single" /> initialized with the <see cref="T:System.Json.JsonValue" /> value specified.</returns>
+      <param name="value">The instance of <see cref="T:System.Json.JsonValue" /> used to initialize the <see cref="T:System.Single" /> object.</param>
+      <exception cref="T:System.InvalidCastException">The <see cref="P:System.Json.JsonValue.JsonType" /> of <paramref name="value" /> is not a <see cref="F:System.Json.JsonType.Number" /> and so cannot be cast to <see cref="T:System.Single" />.</exception>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.Json.JsonValue)~System.Double">
+      <summary>Enables implicit casts from an instance of type <see cref="T:System.Json.JsonValue" /> to a <see cref="T:System.Double" /> object.</summary>
+      <returns>The <see cref="T:System.Double" /> initialized with the <see cref="T:System.Json.JsonValue" /> value specified.</returns>
+      <param name="value">The instance of <see cref="T:System.Json.JsonValue" /> used to initialize the <see cref="T:System.Double" /> object. </param>
+      <exception cref="T:System.InvalidCastException">The <see cref="P:System.Json.JsonValue.JsonType" /> of <paramref name="value" /> is not a <see cref="F:System.Json.JsonType.Number" /> and so cannot be cast to <see cref="T:System.Double" />.</exception>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.Json.JsonValue)~System.SByte">
+      <summary>Enables implicit casts from an instance of type <see cref="T:System.Json.JsonValue" /> to a <see cref="T:System.SByte" /> object.</summary>
+      <returns>The <see cref="T:System.SByte" /> initialized with the <see cref="T:System.Json.JsonValue" /> value specified.</returns>
+      <param name="value">The instance of <see cref="T:System.Json.JsonValue" /> used to initialize the <see cref="T:System.SByte" /> object.</param>
+      <exception cref="T:System.InvalidCastException">The <see cref="P:System.Json.JsonValue.JsonType" /> of <paramref name="value" /> is not a <see cref="F:System.Json.JsonType.Number" /> and so cannot be cast to <see cref="T:System.SByte" />.</exception>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.Json.JsonValue)~System.Byte">
+      <summary>Enables implicit casts from an instance of type <see cref="T:System.Json.JsonValue" /> to a <see cref="T:System.Byte" /> object.</summary>
+      <returns>The <see cref="T:System.Byte" /> initialized with the <see cref="T:System.Json.JsonValue" /> value specified.</returns>
+      <param name="value">The instance of <see cref="T:System.Json.JsonValue" /> used to initialize the <see cref="T:System.Byte" /> object.</param>
+      <exception cref="T:System.InvalidCastException">The <see cref="P:System.Json.JsonValue.JsonType" /> of <paramref name="value" /> is not a <see cref="F:System.Json.JsonType.Number" /> and so cannot be cast to <see cref="T:System.Byte" />.</exception>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.Json.JsonValue)~System.Uri">
+      <summary>Enables implicit casts from an instance of type <see cref="T:System.Json.JsonValue" /> to a <see cref="T:System.Uri" /> object.</summary>
+      <returns>The <see cref="T:System.Uri" /> initialized with the <see cref="T:System.Json.JsonValue" /> value specified, or null if <paramref name="value" /> is null.</returns>
+      <param name="value">The instance of <see cref="T:System.Json.JsonValue" /> used to initialize the <see cref="T:System.Uri" /> object.</param>
+      <exception cref="T:System.InvalidCastException">The <see cref="P:System.Json.JsonValue.JsonType" /> of <paramref name="value" /> is not a <see cref="F:System.Json.JsonType.String" /> and so cannot be cast to <see cref="T:System.Uri" />.</exception>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.Json.JsonValue)~System.UInt16">
+      <summary>Enables implicit casts from an instance of type <see cref="T:System.Json.JsonValue" /> to a <see cref="T:System.UInt16" /> object.</summary>
+      <returns>The <see cref="T:System.UInt16" /> initialized with the <see cref="T:System.Json.JsonValue" /> value specified.</returns>
+      <param name="value">The instance of <see cref="T:System.Json.JsonValue" /> used to initialize the <see cref="T:System.UInt16" /> object. </param>
+      <exception cref="T:System.InvalidCastException">The <see cref="P:System.Json.JsonValue.JsonType" /> of <paramref name="value" /> is not a <see cref="F:System.Json.JsonType.Number" /> and so cannot be cast to <see cref="T:System.UInt16" />.</exception>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.Json.JsonValue)~System.UInt32">
+      <summary>Enables implicit casts from an instance of type <see cref="T:System.Json.JsonValue" /> to a <see cref="T:System.UInt32" /> object.</summary>
+      <returns>The <see cref="T:System.UInt32" /> initialized with the <see cref="T:System.Json.JsonValue" /> value specified.</returns>
+      <param name="value">The instance of <see cref="T:System.Json.JsonValue" /> used to initialize the <see cref="T:System.UInt32" /> object. </param>
+      <exception cref="T:System.InvalidCastException">The <see cref="P:System.Json.JsonValue.JsonType" /> of <paramref name="value" /> is not a <see cref="F:System.Json.JsonType.Number" /> and so cannot be cast to <see cref="T:System.UInt32" />.</exception>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.Json.JsonValue)~System.Int16">
+      <summary>Enables implicit casts from an instance of type <see cref="T:System.Json.JsonValue" /> to a <see cref="T:System.Int16" /> object.</summary>
+      <returns>The <see cref="T:System.Int16" /> initialized with the <see cref="T:System.Json.JsonValue" /> value specified.</returns>
+      <param name="value">The instance of <see cref="T:System.Json.JsonValue" /> used to initialize the <see cref="T:System.Int16" /> object. </param>
+      <exception cref="T:System.InvalidCastException">The <see cref="P:System.Json.JsonValue.JsonType" /> of <paramref name="value" /> is not a <see cref="F:System.Json.JsonType.Number" /> and so cannot be cast to <see cref="T:System.Int16" />.</exception>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.Json.JsonValue)~System.Guid">
+      <summary>Enables implicit casts from an instance of type <see cref="T:System.Json.JsonValue" /> to a <see cref="T:System.Guid" /> object.</summary>
+      <returns>The <see cref="T:System.Guid" /> initialized with the <see cref="T:System.Json.JsonValue" /> value specified.</returns>
+      <param name="value">The instance of <see cref="T:System.Json.JsonValue" /> used to initialize the <see cref="T:System.Guid" /> object. </param>
+      <exception cref="T:System.InvalidCastException">The <see cref="P:System.Json.JsonValue.JsonType" /> of <paramref name="value" /> is not a <see cref="F:System.Json.JsonType.String" /> and so cannot be cast to <see cref="T:System.Guid" />.</exception>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.SByte)~System.Json.JsonValue">
+      <summary>Enables implicit casts from type <see cref="T:System.SByte" /> to a <see cref="T:System.JsonPrimitive" />.</summary>
+      <returns>The <see cref="T:System.Json.JsonValue" /> initialized with the <see cref="T:System.SByte" /> specified.</returns>
+      <param name="value">The <see cref="T:System.SByte" /> instance used to initialize the <see cref="T:System.JsonPrimitive" />.</param>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.Single)~System.Json.JsonValue">
+      <summary>Enables implicit casts from type <see cref="T:System.Single" /> to a <see cref="T:System.JsonPrimitive" />.</summary>
+      <returns>The <see cref="T:System.Json.JsonValue" /> initialized with the <see cref="T:System.Single" /> specified.</returns>
+      <param name="value">The <see cref="T:System.Single" /> instance used to initialize the <see cref="T:System.JsonPrimitive" />.</param>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.String)~System.Json.JsonValue">
+      <summary>Enables implicit casts from type <see cref="T:System.String" /> to a <see cref="T:System.JsonPrimitive" />.</summary>
+      <returns>The <see cref="T:System.Json.JsonValue" /> initialized with the <see cref="T:System.String" /> specified, or null if <paramref name="value" /> is null.</returns>
+      <param name="value">The <see cref="T:System.String" /> instance used to initialize the <see cref="T:System.JsonPrimitive" />.</param>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.TimeSpan)~System.Json.JsonValue">
+      <summary>Enables implicit casts from type <see cref="T:System.Timespan" /> to a <see cref="T:System.JsonPrimitive" />.</summary>
+      <returns>The <see cref="T:System.Json.JsonValue" /> initialized with the <see cref="T:System.Timespan" /> specified.</returns>
+      <param name="value">The <see cref="T:System.Timespan" /> instance used to initialize the <see cref="T:System.JsonPrimitive" />.</param>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.UInt16)~System.Json.JsonValue">
+      <summary>Enables implicit casts from type <see cref="T:System.UInt16" /> to a <see cref="T:System.JsonPrimitive" />.</summary>
+      <returns>The <see cref="T:System.Json.JsonValue" /> initialized with the <see cref="T:System.UInt16" /> specified.</returns>
+      <param name="value">The <see cref="T:System.UInt16" /> instance used to initialize the <see cref="T:System.JsonPrimitive" />.</param>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.UInt32)~System.Json.JsonValue">
+      <summary>Enables implicit casts from type <see cref="T:System.UInt32" /> to a <see cref="T:System.JsonPrimitive" />.</summary>
+      <returns>The <see cref="T:System.Json.JsonValue" /> initialized with the <see cref="T:System.UInt32" /> specified.</returns>
+      <param name="value">The <see cref="T:System.UInt32" /> instance used to initialize the <see cref="T:System.JsonPrimitive" />.</param>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.UInt64)~System.Json.JsonValue">
+      <summary>Enables implicit casts from type <see cref="T:System.UInt64" /> to a <see cref="T:System.JsonPrimitive" />.</summary>
+      <returns>The <see cref="T:System.Json.JsonValue" /> initialized with the <see cref="T:System.UInt64" /> specified.</returns>
+      <param name="value">The <see cref="T:System.UInt64" /> instance used to initialize the <see cref="T:System.JsonPrimitive" />.</param>
+    </member>
+    <member name="M:System.Json.JsonValue.op_Implicit(System.Uri)~System.Json.JsonValue">
+      <summary>Enables implicit casts from type <see cref="T:System.Uri" /> to a <see cref="T:System.JsonPrimitive" />.</summary>
+      <returns>The <see cref="T:System.Json.JsonValue" /> initialized with the <see cref="T:System.Uri" /> specified, or null if <paramref name="value" /> is null.</returns>
+      <param name="value">The <see cref="T:System.Uri" /> instance used to initialize the <see cref="T:System.JsonPrimitive" />.</param>
+    </member>
+    <member name="M:System.Json.JsonValue.Parse(System.String)">
+      <summary>Deserializes text-based JSON into a JSON CLR type.</summary>
+      <returns>The <see cref="T:System.Json.JsonValue" /> object that represents the parsed text-based JSON as a CLR type. </returns>
+      <param name="jsonString">The text-based JSON to be parsed into a JSON CLR type.</param>
+      <exception cref="T:System.ArgumentException">The length of <paramref name="jsonString" /> is zero.</exception>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="jsonString" /> is null.</exception>
+    </member>
+    <member name="M:System.Json.JsonValue.Save(System.IO.Stream)">
+      <summary>When implemented in a derived class, serializes the <see cref="T:System.Json.JsonValue" /> CLR type into text-based JSON using a stream.</summary>
+      <param name="stream">Stream to which to write text-based JSON.</param>
+    </member>
+    <member name="M:System.Json.JsonValue.Save(System.IO.TextWriter)">
+      <summary>Serializes the <see cref="T:System.Json.JsonValue" /> CLR type into text-based JSON using a text writer.</summary>
+      <param name="textWriter">The <see cref="T:System.IO.TextWriter" /> used to write text-based JSON.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="textWriter" /> is null.</exception>
+    </member>
+    <member name="M:System.Json.JsonValue.System#Collections#IEnumerable#GetEnumerator">
+      <summary>This method is not supported for this base class and throws an exception. </summary>
+      <returns>
+An <see cref="T:System.Collections.IEnumerator" />.
+</returns>
+    </member>
+    <member name="M:System.Json.JsonValue.ToString">
+      <summary>Saves (serializes) this JSON CLR type into text-based JSON.</summary>
+      <returns>
+Returns <see cref="T:System.String" />, which contains text-based JSON.</returns>
+    </member>
+  </members>
+</doc>
\ No newline at end of file
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/System.Runtime.Serialization.Json.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/System.Runtime.Serialization.Json.dll
new file mode 100644 (file)
index 0000000..cebb67e
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/System.Runtime.Serialization.Json.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/System.Runtime.Serialization.Json.xml b/trunk/packages/Hammock.1.2.3/lib/sl4/System.Runtime.Serialization.Json.xml
new file mode 100644 (file)
index 0000000..f57db9e
--- /dev/null
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<doc>
+  <assembly>
+    <name>System.Runtime.Serialization.Json</name>
+  </assembly>
+  <members>
+    <member name="T:System.Runtime.Serialization.Json.JsonReaderWriterFactory">
+      <summary>Produces instances of <see cref="T:System.Xml.XmlDictionaryReader" /> that can read data encoded with JavaScript Object Notation (JSON) from a stream or buffer and map it to an XML Infoset, and produces instances of <see cref="T:System.Xml.XmlDictionaryWriter" /> that can map an XML Infoset to JSON and write JSON-encoded data to a stream. </summary>
+    </member>
+    <member name="M:System.Runtime.Serialization.Json.JsonReaderWriterFactory.CreateJsonReader(System.Byte[],System.Int32,System.Int32,System.Xml.XmlDictionaryReaderQuotas)">
+      <summary>Creates an <see cref="T:System.Xml.XmlDictionaryReader" /> that can map a buffer encoded with JavaScript Object Notation (JSON), of a specified size and offset, to an XML Infoset.</summary>
+      <returns>An <see cref="T:System.Xml.XmlDictionaryReader" /> that can read JSON.</returns>
+      <param name="buffer">The input <see cref="T:System.Byte" /> buffer array from which to read.</param>
+      <param name="offset">Starting position from which to read in <paramref name="buffer" />.</param>
+      <param name="count">Number of bytes that can be read from <paramref name="buffer" />.</param>
+      <param name="quotas">The <see cref="T:System.Xml.XmlDictionaryReaderQuotas" /> must be set to <see cref="P:System.Xml.XmlDictionaryReaderQuotas.Max" /> in Silverlight version 4 Release Candidate applications.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="stream" /> is null.</exception>
+      <exception cref="T:System.ArgumentOutOfRangeException">
+        <paramref name="offset" /> is negative or exceeds the <paramref name="buffer" /> length.</exception>
+      <exception cref="T:System.ArgumentOutOfRangeException">
+        <paramref name="count" /> is negative or exceeds the <paramref name="buffer" /> length minus the <paramref name="offset" />.</exception>
+    </member>
+    <member name="M:System.Runtime.Serialization.Json.JsonReaderWriterFactory.CreateJsonReader(System.Byte[],System.Xml.XmlDictionaryReaderQuotas)">
+      <summary>Creates an <see cref="T:System.Xml.XmlDictionaryReader" /> that can map a specified buffer encoded with JavaScript Object Notation (JSON) to an XML Infoset.</summary>
+      <returns>An <see cref="T:System.Xml.XmlDictionaryReader" /> that can process JavaScript Object Notation (JSON) data from the buffer specified.</returns>
+      <param name="buffer">The input <see cref="T:System.Byte" /> buffer array from which to read.</param>
+      <param name="quotas">The <see cref="T:System.Xml.XmlDictionaryReaderQuotas" /> must be set to <see cref="P:System.Xml.XmlDictionaryReaderQuotas.Max" /> in Silverlight version 4 Release Candidate applications used to prevent Denial of Service (DoS) attacks when reading untrusted data. </param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="buffer" /> is null.</exception>
+    </member>
+    <member name="M:System.Runtime.Serialization.Json.JsonReaderWriterFactory.CreateJsonReader(System.IO.Stream,System.Xml.XmlDictionaryReaderQuotas)">
+      <summary>Creates an <see cref="T:System.Xml.XmlDictionaryReader" /> that can map a specified stream encoded with JavaScript Object Notation (JSON) to an XML Infoset.</summary>
+      <returns>An <see cref="T:System.Xml.XmlDictionaryReader" /> that can read JSON.</returns>
+      <param name="stream">The input <see cref="T:System.IO.Stream" /> from which to read.</param>
+      <param name="quotas">The <see cref="T:System.Xml.XmlDictionaryReaderQuotas" /> must be set to <see cref="P:System.Xml.XmlDictionaryReaderQuotas.Max" /> in Silverlight version 4 Release Candidate applications. </param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="stream" /> is null.</exception>
+    </member>
+    <member name="M:System.Runtime.Serialization.Json.JsonReaderWriterFactory.CreateJsonWriter(System.IO.Stream)">
+      <summary>Creates an <see cref="T:System.Xml.XmlDictionaryWriter" /> that writes data encoded with JSON to a stream using a UTF-8 character encoding.</summary>
+      <returns>An <see cref="T:System.Xml.XmlDictionaryWriter" /> that writes data encoded with JSON to the stream from an XML Infoset.</returns>
+      <param name="stream">The output <see cref="T:System.IO.Stream" /> for the JSON writer.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="stream" /> is null.</exception>
+    </member>
+    <member name="M:System.Runtime.Serialization.Json.JsonReaderWriterFactory.CreateJsonWriter(System.IO.Stream,System.Text.Encoding)">
+      <summary>Creates an <see cref="T:System.Xml.XmlDictionaryWriter" /> that writes data encoded with JSON to a stream with a specified character encoding.</summary>
+      <returns>An <see cref="T:System.Xml.XmlDictionaryWriter" /> that writes data encoded with JSON to the stream from an XML Infoset.</returns>
+      <param name="stream">The output <see cref="T:System.IO.Stream" /> for the JSON writer.</param>
+      <param name="encoding">The <see cref="T:System.Text.Encoding" /> that specifies the character encoding used by the writer. The default encoding is UTF-8.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="stream" /> or <paramref name="encoding" /> is null.</exception>
+    </member>
+    <member name="M:System.Runtime.Serialization.Json.JsonReaderWriterFactory.CreateJsonWriter(System.IO.Stream,System.Text.Encoding,System.Boolean)">
+      <summary>Creates an <see cref="T:System.Xml.XmlDictionaryWriter" /> that writes data encoded with JSON to a stream with a specified character encoding and that specifies whether the output stream is closed by the writer when it is done.</summary>
+      <returns>An <see cref="T:System.Xml.XmlDictionaryWriter" /> that writes data encoded with JSON to the stream from an XML Infoset.</returns>
+      <param name="stream">The output <see cref="T:System.IO.Stream" /> for the JSON writer.</param>
+      <param name="encoding">The <see cref="T:System.Text.Encoding" /> that specifies the character encoding used by the writer. The default encoding is UTF-8.</param>
+      <param name="ownsStream">If true, the output stream is closed by the writer when done; otherwise, false. The default value is true.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="stream" /> or <paramref name="encoding" /> is null.</exception>
+    </member>
+  </members>
+</doc>
\ No newline at end of file
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/System.Xml.Linq.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/System.Xml.Linq.dll
new file mode 100644 (file)
index 0000000..a31bfef
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/System.Xml.Linq.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/System.Xml.Linq.xml b/trunk/packages/Hammock.1.2.3/lib/sl4/System.Xml.Linq.xml
new file mode 100644 (file)
index 0000000..873e381
--- /dev/null
@@ -0,0 +1,1655 @@
+<?xml version="1.0" encoding="utf-8"?>
+<doc>
+  <assembly>
+    <name>System.Xml.Linq</name>
+  </assembly>
+  <members>
+    <member name="T:System.Xml.Linq.Extensions">
+      <summary>Contains the LINQ to XML extension methods.</summary>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.Ancestors``1(System.Collections.Generic.IEnumerable{``0})">
+      <summary>Returns a collection of elements that contains the ancestors of every node in the source collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains the ancestors of every node in the source collection.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XNode" /> that contains the source collection.</param>
+      <typeparam name="T">The type of the objects in <paramref name="source" />, constrained to <see cref="T:System.Xml.Linq.XNode" />.</typeparam>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.Ancestors``1(System.Collections.Generic.IEnumerable{``0},System.Xml.Linq.XName)">
+      <summary>Returns a filtered collection of elements that contains the ancestors of every node in the source collection. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains the ancestors of every node in the source collection. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XNode" /> that contains the source collection.</param>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> to match.</param>
+      <typeparam name="T">The type of the objects in <paramref name="source" />, constrained to <see cref="T:System.Xml.Linq.XNode" />.</typeparam>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.AncestorsAndSelf(System.Collections.Generic.IEnumerable{System.Xml.Linq.XElement})">
+      <summary>Returns a collection of elements that contains every element in the source collection, and the ancestors of every element in the source collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains every element in the source collection, and the ancestors of every element in the source collection.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains the source collection.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.AncestorsAndSelf(System.Collections.Generic.IEnumerable{System.Xml.Linq.XElement},System.Xml.Linq.XName)">
+      <summary>Returns a filtered collection of elements that contains every element in the source collection, and the ancestors of every element in the source collection. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains every element in the source collection, and the ancestors of every element in the source collection. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains the source collection.</param>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> to match.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.Attributes(System.Collections.Generic.IEnumerable{System.Xml.Linq.XElement})">
+      <summary>Returns a collection of the attributes of every element in the source collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XAttribute" /> that contains the attributes of every element in the source collection.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains the source collection.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.Attributes(System.Collections.Generic.IEnumerable{System.Xml.Linq.XElement},System.Xml.Linq.XName)">
+      <summary>Returns a filtered collection of the attributes of every element in the source collection. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XAttribute" /> that contains a filtered collection of the attributes of every element in the source collection. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains the source collection.</param>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> to match.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.DescendantNodes``1(System.Collections.Generic.IEnumerable{``0})">
+      <summary>Returns a collection of the descendant nodes of every document and element in the source collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XNode" /> of the descendant nodes of every document and element in the source collection.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XContainer" /> that contains the source collection.</param>
+      <typeparam name="T">The type of the objects in <paramref name="source" />, constrained to <see cref="T:System.Xml.Linq.XContainer" />.</typeparam>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.DescendantNodesAndSelf(System.Collections.Generic.IEnumerable{System.Xml.Linq.XElement})">
+      <summary>Returns a collection of nodes that contains every element in the source collection, and the descendant nodes of every element in the source collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XNode" /> that contains every element in the source collection, and the descendant nodes of every element in the source collection.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains the source collection.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.Descendants``1(System.Collections.Generic.IEnumerable{``0})">
+      <summary>Returns a collection of elements that contains the descendant elements of every element and document in the source collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains the descendant elements of every element and document in the source collection.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XContainer" /> that contains the source collection.</param>
+      <typeparam name="T">The type of the objects in <paramref name="source" />, constrained to <see cref="T:System.Xml.Linq.XContainer" />.</typeparam>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.Descendants``1(System.Collections.Generic.IEnumerable{``0},System.Xml.Linq.XName)">
+      <summary>Returns a filtered collection of elements that contains the descendant elements of every element and document in the source collection. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains the descendant elements of every element and document in the source collection. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XContainer" /> that contains the source collection.</param>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> to match.</param>
+      <typeparam name="T">The type of the objects in <paramref name="source" />, constrained to <see cref="T:System.Xml.Linq.XContainer" />.</typeparam>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.DescendantsAndSelf(System.Collections.Generic.IEnumerable{System.Xml.Linq.XElement})">
+      <summary>Returns a collection of elements that contains every element in the source collection, and the descendent elements of every element in the source collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains every element in the source collection, and the descendent elements of every element in the source collection.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains the source collection.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.DescendantsAndSelf(System.Collections.Generic.IEnumerable{System.Xml.Linq.XElement},System.Xml.Linq.XName)">
+      <summary>Returns a filtered collection of elements that contains every element in the source collection, and the descendents of every element in the source collection. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains every element in the source collection, and the descendents of every element in the source collection. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains the source collection.</param>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> to match.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.Elements``1(System.Collections.Generic.IEnumerable{``0})">
+      <summary>Returns a collection of the child elements of every element and document in the source collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> of the child elements of every element or document in the source collection.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains the source collection.</param>
+      <typeparam name="T">The type of the objects in <paramref name="source" />, constrained to <see cref="T:System.Xml.Linq.XContainer" />.</typeparam>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.Elements``1(System.Collections.Generic.IEnumerable{``0},System.Xml.Linq.XName)">
+      <summary>Returns a filtered collection of the child elements of every element and document in the source collection. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> of the child elements of every element and document in the source collection. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains the source collection.</param>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> to match.</param>
+      <typeparam name="T">The type of the objects in <paramref name="source" />, constrained to <see cref="T:System.Xml.Linq.XContainer" />.</typeparam>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.InDocumentOrder``1(System.Collections.Generic.IEnumerable{``0})">
+      <summary>Returns a collection of nodes that contains all nodes in the source collection, sorted in document order.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XNode" /> that contains all nodes in the source collection, sorted in document order.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XNode" /> that contains the source collection.</param>
+      <typeparam name="T">The type of the objects in <paramref name="source" />, constrained to <see cref="T:System.Xml.Linq.XNode" />.</typeparam>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.Nodes``1(System.Collections.Generic.IEnumerable{``0})">
+      <summary>Returns a collection of the child nodes of every document and element in the source collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XNode" /> of the child nodes of every document and element in the source collection.</returns>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XNode" /> that contains the source collection.</param>
+      <typeparam name="T">The type of the objects in <paramref name="source" />, constrained to <see cref="T:System.Xml.Linq.XContainer" />.</typeparam>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.Remove(System.Collections.Generic.IEnumerable{System.Xml.Linq.XAttribute})">
+      <summary>Removes every attribute in the source collection from its parent element.</summary>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XAttribute" /> that contains the source collection.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.Extensions.Remove``1(System.Collections.Generic.IEnumerable{``0})">
+      <summary>Removes every node in the source collection from its parent node.</summary>
+      <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XNode" /> that contains the source collection.</param>
+      <typeparam name="T">The type of the objects in <paramref name="source" />, constrained to <see cref="T:System.Xml.Linq.XNode" />.</typeparam>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="source" /> is null.</exception>
+    </member>
+    <member name="T:System.Xml.Linq.LoadOptions">
+      <summary>Specifies load options when parsing XML.  </summary>
+    </member>
+    <member name="F:System.Xml.Linq.LoadOptions.None">
+      <summary>Does not preserve insignificant white space or load base URI and line information.</summary>
+    </member>
+    <member name="F:System.Xml.Linq.LoadOptions.PreserveWhitespace">
+      <summary>Preserves insignificant white space while parsing.</summary>
+    </member>
+    <member name="F:System.Xml.Linq.LoadOptions.SetBaseUri">
+      <summary>Requests the base URI information from the <see cref="T:System.Xml.XmlReader" />, and makes it available via the <see cref="P:System.Xml.Linq.XObject.BaseUri" /> property.</summary>
+    </member>
+    <member name="F:System.Xml.Linq.LoadOptions.SetLineInfo">
+      <summary>Requests the line information from the <see cref="T:System.Xml.XmlReader" /> and makes it available via properties on <see cref="T:System.Xml.Linq.XObject" />.</summary>
+    </member>
+    <member name="T:System.Xml.Linq.ReaderOptions">
+      <summary>Specifies whether to omit duplicate namespaces when loading an <see cref="T:System.Xml.Linq.XDocument" /> with an <see cref="T:System.Xml.XmlReader" />.</summary>
+    </member>
+    <member name="F:System.Xml.Linq.ReaderOptions.None">
+      <summary>No reader options specified.</summary>
+    </member>
+    <member name="F:System.Xml.Linq.ReaderOptions.OmitDuplicateNamespaces">
+      <summary>Omit duplicate namespaces when loading the <see cref="T:System.Xml.Linq.XDocument" />.</summary>
+    </member>
+    <member name="T:System.Xml.Linq.SaveOptions">
+      <summary>Specifies serialization options. </summary>
+    </member>
+    <member name="F:System.Xml.Linq.SaveOptions.None">
+      <summary>Formats (indent) the XML while serializing.</summary>
+    </member>
+    <member name="F:System.Xml.Linq.SaveOptions.DisableFormatting">
+      <summary>Preserves all insignificant white space while serializing.</summary>
+    </member>
+    <member name="F:System.Xml.Linq.SaveOptions.OmitDuplicateNamespaces">
+      <summary>Removes duplicate namespace declarations. For the duplicate namespace declarations to be removed, both the prefix and the namespace have to match.</summary>
+    </member>
+    <member name="T:System.Xml.Linq.XAttribute">
+      <summary>Represents an XML attribute.</summary>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.#ctor(System.Xml.Linq.XAttribute)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XAttribute" /> class from another <see cref="T:System.Xml.Linq.XAttribute" /> object. </summary>
+      <param name="other">An <see cref="T:System.Xml.Linq.XAttribute" /> object to copy from.</param>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="other" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.#ctor(System.Xml.Linq.XName,System.Object)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XAttribute" /> class from the specified name and value. </summary>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> of the attribute.</param>
+      <param name="value">An <see cref="T:System.Object" /> containing the value of the attribute.</param>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="name" /> or <paramref name="value" /> parameter is null.</exception>
+    </member>
+    <member name="P:System.Xml.Linq.XAttribute.EmptySequence">
+      <summary>Gets an empty collection of attributes.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XAttribute" /> containing an empty collection.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XAttribute.IsNamespaceDeclaration">
+      <summary>Determines if this attribute is a namespace declaration.</summary>
+      <returns>true if this attribute is a namespace declaration; otherwise false.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XAttribute.Name">
+      <summary>Gets the expanded name of this attribute.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XName" /> containing the name of this attribute.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XAttribute.NextAttribute">
+      <summary>Gets the next attribute of the parent element.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XAttribute" /> containing the next attribute of the parent element.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XAttribute.NodeType">
+      <summary>Gets the node type for this node.</summary>
+      <returns>The node type. For <see cref="T:System.Xml.Linq.XAttribute" /> objects, this value is <see cref="F:System.Xml.XmlNodeType.Attribute" />.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.DateTime">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.DateTime" />.</summary>
+      <returns>A <see cref="T:System.DateTime" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.DateTime" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.DateTime" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="attribute" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Nullable{System.DateTime}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.DateTime" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.DateTime" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.DateTime" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.DateTime" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Nullable{System.Decimal}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Decimal" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.Decimal" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.Nullable`1" /> of <see cref="T:System.Decimal" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.Decimal" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Nullable{System.Double}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Double" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.Double" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.Nullable`1" /> of <see cref="T:System.Double" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.Double" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Decimal">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Decimal" />.</summary>
+      <returns>A <see cref="T:System.Decimal" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.Decimal" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.Decimal" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="attribute" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.DateTimeOffset">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.DateTimeOffset" />.</summary>
+      <returns>A <see cref="T:System.DateTimeOffset" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.DateTimeOffset" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.DateTimeOffset" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="attribute" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Guid">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Guid" />.</summary>
+      <returns>A <see cref="T:System.Guid" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.Guid" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.Guid" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="attribute" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Nullable{System.Guid}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Guid" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.Guid" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Guid" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.Guid" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Nullable{System.TimeSpan}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.TimeSpan" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.TimeSpan" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.TimeSpan" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.TimeSpan" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Nullable{System.DateTimeOffset}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.DateTimeOffset" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.DateTimeOffset" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.DateTimeOffset" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.DateTimeOffset" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.TimeSpan">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.TimeSpan" />.</summary>
+      <returns>A <see cref="T:System.TimeSpan" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.TimeSpan" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.TimeSpan" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="attribute" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Double">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Double" />.</summary>
+      <returns>A <see cref="T:System.Double" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.Double" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.Double" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="attribute" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Int32">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to an <see cref="T:System.Int32" />.</summary>
+      <returns>A <see cref="T:System.Int32" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.Int32" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.Int32" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="attribute" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Nullable{System.Int32}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Int32" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.Int32" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Int32" />.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.UInt32">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.UInt32" />.</summary>
+      <returns>A <see cref="T:System.UInt32" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.UInt32" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.UInt32" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="attribute" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.String">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.String" />.</summary>
+      <returns>A <see cref="T:System.String" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.String" />.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Boolean">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Boolean" />.</summary>
+      <returns>A <see cref="T:System.Boolean" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.Boolean" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.Boolean" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="attribute" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Nullable{System.Boolean}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Boolean" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.Boolean" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.Nullable`1" /> of <see cref="T:System.Boolean" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.Boolean" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Nullable{System.UInt32}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.UInt32" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.UInt32" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.UInt32" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.UInt32" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Nullable{System.UInt64}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.UInt64" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.UInt64" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.UInt64" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.UInt64" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Single">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Single" />.</summary>
+      <returns>A <see cref="T:System.Single" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.Single" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.Single" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="attribute" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Nullable{System.Single}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Single" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.Single" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.Nullable`1" /> of <see cref="T:System.Single" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.Single" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Int64">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to an <see cref="T:System.Int64" />.</summary>
+      <returns>A <see cref="T:System.Int64" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.Int64" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.Int64" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="attribute" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.Nullable{System.Int64}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Int64" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.Int64" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Int64" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.Int64" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.op_Explicit(System.Xml.Linq.XAttribute)~System.UInt64">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.UInt64" />.</summary>
+      <returns>A <see cref="T:System.UInt64" /> that contains the content of this <see cref="T:System.Xml.Linq.XAttribute" />.</returns>
+      <param name="attribute">The <see cref="T:System.Xml.Linq.XAttribute" /> to cast to <see cref="T:System.UInt64" />.</param>
+      <exception cref="T:System.FormatException">The attribute does not contain a valid <see cref="T:System.UInt64" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="attribute" /> parameter is null.</exception>
+    </member>
+    <member name="P:System.Xml.Linq.XAttribute.PreviousAttribute">
+      <summary>Gets the previous attribute of the parent element.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XAttribute" /> containing the previous attribute of the parent element.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.Remove">
+      <summary>Removes this attribute from its parent element.</summary>
+      <exception cref="T:System.InvalidOperationException">The parent element is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.SetValue(System.Object)">
+      <summary>Sets the value of this attribute.</summary>
+      <param name="value">The value to assign to this attribute.</param>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="value" /> parameter is null.</exception>
+      <exception cref="T:System.ArgumentException">The <paramref name="value" /> is an <see cref="T:System.Xml.Linq.XObject" />.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XAttribute.ToString">
+      <summary>Converts the current <see cref="T:System.Xml.Linq.XAttribute" /> object to a string representation.</summary>
+      <returns>A <see cref="T:System.String" /> containing the XML text representation of an attribute and its value.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XAttribute.Value">
+      <summary>Gets or sets the value of this attribute.</summary>
+      <returns>A <see cref="T:System.String" /> containing the value of this attribute.</returns>
+      <exception cref="T:System.ArgumentNullException">When setting, the <paramref name="value" /> is null.</exception>
+    </member>
+    <member name="T:System.Xml.Linq.XCData">
+      <summary>Represents a text node that contains CDATA.  </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XCData.#ctor(System.String)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XCData" /> class. </summary>
+      <param name="value">A string that contains the value of the <see cref="T:System.Xml.Linq.XCData" /> node.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XCData.#ctor(System.Xml.Linq.XCData)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XCData" /> class. </summary>
+      <param name="other">The <see cref="T:System.Xml.Linq.XCData" /> node to copy from.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XCData.NodeType">
+      <summary>Gets the node type for this node.</summary>
+      <returns>The node type. For <see cref="T:System.Xml.Linq.XCData" /> objects, this value is <see cref="F:System.Xml.XmlNodeType.CDATA" />.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XCData.WriteTo(System.Xml.XmlWriter)">
+      <summary>Writes this CDATA object to an <see cref="T:System.Xml.XmlWriter" />.</summary>
+      <param name="writer">An <see cref="T:System.Xml.XmlWriter" /> into which this method will write.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="writer" /> is null.</exception>
+    </member>
+    <member name="T:System.Xml.Linq.XComment">
+      <summary>Represents an XML comment. </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XComment.#ctor(System.String)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XComment" /> class with the specified string content. </summary>
+      <param name="value">A string that contains the contents of the new <see cref="T:System.Xml.Linq.XComment" /> object.</param>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="value" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XComment.#ctor(System.Xml.Linq.XComment)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XComment" /> class from an existing comment node. </summary>
+      <param name="other">The <see cref="T:System.Xml.Linq.XComment" /> node to copy from.</param>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="other" /> parameter is null.</exception>
+    </member>
+    <member name="P:System.Xml.Linq.XComment.NodeType">
+      <summary>Gets the node type for this node.</summary>
+      <returns>The node type. For <see cref="T:System.Xml.Linq.XComment" /> objects, this value is <see cref="F:System.Xml.XmlNodeType.Comment" />.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XComment.Value">
+      <summary>Gets or sets the string value of this comment.</summary>
+      <returns>A <see cref="T:System.String" /> that contains the string value of this comment.</returns>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="value" /> is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XComment.WriteTo(System.Xml.XmlWriter)">
+      <summary>Write this comment to an <see cref="T:System.Xml.XmlWriter" />.</summary>
+      <param name="writer">An <see cref="T:System.Xml.XmlWriter" /> into which this method will write.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="writer" /> is null.</exception>
+    </member>
+    <member name="T:System.Xml.Linq.XContainer">
+      <summary>Represents a node that can contain other nodes.</summary>
+    </member>
+    <member name="M:System.Xml.Linq.XContainer.Add(System.Object)">
+      <summary>Adds the specified content as children of this <see cref="T:System.Xml.Linq.XContainer" />.</summary>
+      <param name="content">A content object containing simple content or a collection of content objects to be added.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XContainer.Add(System.Object[])">
+      <summary>Adds the specified content as children of this <see cref="T:System.Xml.Linq.XContainer" />.</summary>
+      <param name="content">A parameter list of content objects.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XContainer.AddFirst(System.Object)">
+      <summary>Adds the specified content as the first children of this document or element.</summary>
+      <param name="content">A content object containing simple content or a collection of content objects to be added.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XContainer.AddFirst(System.Object[])">
+      <summary>Adds the specified content as the first children of this document or element.</summary>
+      <param name="content">A parameter list of content objects.</param>
+      <exception cref="T:System.InvalidOperationException">The parent is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XContainer.CreateWriter">
+      <summary>Creates an <see cref="T:System.Xml.XmlWriter" /> that can be used to add nodes to the <see cref="T:System.Xml.Linq.XContainer" />.</summary>
+      <returns>An <see cref="T:System.Xml.XmlWriter" /> that is ready to have content written to it.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XContainer.DescendantNodes">
+      <summary>Returns a collection of the descendant nodes for this document or element, in document order.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XNode" /> containing the descendant nodes of the <see cref="T:System.Xml.Linq.XContainer" />, in document order.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XContainer.Descendants">
+      <summary>Returns a collection of the descendant elements for this document or element, in document order.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> containing the descendant elements of the <see cref="T:System.Xml.Linq.XContainer" />.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XContainer.Descendants(System.Xml.Linq.XName)">
+      <summary>Returns a filtered collection of the descendant elements for this document or element, in document order. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> containing the descendant elements of the <see cref="T:System.Xml.Linq.XContainer" /> that match the specified <see cref="T:System.Xml.Linq.XName" />.</returns>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> to match.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XContainer.Element(System.Xml.Linq.XName)">
+      <summary>Gets the first (in document order) child element with the specified <see cref="T:System.Xml.Linq.XName" />.</summary>
+      <returns>A <see cref="T:System.Xml.Linq.XElement" /> that matches the specified <see cref="T:System.Xml.Linq.XName" />, or null.</returns>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> to match.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XContainer.Elements">
+      <summary>Returns a collection of the child elements of this element or document, in document order.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> containing the child elements of this <see cref="T:System.Xml.Linq.XContainer" />, in document order.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XContainer.Elements(System.Xml.Linq.XName)">
+      <summary>Returns a filtered collection of the child elements of this element or document, in document order. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> containing the children of the <see cref="T:System.Xml.Linq.XContainer" /> that have a matching <see cref="T:System.Xml.Linq.XName" />, in document order.</returns>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> to match.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XContainer.FirstNode">
+      <summary>Get the first child node of this node.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XNode" /> containing the first child node of the <see cref="T:System.Xml.Linq.XContainer" />.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XContainer.LastNode">
+      <summary>Get the last child node of this node.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XNode" /> containing the last child node of the <see cref="T:System.Xml.Linq.XContainer" />.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XContainer.Nodes">
+      <summary>Returns a collection of the child nodes of this element or document, in document order.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XNode" /> containing the contents of this <see cref="T:System.Xml.Linq.XContainer" />, in document order.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XContainer.RemoveNodes">
+      <summary>Removes the child nodes from this document or element.</summary>
+    </member>
+    <member name="M:System.Xml.Linq.XContainer.ReplaceNodes(System.Object)">
+      <summary>Replaces the children nodes of this document or element with the specified content.</summary>
+      <param name="content">A content object containing simple content or a collection of content objects that replace the children nodes.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XContainer.ReplaceNodes(System.Object[])">
+      <summary>Replaces the children nodes of this document or element with the specified content.</summary>
+      <param name="content">A parameter list of content objects.</param>
+    </member>
+    <member name="T:System.Xml.Linq.XDeclaration">
+      <summary>Represents an XML declaration. </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XDeclaration.#ctor(System.String,System.String,System.String)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XDeclaration" /> class with the specified version, encoding, and standalone status.</summary>
+      <param name="version">The version of the XML, usually "1.0".</param>
+      <param name="encoding">The encoding for the XML document.</param>
+      <param name="standalone">A string containing "yes" or "no" that specifies whether the XML is standalone or requires external entities to be resolved.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDeclaration.#ctor(System.Xml.Linq.XDeclaration)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XDeclaration" /> class from another <see cref="T:System.Xml.Linq.XDeclaration" /> object. </summary>
+      <param name="other">The <see cref="T:System.Xml.Linq.XDeclaration" /> used to initialize this <see cref="T:System.Xml.Linq.XDeclaration" /> object.</param>
+      <exception cref="T:System.ArgumentNullException">
+        <paramref name="other" /> is null.</exception>
+    </member>
+    <member name="P:System.Xml.Linq.XDeclaration.Encoding">
+      <summary>Gets or sets the encoding for this document.</summary>
+      <returns>A <see cref="T:System.String" /> containing the code page name for this document.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XDeclaration.Standalone">
+      <summary>Gets or sets the standalone property for this document.</summary>
+      <returns>A <see cref="T:System.String" /> containing the standalone property for this document.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XDeclaration.ToString">
+      <summary>Provides the declaration as a formatted string.</summary>
+      <returns>A <see cref="T:System.String" /> that contains the formatted XML string.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XDeclaration.Version">
+      <summary>Gets or sets the version property for this document.</summary>
+      <returns>A <see cref="T:System.String" /> containing the version property for this document.</returns>
+    </member>
+    <member name="T:System.Xml.Linq.XDocument">
+      <summary>Represents an XML document. </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.#ctor">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XDocument" /> class. </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.#ctor(System.Object[])">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XDocument" /> class with the specified content.</summary>
+      <param name="content">A parameter list of content objects to add to this document.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.#ctor(System.Xml.Linq.XDeclaration,System.Object[])">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XDocument" /> class with the specified <see cref="T:System.Xml.Linq.XDeclaration" /> and content.</summary>
+      <param name="declaration">An <see cref="T:System.Xml.Linq.XDeclaration" /> for the document.</param>
+      <param name="content">The content of the document.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.#ctor(System.Xml.Linq.XDocument)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XDocument" /> class from an existing <see cref="T:System.Xml.Linq.XDocument" /> object.</summary>
+      <param name="other">The <see cref="T:System.Xml.Linq.XDocument" /> object that will be copied.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XDocument.Declaration">
+      <summary>Gets or sets the XML declaration for this document.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XDeclaration" /> that contains the XML declaration for this document.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XDocument.DocumentType">
+      <summary>Gets the Document Type Definition (DTD) for this document.</summary>
+      <returns>A <see cref="T:System.Xml.Linq.XDocumentType" /> that contains the DTD for this document.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.Load(System.IO.Stream)">
+      <summary>Creates a new <see cref="T:System.Xml.Linq.XDocument" /> instance using the specified stream.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XDocument" /> object used to read the data contained in the stream. </returns>
+      <param name="stream">The stream containing the XML data.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.Load(System.IO.Stream,System.Xml.Linq.LoadOptions)">
+      <summary>Creates a new <see cref="T:System.Xml.Linq.XDocument" /> instance using the specified stream, optionally preserving white space, setting the base URI, and retaining line information.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XDocument" /> object used to read the data contained in the stream.</returns>
+      <param name="stream">The stream containing the XML data.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.LoadOptions" /> that specifies whether to load base URI and line information.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.Load(System.IO.TextReader)">
+      <summary>Creates a new <see cref="T:System.Xml.Linq.XDocument" /> from a <see cref="T:System.IO.TextReader" />. </summary>
+      <returns>An <see cref="T:System.Xml.Linq.XDocument" /> that contains the contents of the specified <see cref="T:System.IO.TextReader" />.</returns>
+      <param name="textReader">A <see cref="T:System.IO.TextReader" /> that contains the content for the <see cref="T:System.Xml.Linq.XDocument" />.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.Load(System.IO.TextReader,System.Xml.Linq.LoadOptions)">
+      <summary>Creates a new <see cref="T:System.Xml.Linq.XDocument" /> from a <see cref="T:System.IO.TextReader" />, optionally preserving white space, setting the base URI, and retaining line information.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XDocument" /> that contains the XML that was read from the specified <see cref="T:System.IO.TextReader" />.</returns>
+      <param name="textReader">A <see cref="T:System.IO.TextReader" /> that contains the content for the <see cref="T:System.Xml.Linq.XDocument" />.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.LoadOptions" /> that specifies white space behavior, and whether to load base URI and line information.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.Load(System.String)">
+      <summary>Creates a new <see cref="T:System.Xml.Linq.XDocument" /> from a file located in the application's XAP package.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XDocument" /> that contains the contents of the specified file.</returns>
+      <param name="uri">A URI string that references the file to be loaded into a new <see cref="T:System.Xml.Linq.XDocument" />. This file is located in the application's XAP package. If you want to download a file from some other location, follow the steps described in How to: Load an XML File from an Arbitrary URI Location with LINQ to XML.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.Load(System.String,System.Xml.Linq.LoadOptions)">
+      <summary>Creates a new <see cref="T:System.Xml.Linq.XDocument" /> from a file located in the application's XAP package, optionally preserving white space, setting the base URI, and retaining line information.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XDocument" /> that contains the contents of the specified file.</returns>
+      <param name="uri">A URI string that references the file to be loaded into a new <see cref="T:System.Xml.Linq.XDocument" />. This file is located in the application's XAP package. If you want to download a file from some other location, follow the steps described in How to: Load an XML File from an Arbitrary URI Location with LINQ to XML.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.LoadOptions" /> that specifies how white space is handled and whether to load base URI and line information.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.Load(System.Xml.XmlReader)">
+      <summary>Creates a new <see cref="T:System.Xml.Linq.XDocument" /> from an <see cref="T:System.Xml.XmlReader" />. </summary>
+      <returns>An <see cref="T:System.Xml.Linq.XDocument" /> that contains the contents of the specified <see cref="T:System.Xml.XmlReader" />.</returns>
+      <param name="reader">A <see cref="T:System.Xml.XmlReader" /> that contains the content for the <see cref="T:System.Xml.Linq.XDocument" />.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.Load(System.Xml.XmlReader,System.Xml.Linq.LoadOptions)">
+      <summary>Creates a new <see cref="T:System.Xml.Linq.XDocument" /> from an <see cref="T:System.Xml.XmlReader" />, optionally setting the base URI, and retaining line information.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XDocument" /> that contains the XML that was read from the specified <see cref="T:System.Xml.XmlReader" />.</returns>
+      <param name="reader">A <see cref="T:System.Xml.XmlReader" /> that will be read for the content of the <see cref="T:System.Xml.Linq.XDocument" />.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.LoadOptions" /> that specifies whether to load base URI and line information.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XDocument.NodeType">
+      <summary>Gets the node type for this node.</summary>
+      <returns>The node type. For <see cref="T:System.Xml.Linq.XDocument" /> objects, this value is <see cref="F:System.Xml.XmlNodeType.Document" />.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.Parse(System.String)">
+      <summary>Creates a new <see cref="T:System.Xml.Linq.XDocument" /> from a string.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XDocument" /> populated from the string that contains XML.</returns>
+      <param name="text">A string that contains XML.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.Parse(System.String,System.Xml.Linq.LoadOptions)">
+      <summary>Creates a new <see cref="T:System.Xml.Linq.XDocument" /> from a string, optionally preserving white space, setting the base URI, and retaining line information.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XDocument" /> populated from the string that contains XML.</returns>
+      <param name="text">A string that contains XML.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.LoadOptions" /> that specifies white space behavior, and whether to load base URI and line information.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XDocument.Root">
+      <summary>Gets the root element of the XML Tree for this document.</summary>
+      <returns>The root <see cref="T:System.Xml.Linq.XElement" /> of the XML tree.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.Save(System.IO.Stream)">
+      <summary>Outputs this <see cref="T:System.Xml.Linq.XDocument" /> to the specified <see cref="T:System.IO.Stream" />.</summary>
+      <param name="stream">The stream to output this <see cref="T:System.Xml.Linq.XDocument" /> to.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.Save(System.IO.Stream,System.Xml.Linq.SaveOptions)">
+      <summary>Outputs this <see cref="T:System.Xml.Linq.XDocument" /> to the specified <see cref="T:System.IO.Stream" />, optionally specifying formatting behavior.</summary>
+      <param name="stream">The stream to output this <see cref="T:System.Xml.Linq.XDocument" /> to.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.SaveOptions" /> that specifies formatting behavior.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.Save(System.IO.TextWriter)">
+      <summary>Serialize this <see cref="T:System.Xml.Linq.XDocument" /> to a <see cref="T:System.IO.TextWriter" />.</summary>
+      <param name="textWriter">A <see cref="T:System.IO.TextWriter" /> that the <see cref="T:System.Xml.Linq.XDocument" /> will be written to.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.Save(System.IO.TextWriter,System.Xml.Linq.SaveOptions)">
+      <summary>Serialize this <see cref="T:System.Xml.Linq.XDocument" /> to a <see cref="T:System.IO.TextWriter" />, optionally disabling formatting.</summary>
+      <param name="textWriter">The <see cref="T:System.IO.TextWriter" /> to output the XML to.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.SaveOptions" /> that specifies formatting behavior.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.Save(System.Xml.XmlWriter)">
+      <summary>Serialize this <see cref="T:System.Xml.Linq.XDocument" /> to an <see cref="T:System.Xml.XmlWriter" />.</summary>
+      <param name="writer">A <see cref="T:System.Xml.XmlWriter" /> that the <see cref="T:System.Xml.Linq.XDocument" /> will be written to.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocument.WriteTo(System.Xml.XmlWriter)">
+      <summary>Write this document to an <see cref="T:System.Xml.XmlWriter" />.</summary>
+      <param name="writer">An <see cref="T:System.Xml.XmlWriter" /> into which this method will write.</param>
+    </member>
+    <member name="T:System.Xml.Linq.XDocumentType">
+      <summary>Represents an XML Document Type Definition (DTD).  </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XDocumentType.#ctor(System.String,System.String,System.String,System.String)">
+      <summary>Initializes an instance of the <see cref="T:System.Xml.Linq.XDocumentType" /> class. </summary>
+      <param name="name">A <see cref="T:System.String" /> that contains the qualified name of the DTD, which is the same as the qualified name of the root element of the XML document.</param>
+      <param name="publicId">A <see cref="T:System.String" /> that contains the public identifier of an external public DTD.</param>
+      <param name="systemId">A <see cref="T:System.String" /> that contains the system identifier of an external private DTD.</param>
+      <param name="internalSubset">A <see cref="T:System.String" /> that contains the internal subset for an internal DTD.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XDocumentType.#ctor(System.Xml.Linq.XDocumentType)">
+      <summary>Initializes an instance of the <see cref="T:System.Xml.Linq.XDocumentType" /> class from another <see cref="T:System.Xml.Linq.XDocumentType" /> object.</summary>
+      <param name="other">An <see cref="T:System.Xml.Linq.XDocumentType" /> object to copy from.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XDocumentType.InternalSubset">
+      <summary>Gets or sets the internal subset for this Document Type Definition (DTD).</summary>
+      <returns>A <see cref="T:System.String" /> that contains the internal subset for this Document Type Definition (DTD).</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XDocumentType.Name">
+      <summary>Gets or sets the name for this Document Type Definition (DTD).</summary>
+      <returns>A <see cref="T:System.String" /> that contains the name for this Document Type Definition (DTD).</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XDocumentType.NodeType">
+      <summary>Gets the node type for this node.</summary>
+      <returns>The node type. For <see cref="T:System.Xml.Linq.XDocumentType" /> objects, this value is <see cref="F:System.Xml.XmlNodeType.DocumentType" />.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XDocumentType.PublicId">
+      <summary>Gets or sets the public identifier for this Document Type Definition (DTD).</summary>
+      <returns>A <see cref="T:System.String" /> that contains the public identifier for this Document Type Definition (DTD).</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XDocumentType.SystemId">
+      <summary>Gets or sets the system identifier for this Document Type Definition (DTD).</summary>
+      <returns>A <see cref="T:System.String" /> that contains the system identifier for this Document Type Definition (DTD).</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XDocumentType.WriteTo(System.Xml.XmlWriter)">
+      <summary>Write this <see cref="T:System.Xml.Linq.XDocumentType" /> to an <see cref="T:System.Xml.XmlWriter" />.</summary>
+      <param name="writer">An <see cref="T:System.Xml.XmlWriter" /> into which this method will write.</param>
+    </member>
+    <member name="T:System.Xml.Linq.XElement">
+      <summary>Represents an XML element.</summary>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.#ctor(System.Xml.Linq.XElement)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XElement" /> class from another <see cref="T:System.Xml.Linq.XElement" /> object.</summary>
+      <param name="other">An <see cref="T:System.Xml.Linq.XElement" /> object to copy from.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.#ctor(System.Xml.Linq.XName)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XElement" /> class with the specified name. </summary>
+      <param name="name">An <see cref="T:System.Xml.Linq.XName" /> that contains the name of the element.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.#ctor(System.Xml.Linq.XName,System.Object)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XElement" /> class with the specified name and content.</summary>
+      <param name="name">An <see cref="T:System.Xml.Linq.XName" /> that contains the element name.</param>
+      <param name="content">The contents of the element.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.#ctor(System.Xml.Linq.XName,System.Object[])">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XElement" /> class with the specified name and content.</summary>
+      <param name="name">An <see cref="T:System.Xml.Linq.XName" /> that contains the element name.</param>
+      <param name="content">The initial content of the element.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.#ctor(System.Xml.Linq.XStreamingElement)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XElement" /> class from an <see cref="T:System.Xml.Linq.XStreamingElement" /> object.</summary>
+      <param name="other">An <see cref="T:System.Xml.Linq.XStreamingElement" /> that contains unevaluated queries that will be iterated for the contents of this <see cref="T:System.Xml.Linq.XElement" />.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.AncestorsAndSelf">
+      <summary>Returns a collection of elements that contain this element, and the ancestors of this element. </summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> of elements that contain this element, and the ancestors of this element. </returns>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.AncestorsAndSelf(System.Xml.Linq.XName)">
+      <summary>Returns a filtered collection of elements that contain this element, and the ancestors of this element. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contain this element, and the ancestors of this element. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</returns>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> to match.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Attribute(System.Xml.Linq.XName)">
+      <summary>Returns the <see cref="T:System.Xml.Linq.XAttribute" /> of this <see cref="T:System.Xml.Linq.XElement" /> that has the specified <see cref="T:System.Xml.Linq.XName" />.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XAttribute" /> that has the specified <see cref="T:System.Xml.Linq.XName" />; null if there is no attribute with the specified name.</returns>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> of the <see cref="T:System.Xml.Linq.XAttribute" /> to get.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Attributes">
+      <summary>Returns a collection of attributes of this element.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XAttribute" /> of attributes of this element.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Attributes(System.Xml.Linq.XName)">
+      <summary>Returns a filtered collection of attributes of this element. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XAttribute" /> that contains the attributes of this element. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</returns>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> to match.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.DescendantNodesAndSelf">
+      <summary>Returns a collection of nodes that contain this element, and all descendant nodes of this element, in document order.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XNode" /> that contain this element, and all descendant nodes of this element, in document order.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.DescendantsAndSelf">
+      <summary>Returns a collection of elements that contain this element, and all descendant elements of this element, in document order.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> of elements that contain this element, and all descendant elements of this element, in document order.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.DescendantsAndSelf(System.Xml.Linq.XName)">
+      <summary>Returns a filtered collection of elements that contain this element, and all descendant elements of this element, in document order. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contain this element, and all descendant elements of this element, in document order. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</returns>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> to match.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XElement.EmptySequence">
+      <summary>Gets an empty collection of elements.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> that contains an empty collection.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XElement.FirstAttribute">
+      <summary>Gets the first attribute of this element.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XAttribute" /> that contains the first attribute of this element.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.GetDefaultNamespace">
+      <summary>Gets the default <see cref="T:System.Xml.Linq.XNamespace" /> of this <see cref="T:System.Xml.Linq.XElement" />.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XNamespace" /> that contains the default namespace of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.GetNamespaceOfPrefix(System.String)">
+      <summary>Gets the namespace associated with a particular prefix for this <see cref="T:System.Xml.Linq.XElement" />.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XNamespace" /> for the namespace associated with the prefix for this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="prefix">A string that contains the namespace prefix to look up.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.GetPrefixOfNamespace(System.Xml.Linq.XNamespace)">
+      <summary>Gets the prefix associated with a namespace for this <see cref="T:System.Xml.Linq.XElement" />.</summary>
+      <returns>A <see cref="T:System.String" /> that contains the namespace prefix.</returns>
+      <param name="ns">An <see cref="T:System.Xml.Linq.XNamespace" /> to look up.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XElement.HasAttributes">
+      <summary>Gets a value indicating whether this element as at least one attribute.</summary>
+      <returns>true if this element has at least one attribute; otherwise false.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XElement.HasElements">
+      <summary>Gets a value indicating whether this element has at least one child element.</summary>
+      <returns>true if this element has at least one child element; otherwise false.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XElement.IsEmpty">
+      <summary>Gets a value indicating whether this element contains no content.</summary>
+      <returns>true if this element contains no content; otherwise false.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XElement.LastAttribute">
+      <summary>Gets the last attribute of this element.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XAttribute" /> that contains the last attribute of this element.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Load(System.IO.Stream)">
+      <summary>Creates a new <see cref="T:System.Xml.Linq.XElement" /> instance using the specified stream.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XElement" /> object used to read the data contained in the stream.</returns>
+      <param name="stream">The stream containing the XML data.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Load(System.IO.Stream,System.Xml.Linq.LoadOptions)">
+      <summary>Creates a new <see cref="T:System.Xml.Linq.XElement" /> instance using the specified stream, optionally preserving white space, setting the base URI, and retaining line information.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XElement" /> object used to read the data contained in the stream.</returns>
+      <param name="stream">The stream containing the XML data.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.LoadOptions" /> that specifies whether to load base URI and line information.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Load(System.IO.TextReader)">
+      <summary>Loads an <see cref="T:System.Xml.Linq.XElement" /> from a <see cref="T:System.IO.TextReader" />. </summary>
+      <returns>An <see cref="T:System.Xml.Linq.XElement" /> that contains the XML that was read from the specified <see cref="T:System.IO.TextReader" />.</returns>
+      <param name="textReader">A <see cref="T:System.IO.TextReader" /> that will be read for the <see cref="T:System.Xml.Linq.XElement" /> content.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Load(System.IO.TextReader,System.Xml.Linq.LoadOptions)">
+      <summary>Loads an <see cref="T:System.Xml.Linq.XElement" /> from a <see cref="T:System.IO.TextReader" />, optionally preserving white space and retaining line information. </summary>
+      <returns>An <see cref="T:System.Xml.Linq.XElement" /> that contains the XML that was read from the specified <see cref="T:System.IO.TextReader" />.</returns>
+      <param name="textReader">A <see cref="T:System.IO.TextReader" /> that will be read for the <see cref="T:System.Xml.Linq.XElement" /> content.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.LoadOptions" /> that specifies white space behavior, and whether to load base URI and line information.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Load(System.String)">
+      <summary>Loads an <see cref="T:System.Xml.Linq.XElement" /> from a file located in the applications' XAP package.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XElement" /> that contains the contents of the specified file.</returns>
+      <param name="uri">A URI string that references the file to be loaded into a new <see cref="T:System.Xml.Linq.XElement" />. This file is located in the application's XAP package. If you want to download a file from some other location, follow the steps described in How to: Load an XML File from an Arbitrary URI Location with LINQ to XML.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Load(System.String,System.Xml.Linq.LoadOptions)">
+      <summary>Loads an <see cref="T:System.Xml.Linq.XElement" /> from a file located in the application's XAP package, optionally preserving white space, setting the base URI, and retaining line information.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XElement" /> that contains the contents of the specified file.</returns>
+      <param name="uri">A URI string that references the file to be loaded into a new <see cref="T:System.Xml.Linq.XElement" />. This file is located in the application's XAP package. If you want to download a file from some other location, follow the steps described in How to: Load an XML File from an Arbitrary URI Location with LINQ to XML.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.LoadOptions" /> that specifies white space behavior, and whether to load base URI and line information.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Load(System.Xml.XmlReader)">
+      <summary>Loads an <see cref="T:System.Xml.Linq.XElement" /> from an <see cref="T:System.Xml.XmlReader" />. </summary>
+      <returns>An <see cref="T:System.Xml.Linq.XElement" /> that contains the XML that was read from the specified <see cref="T:System.Xml.XmlReader" />.</returns>
+      <param name="reader">A <see cref="T:System.Xml.XmlReader" /> that will be read for the content of the <see cref="T:System.Xml.Linq.XElement" />.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Load(System.Xml.XmlReader,System.Xml.Linq.LoadOptions)">
+      <summary>Loads an <see cref="T:System.Xml.Linq.XElement" /> from an <see cref="T:System.Xml.XmlReader" />, optionally preserving white space, setting the base URI, and retaining line information.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XElement" /> that contains the XML that was read from the specified <see cref="T:System.Xml.XmlReader" />.</returns>
+      <param name="reader">A <see cref="T:System.Xml.XmlReader" /> that will be read for the content of the <see cref="T:System.Xml.Linq.XElement" />.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.LoadOptions" /> that specifies white space behavior, and whether to load base URI and line information.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XElement.Name">
+      <summary>Gets the name of this element.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XName" /> that contains the name of this element.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XElement.NodeType">
+      <summary>Gets the node type for this node.</summary>
+      <returns>The node type. For <see cref="T:System.Xml.Linq.XElement" /> objects, this value is <see cref="F:System.Xml.XmlNodeType.Element" />.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.DateTime">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.DateTime" />.</summary>
+      <returns>A <see cref="T:System.DateTime" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.DateTime" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.DateTime" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="element" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Decimal">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Decimal" />.</summary>
+      <returns>A <see cref="T:System.Decimal" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Decimal" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.Decimal" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="element" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Nullable{System.Decimal}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Decimal" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.Decimal" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Nullable`1" /> of <see cref="T:System.Decimal" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.Decimal" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Nullable{System.Single}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Single" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.Single" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Nullable`1" /> of <see cref="T:System.Single" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.Single" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.TimeSpan">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.TimeSpan" />.</summary>
+      <returns>A <see cref="T:System.TimeSpan" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.TimeSpan" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.TimeSpan" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="element" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Nullable{System.Double}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Double" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.Double" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Nullable`1" /> of <see cref="T:System.Double" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.Double" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Double">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Double" />.</summary>
+      <returns>A <see cref="T:System.Double" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Double" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.Double" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="element" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Single">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Single" />.</summary>
+      <returns>A <see cref="T:System.Single" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Single" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.Single" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="element" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Guid">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Guid" />.</summary>
+      <returns>A <see cref="T:System.Guid" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Guid" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.Guid" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="element" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Nullable{System.Guid}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Guid" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.Guid" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Nullable`1" /> of <see cref="T:System.Guid" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.Guid" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Nullable{System.TimeSpan}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.TimeSpan" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.TimeSpan" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Nullable`1" /> of <see cref="T:System.TimeSpan" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.TimeSpan" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Nullable{System.DateTime}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.DateTime" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.DateTime" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Nullable`1" /> of <see cref="T:System.DateTime" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.DateTime" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.DateTimeOffset">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XAttribute" /> to a <see cref="T:System.DateTimeOffset" />.</summary>
+      <returns>A <see cref="T:System.DateTimeOffset" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.DateTimeOffset" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.DateTimeOffset" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="element" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Nullable{System.DateTimeOffset}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.DateTimeOffset" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.DateTimeOffset" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to an <see cref="T:System.Nullable`1" /> of <see cref="T:System.DateTimeOffset" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.DateTimeOffset" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Int32">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to an <see cref="T:System.Int32" />.</summary>
+      <returns>A <see cref="T:System.Int32" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Int32" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.Int32" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="element" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Nullable{System.Int32}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Int32" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.Int32" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Nullable`1" /> of <see cref="T:System.Int32" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.Int32" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Nullable{System.Boolean}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Boolean" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.Boolean" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Nullable`1" /> of <see cref="T:System.Boolean" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.Boolean" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.String">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.String" />.</summary>
+      <returns>A <see cref="T:System.String" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.String" />.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Boolean">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Boolean" />.</summary>
+      <returns>A <see cref="T:System.Boolean" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Boolean" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.Boolean" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="element" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.UInt32">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.UInt32" />.</summary>
+      <returns>A <see cref="T:System.UInt32" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.UInt32" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.UInt32" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="element" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.UInt64">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.UInt64" />.</summary>
+      <returns>A <see cref="T:System.UInt64" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.UInt64" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.UInt64" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="element" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Nullable{System.UInt64}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.UInt64" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.UInt64" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Nullable`1" /> of <see cref="T:System.UInt64" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.UInt64" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Nullable{System.Int64}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.Int64" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.Int64" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Nullable`1" /> of <see cref="T:System.Int64" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.Int64" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Nullable{System.UInt32}">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to a <see cref="T:System.Nullable`1" /> of <see cref="T:System.UInt32" />.</summary>
+      <returns>A <see cref="T:System.Nullable`1" /> of <see cref="T:System.UInt32" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Nullable`1" /> of <see cref="T:System.UInt32" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.UInt32" /> value.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.op_Explicit(System.Xml.Linq.XElement)~System.Int64">
+      <summary>Cast the value of this <see cref="T:System.Xml.Linq.XElement" /> to an <see cref="T:System.Int64" />.</summary>
+      <returns>A <see cref="T:System.Int64" /> that contains the content of this <see cref="T:System.Xml.Linq.XElement" />.</returns>
+      <param name="element">The <see cref="T:System.Xml.Linq.XElement" /> to cast to <see cref="T:System.Int64" />.</param>
+      <exception cref="T:System.FormatException">The element does not contain a valid <see cref="T:System.Int64" /> value.</exception>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="element" /> parameter is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Parse(System.String)">
+      <summary>Load an <see cref="T:System.Xml.Linq.XElement" /> from a string that contains XML.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XElement" /> populated from the string that contains XML.</returns>
+      <param name="text">A <see cref="T:System.String" /> that contains XML.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Parse(System.String,System.Xml.Linq.LoadOptions)">
+      <summary>Load an <see cref="T:System.Xml.Linq.XElement" /> from a string that contains XML, optionally preserving white space and retaining line information.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XElement" /> populated from the string that contains XML.</returns>
+      <param name="text">A <see cref="T:System.String" /> that contains XML.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.LoadOptions" /> that specifies white space behavior, and whether to load base URI and line information.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.RemoveAll">
+      <summary>Removes nodes and attributes from this <see cref="T:System.Xml.Linq.XElement" />.</summary>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.RemoveAttributes">
+      <summary>Removes the attributes of this <see cref="T:System.Xml.Linq.XElement" />.</summary>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.ReplaceAll(System.Object)">
+      <summary>Replaces the child nodes and the attributes of this element with the specified content.</summary>
+      <param name="content">The content that will replace the child nodes and attributes of this element.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.ReplaceAll(System.Object[])">
+      <summary>Replaces the child nodes and the attributes of this element with the specified content.</summary>
+      <param name="content">A parameter list of content objects.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.ReplaceAttributes(System.Object)">
+      <summary>Replaces the attributes of this element with the specified content.</summary>
+      <param name="content">The content that will replace the attributes of this element.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.ReplaceAttributes(System.Object[])">
+      <summary>Replaces the attributes of this element with the specified content.</summary>
+      <param name="content">A parameter list of content objects.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Save(System.IO.Stream)">
+      <summary>Outputs this <see cref="T:System.Xml.Linq.XElement" /> to the specified <see cref="T:System.IO.Stream" />.</summary>
+      <param name="stream">The stream to output this <see cref="T:System.Xml.Linq.XElement" /> to.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Save(System.IO.Stream,System.Xml.Linq.SaveOptions)">
+      <summary>Outputs this <see cref="T:System.Xml.Linq.XElement" /> to the specified <see cref="T:System.IO.Stream" />, optionally specifying formatting behavior.</summary>
+      <param name="stream">The stream to output this <see cref="T:System.Xml.Linq.XElement" /> to.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.SaveOptions" /> that specifies formatting behavior.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Save(System.IO.TextWriter)">
+      <summary>Serialize this element to a <see cref="T:System.IO.TextWriter" />.</summary>
+      <param name="textWriter">A <see cref="T:System.IO.TextWriter" /> that the <see cref="T:System.Xml.Linq.XElement" /> will be written to.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Save(System.IO.TextWriter,System.Xml.Linq.SaveOptions)">
+      <summary>Serialize this element to a <see cref="T:System.IO.TextWriter" />, optionally disabling formatting.</summary>
+      <param name="textWriter">The <see cref="T:System.IO.TextWriter" /> to output the XML to.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.SaveOptions" /> that specifies formatting behavior.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.Save(System.Xml.XmlWriter)">
+      <summary>Serialize this element to an <see cref="T:System.Xml.XmlWriter" />.</summary>
+      <param name="writer">A <see cref="T:System.Xml.XmlWriter" /> that the <see cref="T:System.Xml.Linq.XElement" /> will be written to.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.SetAttributeValue(System.Xml.Linq.XName,System.Object)">
+      <summary>Sets the value of an attribute, adds an attribute, or removes an attribute. </summary>
+      <param name="name">An <see cref="T:System.Xml.Linq.XName" /> that contains the name of the attribute to change.</param>
+      <param name="value">The value to assign to the attribute. The attribute is removed if the value is null. Otherwise, the value is converted to its string representation and assigned to the <see cref="P:System.Xml.Linq.XAttribute.Value" /> property of the attribute.</param>
+      <exception cref="T:System.ArgumentException">The <paramref name="value" /> is an instance of <see cref="T:System.Xml.Linq.XObject" />.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.SetElementValue(System.Xml.Linq.XName,System.Object)">
+      <summary>Sets the value of a child element, adds a child element, or removes a child element.</summary>
+      <param name="name">An <see cref="T:System.Xml.Linq.XName" /> that contains the name of the child element to change.</param>
+      <param name="value">The value to assign to the child element. The child element is removed if the value is null. Otherwise, the value is converted to its string representation and assigned to the <see cref="P:System.Xml.Linq.XElement.Value" /> property of the child element.</param>
+      <exception cref="T:System.ArgumentException">The <paramref name="value" /> is an instance of <see cref="T:System.Xml.Linq.XObject" />.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.SetValue(System.Object)">
+      <summary>Sets the value of this element.</summary>
+      <param name="value">The value to assign to this element. The value is converted to its string representation and assigned to the <see cref="P:System.Xml.Linq.XElement.Value" /> property.</param>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="value" /> is null.</exception>
+      <exception cref="T:System.ArgumentException">The <paramref name="value" /> is an <see cref="T:System.Xml.Linq.XObject" />.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.System#Xml#Serialization#IXmlSerializable#GetSchema">
+      <summary>Gets an XML schema definition that describes the XML representation of this object.</summary>
+      <returns>An <see cref="T:System.Xml.Schema.XmlSchema" /> that describes the XML representation of the object that is produced by the <see cref="M:System.Xml.Serialization.IXmlSerializable.WriteXml(System.Xml.XmlWriter)" /> method and consumed by the <see cref="M:System.Xml.Serialization.IXmlSerializable.ReadXml(System.Xml.XmlReader)" /> method.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.System#Xml#Serialization#IXmlSerializable#ReadXml(System.Xml.XmlReader)">
+      <summary>Generates an object from its XML representation.</summary>
+      <param name="reader">The <see cref="T:System.Xml.XmlReader" /> from which the object is deserialized.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.System#Xml#Serialization#IXmlSerializable#WriteXml(System.Xml.XmlWriter)">
+      <summary>Converts an object into its XML representation.</summary>
+      <param name="writer">The <see cref="T:System.Xml.XmlWriter" /> to which this object is serialized.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XElement.Value">
+      <summary>Gets the concatenated text contents of this element.</summary>
+      <returns>A <see cref="T:System.String" /> that contains all of the text content of this element. If there are multiple text nodes, they will be concatenated.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XElement.WriteTo(System.Xml.XmlWriter)">
+      <summary>Write this element to an <see cref="T:System.Xml.XmlWriter" />.</summary>
+      <param name="writer">An <see cref="T:System.Xml.XmlWriter" /> into which this method will write.</param>
+    </member>
+    <member name="T:System.Xml.Linq.XName">
+      <summary>Represents a name of an XML element or attribute. </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XName.Equals(System.Object)">
+      <summary>Determines whether the specified <see cref="T:System.Xml.Linq.XName" /> is equal to this <see cref="T:System.Xml.Linq.XName" />.</summary>
+      <returns>true if the specified <see cref="T:System.Xml.Linq.XName" /> is equal to the current <see cref="T:System.Xml.Linq.XName" />; otherwise false.</returns>
+      <param name="obj">The <see cref="T:System.Xml.Linq.XName" /> to compare to the current <see cref="T:System.Xml.Linq.XName" />.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XName.Get(System.String)">
+      <summary>Gets an <see cref="T:System.Xml.Linq.XName" /> object from an expanded name.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XName" /> object constructed from the expanded name.</returns>
+      <param name="expandedName">A <see cref="T:System.String" /> that contains an expanded XML name in the format {namespace}localname.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XName.Get(System.String,System.String)">
+      <summary>Gets an <see cref="T:System.Xml.Linq.XName" /> object from a local name and a namespace.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XName" /> object created from the specified local name and namespace.</returns>
+      <param name="localName">A local (unqualified) name.</param>
+      <param name="namespaceName">An XML namespace.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XName.GetHashCode">
+      <summary>Gets a hash code for this <see cref="T:System.Xml.Linq.XName" />.</summary>
+      <returns>An <see cref="T:System.Int32" /> that contains the hash code for the <see cref="T:System.Xml.Linq.XName" />.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XName.LocalName">
+      <summary>Gets the local (unqualified) part of the name.</summary>
+      <returns>A <see cref="T:System.String" /> that contains the local (unqualified) part of the name.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XName.Namespace">
+      <summary>Gets the namespace part of the fully qualified name.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XNamespace" /> that contains the namespace part of the name.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XName.NamespaceName">
+      <summary>Returns the URI of the <see cref="T:System.Xml.Linq.XNamespace" /> for this <see cref="T:System.Xml.Linq.XName" />.</summary>
+      <returns>The URI of the <see cref="T:System.Xml.Linq.XNamespace" /> for this <see cref="T:System.Xml.Linq.XName" />.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XName.op_Equality(System.Xml.Linq.XName,System.Xml.Linq.XName)">
+      <summary>Returns a value indicating whether two instances of <see cref="T:System.Xml.Linq.XName" /> are equal.</summary>
+      <returns>true if <paramref name="left" /> and <paramref name="right" /> are equal; otherwise false.</returns>
+      <param name="left">The first <see cref="T:System.Xml.Linq.XName" /> to compare.</param>
+      <param name="right">The second <see cref="T:System.Xml.Linq.XName" /> to compare.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XName.op_Implicit(System.String)~System.Xml.Linq.XName">
+      <summary>Converts a string formatted as an expanded XML name (that is,{namespace}localname) to an <see cref="T:System.Xml.Linq.XName" /> object.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XName" /> object constructed from the expanded name.</returns>
+      <param name="expandedName">A string that contains an expanded XML name in the format {namespace}localname.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XName.op_Inequality(System.Xml.Linq.XName,System.Xml.Linq.XName)">
+      <summary>Returns a value indicating whether two instances of <see cref="T:System.Xml.Linq.XName" /> are not equal.</summary>
+      <returns>true if <paramref name="left" /> and <paramref name="right" /> are not equal; otherwise false.</returns>
+      <param name="left">The first <see cref="T:System.Xml.Linq.XName" /> to compare.</param>
+      <param name="right">The second <see cref="T:System.Xml.Linq.XName" /> to compare.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XName.System#IEquatable{T}#Equals(System.Xml.Linq.XName)">
+      <summary>Indicates whether the current <see cref="T:System.Xml.Linq.XName" /> is equal to the specified <see cref="T:System.Xml.Linq.XName" />.</summary>
+      <returns>true if this <see cref="T:System.Xml.Linq.XName" /> is equal to the specified <see cref="T:System.Xml.Linq.XName" />, otherwise false.</returns>
+      <param name="other">The <see cref="T:System.Xml.Linq.XName" /> to compare with this <see cref="T:System.Xml.Linq.XName" />.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XName.ToString">
+      <summary>Returns the expanded XML name in the format {namespace}localname.</summary>
+      <returns>A <see cref="T:System.String" /> that contains the expanded XML name in the format {namespace}localname.</returns>
+    </member>
+    <member name="T:System.Xml.Linq.XNamespace">
+      <summary>Represents an XML namespace. This class cannot be inherited. </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XNamespace.Equals(System.Object)">
+      <summary>Determines whether the specified <see cref="T:System.Xml.Linq.XNamespace" /> is equal to the current <see cref="T:System.Xml.Linq.XNamespace" />.</summary>
+      <returns>A <see cref="T:System.Boolean" /> that indicates whether the specified <see cref="T:System.Xml.Linq.XNamespace" /> is equal to the current <see cref="T:System.Xml.Linq.XNamespace" />.</returns>
+      <param name="obj">The <see cref="T:System.Xml.Linq.XNamespace" /> to compare to the current <see cref="T:System.Xml.Linq.XNamespace" />.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XNamespace.Get(System.String)">
+      <summary>Gets an <see cref="T:System.Xml.Linq.XNamespace" /> for the specified Uniform Resource Identifier (URI).</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XNamespace" /> created from the specified URI.</returns>
+      <param name="namespaceName">A <see cref="T:System.String" /> that contains a namespace URI.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XNamespace.GetHashCode">
+      <summary>Gets a hash code for this <see cref="T:System.Xml.Linq.XNamespace" />.</summary>
+      <returns>An <see cref="T:System.Int32" /> that contains the hash code for the <see cref="T:System.Xml.Linq.XNamespace" />.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XNamespace.GetName(System.String)">
+      <summary>Returns an <see cref="T:System.Xml.Linq.XName" /> object created from this <see cref="T:System.Xml.Linq.XNamespace" /> and the specified local name.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XName" /> created from this <see cref="T:System.Xml.Linq.XNamespace" /> and the specified local name.</returns>
+      <param name="localName">A <see cref="T:System.String" /> that contains a local name.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XNamespace.NamespaceName">
+      <summary>Gets the Uniform Resource Identifier (URI) of this namespace.</summary>
+      <returns>A <see cref="T:System.String" /> that contains the URI of the namespace.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XNamespace.None">
+      <summary>Gets the <see cref="T:System.Xml.Linq.XNamespace" /> object that corresponds to no namespace.</summary>
+      <returns>The <see cref="T:System.Xml.Linq.XNamespace" /> that corresponds to no namespace.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XNamespace.op_Addition(System.Xml.Linq.XNamespace,System.String)">
+      <summary>Combines an <see cref="T:System.Xml.Linq.XNamespace" /> object with a local name to create an <see cref="T:System.Xml.Linq.XName" />.</summary>
+      <returns>The new <see cref="T:System.Xml.Linq.XName" /> constructed from the namespace and local name.</returns>
+      <param name="ns">An <see cref="T:System.Xml.Linq.XNamespace" /> that contains the namespace.</param>
+      <param name="localName">A <see cref="T:System.String" /> that contains the local name.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XNamespace.op_Equality(System.Xml.Linq.XNamespace,System.Xml.Linq.XNamespace)">
+      <summary>Returns a value indicating whether two instances of <see cref="T:System.Xml.Linq.XNamespace" /> are equal.</summary>
+      <returns>A <see cref="T:System.Boolean" /> that indicates whether <paramref name="left" /> and <paramref name="right" /> are equal.</returns>
+      <param name="left">The first <see cref="T:System.Xml.Linq.XNamespace" /> to compare.</param>
+      <param name="right">The second <see cref="T:System.Xml.Linq.XNamespace" /> to compare.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XNamespace.op_Implicit(System.String)~System.Xml.Linq.XNamespace">
+      <summary>Converts a string containing a Uniform Resource Identifier (URI) to an <see cref="T:System.Xml.Linq.XNamespace" />.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XNamespace" /> constructed from the URI string.</returns>
+      <param name="namespaceName">A <see cref="T:System.String" /> that contains the namespace URI.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XNamespace.op_Inequality(System.Xml.Linq.XNamespace,System.Xml.Linq.XNamespace)">
+      <summary>Returns a value indicating whether two instances of <see cref="T:System.Xml.Linq.XNamespace" /> are not equal.</summary>
+      <returns>A <see cref="T:System.Boolean" /> that indicates whether <paramref name="left" /> and <paramref name="right" /> are not equal.</returns>
+      <param name="left">The first <see cref="T:System.Xml.Linq.XNamespace" /> to compare.</param>
+      <param name="right">The second <see cref="T:System.Xml.Linq.XNamespace" /> to compare.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XNamespace.ToString">
+      <summary>Returns the URI of this <see cref="T:System.Xml.Linq.XNamespace" />.</summary>
+      <returns>The URI of this <see cref="T:System.Xml.Linq.XNamespace" />.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XNamespace.Xml">
+      <summary>Gets the <see cref="T:System.Xml.Linq.XNamespace" /> object that corresponds to the XML URI (http://www.w3.org/XML/1998/namespace).</summary>
+      <returns>The <see cref="T:System.Xml.Linq.XNamespace" /> that corresponds to the XML URI (http://www.w3.org/XML/1998/namespace).</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XNamespace.Xmlns">
+      <summary>Gets the <see cref="T:System.Xml.Linq.XNamespace" /> object that corresponds to the xmlns URI (http://www.w3.org/2000/xmlns/).</summary>
+      <returns>The <see cref="T:System.Xml.Linq.XNamespace" /> that corresponds to the xmlns URI (http://www.w3.org/2000/xmlns/).</returns>
+    </member>
+    <member name="T:System.Xml.Linq.XNode">
+      <summary>Represents the abstract concept of a node (one of: element, comment, document type, processing instruction, or text node) in the XML tree.  </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.AddAfterSelf(System.Object)">
+      <summary>Adds the specified content immediately after this node.</summary>
+      <param name="content">A content object that contains simple content or a collection of content objects to be added after this node.</param>
+      <exception cref="T:System.InvalidOperationException">The parent is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.AddAfterSelf(System.Object[])">
+      <summary>Adds the specified content immediately after this node.</summary>
+      <param name="content">A parameter list of content objects.</param>
+      <exception cref="T:System.InvalidOperationException">The parent is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.AddBeforeSelf(System.Object)">
+      <summary>Adds the specified content immediately before this node.</summary>
+      <param name="content">A content object that contains simple content or a collection of content objects to be added before this node.</param>
+      <exception cref="T:System.InvalidOperationException">The parent is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.AddBeforeSelf(System.Object[])">
+      <summary>Adds the specified content immediately before this node.</summary>
+      <param name="content">A parameter list of content objects.</param>
+      <exception cref="T:System.InvalidOperationException">The parent is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.Ancestors">
+      <summary>Returns a collection of the ancestor elements of this node.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> of the ancestor elements of this node.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.Ancestors(System.Xml.Linq.XName)">
+      <summary>Returns a filtered collection of the ancestor elements of this node. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> of the ancestor elements of this node. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.The nodes in the returned collection are in reverse document order.This method uses deferred execution.</returns>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> to match.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.CompareDocumentOrder(System.Xml.Linq.XNode,System.Xml.Linq.XNode)">
+      <summary>Compares two nodes to determine their relative XML document order.</summary>
+      <returns>An int containing 0 if the nodes are equal; -1 if <paramref name="n1" /> is before <paramref name="n2" />; 1 if <paramref name="n1" /> is after <paramref name="n2" />.</returns>
+      <param name="n1">First <see cref="T:System.Xml.Linq.XNode" /> to compare.</param>
+      <param name="n2">Second <see cref="T:System.Xml.Linq.XNode" /> to compare.</param>
+      <exception cref="T:System.InvalidOperationException">The two nodes do not share a common ancestor.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.CreateReader">
+      <summary>Creates an <see cref="T:System.Xml.XmlReader" /> for this node.</summary>
+      <returns>An <see cref="T:System.Xml.XmlReader" /> that can be used to read this node and its descendants.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.CreateReader(System.Xml.Linq.ReaderOptions)">
+      <summary>Creates an <see cref="T:System.Xml.XmlReader" /> for this node.</summary>
+      <returns>An <see cref="T:System.Xml.XmlReader" /> that can be used to read this node and its descendants.</returns>
+      <param name="readerOptions">Specifies whether to omit duplicate namespaces.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.DeepEquals(System.Xml.Linq.XNode,System.Xml.Linq.XNode)">
+      <summary>Compares the values of two nodes, including the values of all descendant nodes.</summary>
+      <returns>true if the nodes are equal; otherwise false.</returns>
+      <param name="n1">The first <see cref="T:System.Xml.Linq.XNode" /> to compare.</param>
+      <param name="n2">The second <see cref="T:System.Xml.Linq.XNode" /> to compare.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XNode.DocumentOrderComparer">
+      <summary>Gets a comparer that can compare the relative position of two nodes.</summary>
+      <returns>A <see cref="T:System.Xml.Linq.XNodeDocumentOrderComparer" /> that can compare the relative position of two nodes.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.ElementsAfterSelf">
+      <summary>Returns a collection of the sibling elements after this node, in document order.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> of the sibling elements after this node, in document order.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.ElementsAfterSelf(System.Xml.Linq.XName)">
+      <summary>Returns a filtered collection of the sibling elements after this node, in document order. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> of the sibling elements after this node, in document order. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</returns>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> to match.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.ElementsBeforeSelf">
+      <summary>Returns a collection of the sibling elements before this node, in document order.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> of the sibling elements before this node, in document order.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.ElementsBeforeSelf(System.Xml.Linq.XName)">
+      <summary>Returns a filtered collection of the sibling elements before this node, in document order. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XElement" /> of the sibling elements before this node, in document order. Only elements that have a matching <see cref="T:System.Xml.Linq.XName" /> are included in the collection.</returns>
+      <param name="name">The <see cref="T:System.Xml.Linq.XName" /> to match.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XNode.EqualityComparer">
+      <summary>Gets a comparer that can compare two nodes for value equality.</summary>
+      <returns>A <see cref="T:System.Xml.Linq.XNodeEqualityComparer" /> that can compare two nodes for value equality.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.IsAfter(System.Xml.Linq.XNode)">
+      <summary>Determines if the current node appears after a specified node in terms of document order.</summary>
+      <returns>true if this node appears after the specified node; otherwise false.</returns>
+      <param name="node">The <see cref="T:System.Xml.Linq.XNode" /> to compare for document order.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.IsBefore(System.Xml.Linq.XNode)">
+      <summary>Determines if the current node appears before a specified node in terms of document order.</summary>
+      <returns>true if this node appears before the specified node; otherwise false.</returns>
+      <param name="node">The <see cref="T:System.Xml.Linq.XNode" /> to compare for document order.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XNode.NextNode">
+      <summary>Gets the next sibling node of this node.</summary>
+      <returns>The <see cref="T:System.Xml.Linq.XNode" /> that contains the next sibling node.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.NodesAfterSelf">
+      <summary>Returns a collection of the sibling nodes after this node, in document order.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XNode" /> of the sibling nodes after this node, in document order.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.NodesBeforeSelf">
+      <summary>Returns a collection of the sibling nodes before this node, in document order.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Xml.Linq.XNode" /> of the sibling nodes before this node, in document order.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XNode.PreviousNode">
+      <summary>Gets the previous sibling node of this node.</summary>
+      <returns>The <see cref="T:System.Xml.Linq.XNode" /> that contains the previous sibling node.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.ReadFrom(System.Xml.XmlReader)">
+      <summary>Creates an <see cref="T:System.Xml.Linq.XNode" /> from an <see cref="T:System.Xml.XmlReader" />.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XNode" /> that contains the node and its descendant nodes that were read from the reader. The runtime type of the node is determined by the node type (<see cref="P:System.Xml.Linq.XObject.NodeType" />) of the first node encountered in the reader.</returns>
+      <param name="reader">An <see cref="T:System.Xml.XmlReader" /> positioned at the node to read into this <see cref="T:System.Xml.Linq.XNode" />.</param>
+      <exception cref="T:System.InvalidOperationException">The <see cref="T:System.Xml.XmlReader" /> is not positioned on a recognized node type.</exception>
+      <exception cref="T:System.Xml.XmlException">The underlying <see cref="T:System.Xml.XmlReader" /> throws an exception.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.Remove">
+      <summary>Removes this node from its parent.</summary>
+      <exception cref="T:System.InvalidOperationException">The parent is null.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.ReplaceWith(System.Object)">
+      <summary>Replaces this node with the specified content.</summary>
+      <param name="content">Content that replaces this node.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.ReplaceWith(System.Object[])">
+      <summary>Replaces this node with the specified content.</summary>
+      <param name="content">A parameter list of the new content.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.ToString">
+      <summary>Returns the indented XML for this node.</summary>
+      <returns>A <see cref="T:System.String" /> containing the indented XML.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.ToString(System.Xml.Linq.SaveOptions)">
+      <summary>Returns the XML for this node, optionally disabling formatting.</summary>
+      <returns>A <see cref="T:System.String" /> containing the XML.</returns>
+      <param name="options">A <see cref="T:System.Xml.Linq.SaveOptions" /> that specifies formatting behavior.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XNode.WriteTo(System.Xml.XmlWriter)">
+      <summary>Writes this node to an <see cref="T:System.Xml.XmlWriter" />.</summary>
+      <param name="writer">An <see cref="T:System.Xml.XmlWriter" /> into which this method will write.</param>
+    </member>
+    <member name="T:System.Xml.Linq.XNodeDocumentOrderComparer">
+      <summary>Contains functionality to compare nodes for their document order. This class cannot be inherited.  </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XNodeDocumentOrderComparer.#ctor">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XNodeDocumentOrderComparer" /> class. </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XNodeDocumentOrderComparer.Compare(System.Xml.Linq.XNode,System.Xml.Linq.XNode)">
+      <summary>Compares two nodes to determine their relative document order.</summary>
+      <returns>An <see cref="T:System.Int32" /> that contains 0 if the nodes are equal; -1 if <paramref name="x" /> is before <paramref name="y" />; 1 if <paramref name="x" /> is after <paramref name="y" />.</returns>
+      <param name="x">The first <see cref="T:System.Xml.Linq.XNode" /> to compare.</param>
+      <param name="y">The second <see cref="T:System.Xml.Linq.XNode" /> to compare.</param>
+      <exception cref="T:System.InvalidOperationException">The two nodes do not share a common ancestor.</exception>
+    </member>
+    <member name="T:System.Xml.Linq.XNodeEqualityComparer">
+      <summary>Compares nodes to determine whether they are equal. This class cannot be inherited. </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XNodeEqualityComparer.#ctor">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XNodeEqualityComparer" /> class. </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XNodeEqualityComparer.Equals(System.Xml.Linq.XNode,System.Xml.Linq.XNode)">
+      <summary>Compares the values of two nodes.</summary>
+      <returns>A <see cref="T:System.Boolean" /> indicating if the nodes are equal.</returns>
+      <param name="x">The first <see cref="T:System.Xml.Linq.XNode" /> to compare.</param>
+      <param name="y">The second <see cref="T:System.Xml.Linq.XNode" /> to compare.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XNodeEqualityComparer.GetHashCode(System.Xml.Linq.XNode)">
+      <summary>Returns a hash code based on an <see cref="T:System.Xml.Linq.XNode" />.</summary>
+      <returns>A <see cref="T:System.Int32" /> that contains a value-based hash code for the node.</returns>
+      <param name="obj">The <see cref="T:System.Xml.Linq.XNode" /> to hash.</param>
+    </member>
+    <member name="T:System.Xml.Linq.XObject">
+      <summary>Represents a node or an attribute in an XML tree. </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XObject.AddAnnotation(System.Object)">
+      <summary>Adds an object to the annotation list of this <see cref="T:System.Xml.Linq.XObject" />.</summary>
+      <param name="annotation">An <see cref="T:System.Object" /> that contains the annotation to add.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XObject.Annotation``1">
+      <summary>Get the first annotation object of the specified type from this <see cref="T:System.Xml.Linq.XObject" />. </summary>
+      <returns>The first annotation object that matches the specified type, or null if no annotation is of the specified type.</returns>
+      <typeparam name="T">The type of the annotation to retrieve.</typeparam>
+    </member>
+    <member name="M:System.Xml.Linq.XObject.Annotation(System.Type)">
+      <summary>Gets the first annotation object of the specified type from this <see cref="T:System.Xml.Linq.XObject" />.</summary>
+      <returns>The <see cref="T:System.Object" /> that contains the first annotation object that matches the specified type, or null if no annotation is of the specified type.</returns>
+      <param name="type">The <see cref="T:System.Type" /> of the annotation to retrieve.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XObject.Annotations``1">
+      <summary>Gets a collection of annotations of the specified type for this <see cref="T:System.Xml.Linq.XObject" />.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> that contains the annotations for this <see cref="T:System.Xml.Linq.XObject" />.</returns>
+      <typeparam name="T">The type of the annotations to retrieve.</typeparam>
+    </member>
+    <member name="M:System.Xml.Linq.XObject.Annotations(System.Type)">
+      <summary>Gets a collection of annotations of the specified type for this <see cref="T:System.Xml.Linq.XObject" />.</summary>
+      <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1" /> of <see cref="T:System.Object" /> that contains the annotations that match the specified type for this <see cref="T:System.Xml.Linq.XObject" />.</returns>
+      <param name="type">The <see cref="T:System.Type" /> of the annotations to retrieve.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XObject.BaseUri">
+      <summary>Gets the base URI for this <see cref="T:System.Xml.Linq.XObject" />.</summary>
+      <returns>A <see cref="T:System.String" /> that contains the base URI for this <see cref="T:System.Xml.Linq.XObject" />.</returns>
+    </member>
+    <member name="E:System.Xml.Linq.XObject.Changed">
+      <summary>Raised when this <see cref="T:System.Xml.Linq.XObject" /> or any of its descendants have changed.</summary>
+    </member>
+    <member name="E:System.Xml.Linq.XObject.Changing">
+      <summary>Raised when this <see cref="T:System.Xml.Linq.XObject" /> or any of its descendants are about to change.</summary>
+    </member>
+    <member name="P:System.Xml.Linq.XObject.Document">
+      <summary>Gets the <see cref="T:System.Xml.Linq.XDocument" /> for this <see cref="T:System.Xml.Linq.XObject" />.</summary>
+      <returns>The <see cref="T:System.Xml.Linq.XDocument" /> for this <see cref="T:System.Xml.Linq.XObject" />. </returns>
+    </member>
+    <member name="P:System.Xml.Linq.XObject.NodeType">
+      <summary>Gets the node type for this <see cref="T:System.Xml.Linq.XObject" />.</summary>
+      <returns>The node type for this <see cref="T:System.Xml.Linq.XObject" />. </returns>
+    </member>
+    <member name="P:System.Xml.Linq.XObject.Parent">
+      <summary>Gets the parent <see cref="T:System.Xml.Linq.XElement" /> of this <see cref="T:System.Xml.Linq.XObject" />.</summary>
+      <returns>The parent <see cref="T:System.Xml.Linq.XElement" /> of this <see cref="T:System.Xml.Linq.XObject" />.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XObject.RemoveAnnotations``1">
+      <summary>Removes the annotations of the specified type from this <see cref="T:System.Xml.Linq.XObject" />.</summary>
+      <typeparam name="T">The type of annotations to remove.</typeparam>
+    </member>
+    <member name="M:System.Xml.Linq.XObject.RemoveAnnotations(System.Type)">
+      <summary>Removes the annotations of the specified type from this <see cref="T:System.Xml.Linq.XObject" />.</summary>
+      <param name="type">The <see cref="T:System.Type" /> of annotations to remove.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XObject.System#Xml#IXmlLineInfo#HasLineInfo">
+      <summary>Gets a value indicating whether or not this <see cref="T:System.Xml.Linq.XObject" /> has line information.</summary>
+      <returns>true if the <see cref="T:System.Xml.Linq.XObject" /> has line information, otherwise false.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XObject.System#Xml#IXmlLineInfo#LineNumber">
+      <summary>Gets the line number that the underlying <see cref="T:System.Xml.XmlReader" /> reported for this <see cref="T:System.Xml.Linq.XObject" />.</summary>
+      <returns>An <see cref="T:System.Int32" /> that contains the line number reported by the <see cref="T:System.Xml.XmlReader" /> for this <see cref="T:System.Xml.Linq.XObject" />.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XObject.System#Xml#IXmlLineInfo#LinePosition">
+      <summary>Gets the line position that the underlying <see cref="T:System.Xml.XmlReader" /> reported for this <see cref="T:System.Xml.Linq.XObject" />.</summary>
+      <returns>An <see cref="T:System.Int32" /> that contains the line position reported by the <see cref="T:System.Xml.XmlReader" /> for this <see cref="T:System.Xml.Linq.XObject" />.</returns>
+    </member>
+    <member name="T:System.Xml.Linq.XObjectChange">
+      <summary>Specifies the event type when an event is raised for an <see cref="T:System.Xml.Linq.XObject" />.</summary>
+    </member>
+    <member name="F:System.Xml.Linq.XObjectChange.Add">
+      <summary>An <see cref="T:System.Xml.Linq.XObject" /> has been or will be added to an <see cref="T:System.Xml.Linq.XContainer" />.</summary>
+    </member>
+    <member name="F:System.Xml.Linq.XObjectChange.Remove">
+      <summary>An <see cref="T:System.Xml.Linq.XObject" /> has been or will be removed from an <see cref="T:System.Xml.Linq.XContainer" />.</summary>
+    </member>
+    <member name="F:System.Xml.Linq.XObjectChange.Name">
+      <summary>An <see cref="T:System.Xml.Linq.XObject" /> has been or will be renamed.</summary>
+    </member>
+    <member name="F:System.Xml.Linq.XObjectChange.Value">
+      <summary>The value of an <see cref="T:System.Xml.Linq.XObject" /> has been or will be changed. In addition, a change in the serialization of an empty element (either from an empty tag to start/end tag pair or vice versa) raises this event.</summary>
+    </member>
+    <member name="T:System.Xml.Linq.XObjectChangeEventArgs">
+      <summary>Provides data for the <see cref="E:System.Xml.Linq.XObject.Changing" /> and <see cref="E:System.Xml.Linq.XObject.Changed" /> events.</summary>
+    </member>
+    <member name="M:System.Xml.Linq.XObjectChangeEventArgs.#ctor(System.Xml.Linq.XObjectChange)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XObjectChangeEventArgs" /> class. </summary>
+      <param name="objectChange">An <see cref="T:System.Xml.Linq.XObjectChange" /> that contains the event arguments for LINQ to XML events.</param>
+    </member>
+    <member name="F:System.Xml.Linq.XObjectChangeEventArgs.Add">
+      <summary>Event argument for an <see cref="F:System.Xml.Linq.XObjectChange.Add" /> change event.</summary>
+    </member>
+    <member name="F:System.Xml.Linq.XObjectChangeEventArgs.Name">
+      <summary>Event argument for a <see cref="F:System.Xml.Linq.XObjectChange.Name" /> change event.</summary>
+    </member>
+    <member name="P:System.Xml.Linq.XObjectChangeEventArgs.ObjectChange">
+      <summary>Gets the type of change.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XObjectChange" /> that contains the type of change.</returns>
+    </member>
+    <member name="F:System.Xml.Linq.XObjectChangeEventArgs.Remove">
+      <summary>Event argument for a <see cref="F:System.Xml.Linq.XObjectChange.Remove" /> change event.</summary>
+    </member>
+    <member name="F:System.Xml.Linq.XObjectChangeEventArgs.Value">
+      <summary>Event argument for a <see cref="F:System.Xml.Linq.XObjectChange.Value" /> change event.</summary>
+    </member>
+    <member name="T:System.Xml.Linq.XProcessingInstruction">
+      <summary>Represents an XML processing instruction. </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XProcessingInstruction.#ctor(System.String,System.String)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XProcessingInstruction" /> class. </summary>
+      <param name="target">A <see cref="T:System.String" /> containing the target application for this <see cref="T:System.Xml.Linq.XProcessingInstruction" />.</param>
+      <param name="data">The string data for this <see cref="T:System.Xml.Linq.XProcessingInstruction" />.</param>
+      <exception cref="T:System.ArgumentNullException">The <paramref name="target" /> or <paramref name="data" /> parameter is null.</exception>
+      <exception cref="T:System.ArgumentException">The <paramref name="target" /> does not follow the constraints of an XML name.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XProcessingInstruction.#ctor(System.Xml.Linq.XProcessingInstruction)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XProcessingInstruction" /> class. </summary>
+      <param name="other">The <see cref="T:System.Xml.Linq.XProcessingInstruction" /> node to copy from.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XProcessingInstruction.Data">
+      <summary>Gets or sets the string value of this processing instruction.</summary>
+      <returns>A <see cref="T:System.String" /> that contains the string value of this processing instruction.</returns>
+      <exception cref="T:System.ArgumentNullException">The string <paramref name="value" /> is null.</exception>
+    </member>
+    <member name="P:System.Xml.Linq.XProcessingInstruction.NodeType">
+      <summary>Gets the node type for this node.</summary>
+      <returns>The node type. For <see cref="T:System.Xml.Linq.XProcessingInstruction" /> objects, this value is <see cref="F:System.Xml.XmlNodeType.ProcessingInstruction" />.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XProcessingInstruction.Target">
+      <summary>Gets or sets a string containing the target application for this processing instruction.</summary>
+      <returns>A <see cref="T:System.String" /> containing the target application for this processing instruction.</returns>
+      <exception cref="T:System.ArgumentNullException">The string <paramref name="value" /> is null.</exception>
+      <exception cref="T:System.ArgumentException">The <paramref name="target" /> does not follow the constraints of an XML name.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XProcessingInstruction.WriteTo(System.Xml.XmlWriter)">
+      <summary>Writes this processing instruction to an <see cref="T:System.Xml.XmlWriter" />.</summary>
+      <param name="writer">The <see cref="T:System.Xml.XmlWriter" /> to write this processing instruction to.</param>
+    </member>
+    <member name="T:System.Xml.Linq.XStreamingElement">
+      <summary>Represents elements in an XML tree that supports deferred streaming output.</summary>
+    </member>
+    <member name="M:System.Xml.Linq.XStreamingElement.#ctor(System.Xml.Linq.XName)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XElement" /> class from the specified <see cref="T:System.Xml.Linq.XName" />.</summary>
+      <param name="name">An <see cref="T:System.Xml.Linq.XName" /> that contains the name of the element.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XStreamingElement.#ctor(System.Xml.Linq.XName,System.Object)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XStreamingElement" /> class with the specified name and content.</summary>
+      <param name="name">An <see cref="T:System.Xml.Linq.XName" /> that contains the element name.</param>
+      <param name="content">The contents of the element.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XStreamingElement.#ctor(System.Xml.Linq.XName,System.Object[])">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XStreamingElement" /> class with the specified name and content.</summary>
+      <param name="name">An <see cref="T:System.Xml.Linq.XName" /> that contains the element name.</param>
+      <param name="content">The contents of the element.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XStreamingElement.Add(System.Object)">
+      <summary>Adds the specified content as children to this <see cref="T:System.Xml.Linq.XStreamingElement" />.</summary>
+      <param name="content">Content to be added to the streaming element.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XStreamingElement.Add(System.Object[])">
+      <summary>Adds the specified content as children to this <see cref="T:System.Xml.Linq.XStreamingElement" />.</summary>
+      <param name="content">Content to be added to the streaming element.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XStreamingElement.Name">
+      <summary>Gets or sets the name of this streaming element.</summary>
+      <returns>An <see cref="T:System.Xml.Linq.XName" /> that contains the name of this streaming element.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XStreamingElement.Save(System.IO.Stream)">
+      <summary>Outputs this <see cref="T:System.Xml.Linq.XStreamingElement" /> to the specified <see cref="T:System.IO.Stream" />.</summary>
+      <param name="stream">The stream to output this <see cref="T:System.Xml.Linq.XDocument" /> to.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XStreamingElement.Save(System.IO.Stream,System.Xml.Linq.SaveOptions)">
+      <summary>Outputs this <see cref="T:System.Xml.Linq.XStreamingElement" /> to the specified <see cref="T:System.IO.Stream" />, optionally specifying formatting behavior.</summary>
+      <param name="stream">The stream to output this <see cref="T:System.Xml.Linq.XDocument" /> to.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.SaveOptions" /> that specifies formatting behavior.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XStreamingElement.Save(System.IO.TextWriter)">
+      <summary>Serialize this streaming element to a <see cref="T:System.IO.TextWriter" />.</summary>
+      <param name="textWriter">A <see cref="T:System.IO.TextWriter" /> that the <see cref="T:System.Xml.Linq.XStreamingElement" /> will be written to.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XStreamingElement.Save(System.IO.TextWriter,System.Xml.Linq.SaveOptions)">
+      <summary>Serialize this streaming element to a <see cref="T:System.IO.TextWriter" />, optionally disabling formatting.</summary>
+      <param name="textWriter">The <see cref="T:System.IO.TextWriter" /> to output the XML to.</param>
+      <param name="options">A <see cref="T:System.Xml.Linq.SaveOptions" /> that specifies formatting behavior.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XStreamingElement.Save(System.Xml.XmlWriter)">
+      <summary>Serialize this streaming element to an <see cref="T:System.Xml.XmlWriter" />.</summary>
+      <param name="writer">A <see cref="T:System.Xml.XmlWriter" /> that the <see cref="T:System.Xml.Linq.XElement" /> will be written to.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XStreamingElement.ToString">
+      <summary>Returns the formatted (indented) XML for this streaming element.</summary>
+      <returns>A <see cref="T:System.String" /> containing the indented XML.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XStreamingElement.ToString(System.Xml.Linq.SaveOptions)">
+      <summary>Returns the XML for this streaming element, optionally disabling formatting.</summary>
+      <returns>A <see cref="T:System.String" /> containing the XML.</returns>
+      <param name="options">A <see cref="T:System.Xml.Linq.SaveOptions" /> that specifies formatting behavior.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XStreamingElement.WriteTo(System.Xml.XmlWriter)">
+      <summary>Writes this streaming element to an <see cref="T:System.Xml.XmlWriter" />.</summary>
+      <param name="writer">An <see cref="T:System.Xml.XmlWriter" /> into which this method will write.</param>
+    </member>
+    <member name="T:System.Xml.Linq.XText">
+      <summary>Represents a text node.  </summary>
+    </member>
+    <member name="M:System.Xml.Linq.XText.#ctor(System.String)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XText" /> class. </summary>
+      <param name="value">The <see cref="T:System.String" /> that contains the value of the <see cref="T:System.Xml.Linq.XText" /> node.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XText.#ctor(System.Xml.Linq.XText)">
+      <summary>Initializes a new instance of the <see cref="T:System.Xml.Linq.XText" /> class from another <see cref="T:System.Xml.Linq.XText" /> object.</summary>
+      <param name="other">The <see cref="T:System.Xml.Linq.XText" /> node to copy from.</param>
+    </member>
+    <member name="P:System.Xml.Linq.XText.NodeType">
+      <summary>Gets the node type for this node.</summary>
+      <returns>The node type. For <see cref="T:System.Xml.Linq.XText" /> objects, this value is <see cref="F:System.Xml.XmlNodeType.Text" />.</returns>
+    </member>
+    <member name="P:System.Xml.Linq.XText.Value">
+      <summary>Gets or sets the value of this node.</summary>
+      <returns>A <see cref="T:System.String" /> that contains the value of this node.</returns>
+    </member>
+    <member name="M:System.Xml.Linq.XText.WriteTo(System.Xml.XmlWriter)">
+      <summary>Writes this node to an <see cref="T:System.Xml.XmlWriter" />.</summary>
+      <param name="writer">An <see cref="T:System.Xml.XmlWriter" /> into which this method will write.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XNodeDocumentOrderComparer.System#Collections#IComparer#Compare(System.Object,System.Object)">
+      <summary>Compares two nodes to determine their relative document order.</summary>
+      <returns>An <see cref="T:System.Int32" /> that contains 0 if the nodes are equal; -1 if <paramref name="x" /> is before <paramref name="y" />; 1 if <paramref name="x" /> is after <paramref name="y" />.</returns>
+      <param name="x">The first <see cref="T:System.Xml.Linq.XNode" /> to compare.</param>
+      <param name="y">The second <see cref="T:System.Xml.Linq.XNode" /> to compare.</param>
+      <exception cref="T:System.InvalidOperationException">The two nodes do not share a common ancestor.</exception>
+      <exception cref="T:System.ArgumentException">The two nodes are not derived from <see cref="T:System.Xml.Linq.XNode" />.</exception>
+    </member>
+    <member name="M:System.Xml.Linq.XNodeEqualityComparer.System#Collections#IEqualityComparer#Equals(System.Object,System.Object)">
+      <summary>Compares the values of two nodes.</summary>
+      <returns>true if the nodes are equal; otherwise false.</returns>
+      <param name="x">The first <see cref="T:System.Xml.Linq.XNode" /> to compare.</param>
+      <param name="y">The second <see cref="T:System.Xml.Linq.XNode" /> to compare.</param>
+    </member>
+    <member name="M:System.Xml.Linq.XNodeEqualityComparer.System#Collections#IEqualityComparer#GetHashCode(System.Object)">
+      <summary>Returns a hash code based on the value of a node.</summary>
+      <returns>A <see cref="T:System.Int32" /> that contains a value-based hash code for the node.</returns>
+      <param name="obj">The node to hash.</param>
+    </member>
+  </members>
+</doc>
\ No newline at end of file
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/de/Microsoft.CSharp.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/de/Microsoft.CSharp.resources.dll
new file mode 100644 (file)
index 0000000..578348f
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/de/Microsoft.CSharp.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/de/System.Json.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/de/System.Json.resources.dll
new file mode 100644 (file)
index 0000000..f47219d
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/de/System.Json.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/de/System.Runtime.Serialization.Json.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/de/System.Runtime.Serialization.Json.resources.dll
new file mode 100644 (file)
index 0000000..628d002
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/de/System.Runtime.Serialization.Json.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/de/System.Xml.Linq.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/de/System.Xml.Linq.resources.dll
new file mode 100644 (file)
index 0000000..8f968ed
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/de/System.Xml.Linq.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/es/Microsoft.CSharp.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/es/Microsoft.CSharp.resources.dll
new file mode 100644 (file)
index 0000000..640f83d
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/es/Microsoft.CSharp.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/es/System.Json.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/es/System.Json.resources.dll
new file mode 100644 (file)
index 0000000..3704372
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/es/System.Json.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/es/System.Runtime.Serialization.Json.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/es/System.Runtime.Serialization.Json.resources.dll
new file mode 100644 (file)
index 0000000..a699db2
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/es/System.Runtime.Serialization.Json.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/es/System.Xml.Linq.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/es/System.Xml.Linq.resources.dll
new file mode 100644 (file)
index 0000000..08aac27
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/es/System.Xml.Linq.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/fr/Microsoft.CSharp.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/fr/Microsoft.CSharp.resources.dll
new file mode 100644 (file)
index 0000000..a9de5c4
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/fr/Microsoft.CSharp.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/fr/System.Json.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/fr/System.Json.resources.dll
new file mode 100644 (file)
index 0000000..18d5676
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/fr/System.Json.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/fr/System.Runtime.Serialization.Json.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/fr/System.Runtime.Serialization.Json.resources.dll
new file mode 100644 (file)
index 0000000..f30cf5c
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/fr/System.Runtime.Serialization.Json.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/fr/System.Xml.Linq.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/fr/System.Xml.Linq.resources.dll
new file mode 100644 (file)
index 0000000..24d4207
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/fr/System.Xml.Linq.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/it/Microsoft.CSharp.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/it/Microsoft.CSharp.resources.dll
new file mode 100644 (file)
index 0000000..b605d22
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/it/Microsoft.CSharp.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/it/System.Json.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/it/System.Json.resources.dll
new file mode 100644 (file)
index 0000000..e2a0427
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/it/System.Json.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/it/System.Runtime.Serialization.Json.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/it/System.Runtime.Serialization.Json.resources.dll
new file mode 100644 (file)
index 0000000..bd173f5
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/it/System.Runtime.Serialization.Json.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/it/System.Xml.Linq.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/it/System.Xml.Linq.resources.dll
new file mode 100644 (file)
index 0000000..94c1c16
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/it/System.Xml.Linq.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/ja/Microsoft.CSharp.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/ja/Microsoft.CSharp.resources.dll
new file mode 100644 (file)
index 0000000..835edff
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/ja/Microsoft.CSharp.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/ja/System.Json.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/ja/System.Json.resources.dll
new file mode 100644 (file)
index 0000000..72c9c6f
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/ja/System.Json.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/ja/System.Runtime.Serialization.Json.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/ja/System.Runtime.Serialization.Json.resources.dll
new file mode 100644 (file)
index 0000000..614e67a
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/ja/System.Runtime.Serialization.Json.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/ja/System.Xml.Linq.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/ja/System.Xml.Linq.resources.dll
new file mode 100644 (file)
index 0000000..d9ff5ce
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/ja/System.Xml.Linq.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/ko/Microsoft.CSharp.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/ko/Microsoft.CSharp.resources.dll
new file mode 100644 (file)
index 0000000..d49d7b5
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/ko/Microsoft.CSharp.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/ko/System.Json.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/ko/System.Json.resources.dll
new file mode 100644 (file)
index 0000000..bbee67a
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/ko/System.Json.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/ko/System.Runtime.Serialization.Json.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/ko/System.Runtime.Serialization.Json.resources.dll
new file mode 100644 (file)
index 0000000..e7fa814
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/ko/System.Runtime.Serialization.Json.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/ko/System.Xml.Linq.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/ko/System.Xml.Linq.resources.dll
new file mode 100644 (file)
index 0000000..ae2e5ff
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/ko/System.Xml.Linq.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/ru/Microsoft.CSharp.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/ru/Microsoft.CSharp.resources.dll
new file mode 100644 (file)
index 0000000..eabd804
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/ru/Microsoft.CSharp.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/ru/System.Json.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/ru/System.Json.resources.dll
new file mode 100644 (file)
index 0000000..055117f
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/ru/System.Json.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/ru/System.Runtime.Serialization.Json.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/ru/System.Runtime.Serialization.Json.resources.dll
new file mode 100644 (file)
index 0000000..5105120
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/ru/System.Runtime.Serialization.Json.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/ru/System.Xml.Linq.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/ru/System.Xml.Linq.resources.dll
new file mode 100644 (file)
index 0000000..35fa767
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/ru/System.Xml.Linq.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hans/Microsoft.CSharp.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hans/Microsoft.CSharp.resources.dll
new file mode 100644 (file)
index 0000000..8663d91
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hans/Microsoft.CSharp.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hans/System.Json.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hans/System.Json.resources.dll
new file mode 100644 (file)
index 0000000..724ea6f
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hans/System.Json.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hans/System.Runtime.Serialization.Json.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hans/System.Runtime.Serialization.Json.resources.dll
new file mode 100644 (file)
index 0000000..0d38886
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hans/System.Runtime.Serialization.Json.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hans/System.Xml.Linq.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hans/System.Xml.Linq.resources.dll
new file mode 100644 (file)
index 0000000..f43418a
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hans/System.Xml.Linq.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hant/Microsoft.CSharp.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hant/Microsoft.CSharp.resources.dll
new file mode 100644 (file)
index 0000000..e935e3a
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hant/Microsoft.CSharp.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hant/System.Json.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hant/System.Json.resources.dll
new file mode 100644 (file)
index 0000000..7055428
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hant/System.Json.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hant/System.Runtime.Serialization.Json.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hant/System.Runtime.Serialization.Json.resources.dll
new file mode 100644 (file)
index 0000000..550bfd3
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hant/System.Runtime.Serialization.Json.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hant/System.Xml.Linq.resources.dll b/trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hant/System.Xml.Linq.resources.dll
new file mode 100644 (file)
index 0000000..233d5c3
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/lib/sl4/zh-Hant/System.Xml.Linq.resources.dll differ
diff --git a/trunk/packages/Hammock.1.2.3/mono/Hammock.Mono.dll b/trunk/packages/Hammock.1.2.3/mono/Hammock.Mono.dll
new file mode 100644 (file)
index 0000000..73d38f0
Binary files /dev/null and b/trunk/packages/Hammock.1.2.3/mono/Hammock.Mono.dll differ
diff --git a/trunk/packages/Massive.1.0/Massive.1.0.nupkg b/trunk/packages/Massive.1.0/Massive.1.0.nupkg
new file mode 100644 (file)
index 0000000..a19b5a1
Binary files /dev/null and b/trunk/packages/Massive.1.0/Massive.1.0.nupkg differ
diff --git a/trunk/packages/Massive.1.0/content/App_Code/LICENSE.txt b/trunk/packages/Massive.1.0/content/App_Code/LICENSE.txt
new file mode 100644 (file)
index 0000000..f90aa76
--- /dev/null
@@ -0,0 +1,11 @@
+New BSD License
+http://www.opensource.org/licenses/bsd-license.php
+Copyright (c) 2009, Rob Conery (robconery@gmail.com)
+All rights reserved.    
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+Neither the name of the SubSonic nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/trunk/packages/Massive.1.0/content/App_Code/Massive.cs b/trunk/packages/Massive.1.0/content/App_Code/Massive.cs
new file mode 100644 (file)
index 0000000..af02d0c
--- /dev/null
@@ -0,0 +1,400 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Configuration;
+using System.Data;
+using System.Data.Common;
+using System.Dynamic;
+using System.Linq;
+using System.Text;
+
+namespace Massive {
+    public static class ObjectExtensions {
+        /// <summary>
+        /// Extension method for adding in a bunch of parameters
+        /// </summary>
+        public static void AddParams(this DbCommand cmd, object[] args) {
+            foreach (var item in args) {
+                AddParam(cmd, item);
+            }
+        }
+        /// <summary>
+        /// Extension for adding single parameter
+        /// </summary>
+        public static void AddParam(this DbCommand cmd, object item) {
+            var p = cmd.CreateParameter();
+            p.ParameterName = string.Format("@{0}", cmd.Parameters.Count);
+            //fix for NULLs as parameter values
+            if (item == null) {
+                p.Value = DBNull.Value;
+            } else {
+                //fix for Guids
+                if (item.GetType() == typeof(Guid)) {
+                    p.Value = item.ToString();
+                    p.DbType = DbType.String;
+                } else {
+                    p.Value = item;
+                }
+            }
+            cmd.Parameters.Add(p);
+        }
+        /// <summary>
+        /// Turns an IDataReader to a Dynamic list of things
+        /// </summary>
+        public static List<dynamic> ToExpandoList(this IDataReader rdr) {
+            var result = new List<dynamic>();
+            //work with the Expando as a Dictionary
+            while (rdr.Read()) {
+                dynamic e = new ExpandoObject();
+                var d = e as IDictionary<string, object>;
+                for (int i = 0; i < rdr.FieldCount; i++)
+                    d.Add(rdr.GetName(i), rdr[i]);
+                result.Add(e);
+            }
+            return result;
+        }
+        /// <summary>
+        /// Turns the object into an ExpandoObject
+        /// </summary>
+        /// <param name="o"></param>
+        /// <returns></returns>
+        public static dynamic ToExpando(this object o) {
+            var result = new ExpandoObject();
+            var d = result as IDictionary<string, object>; //work with the Expando as a Dictionary
+            if (o.GetType() == typeof(ExpandoObject)) return o; //shouldn't have to... but just in case
+            //special for form submissions
+            if (o.GetType() == typeof(NameValueCollection)) {
+                var nv = (NameValueCollection)o;
+                nv.Cast<string>().Select(key => new KeyValuePair<string, object>(key, nv[key])).ToList().ForEach(i => d.Add(i));
+            } else {
+                //assume it's a regular lovely object
+                var props = o.GetType().GetProperties();
+                foreach (var item in props) {
+                    d.Add(item.Name, item.GetValue(o, null));
+                }
+            }
+            return result;
+        }
+        /// <summary>
+        /// Turns the object into a Dictionary
+        /// </summary>
+        /// <param name="thingy"></param>
+        /// <returns></returns>
+        public static IDictionary<string, object> ToDictionary(this object thingy) {
+            return (IDictionary<string, object>)thingy.ToExpando();
+        }
+    }
+    /// <summary>
+    /// A class that wraps your database table in Dynamic Funtime
+    /// </summary>
+    public abstract class DynamicModel : DynamicObject {
+        DbProviderFactory _factory;
+        string _connectionStringName;
+        string _connectionString;
+
+        public IList<dynamic> Query(string sql, params object[] args) {
+            var result = new List<dynamic>();
+            using (var conn = OpenConnection()) {
+                using (var cmd = CreateCommand(sql, args)) {
+                    cmd.Connection = conn;
+                    using (var rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection)) {
+                        result = rdr.ToExpandoList();
+                    }
+                }
+            }
+            return result;
+        }
+        /// <summary>
+        /// Creates a DBCommand that you can use for loving your database.
+        /// </summary>
+        DbCommand CreateCommand(string sql, params object[] args) {
+            DbCommand result = null;
+            result = _factory.CreateCommand();
+            result.CommandText = sql;
+            if (args.Length > 0)
+                result.AddParams(args);
+            return result;
+        }
+        DbConnection GetConnection() {
+            var connection = _factory.CreateConnection();
+            connection.ConnectionString = _connectionString;
+            return connection;
+        }
+        DbConnection OpenConnection() {
+            var conn = GetConnection();
+            conn.Open();
+            return conn;
+        }
+        /// <summary>
+        /// Creates a slick, groovy little wrapper for your action
+        /// </summary>
+        /// <param name="connectionStringName"></param>
+        public DynamicModel(string connectionStringName) {
+            //can be overridden by property setting
+            TableName = this.GetType().Name;
+            _connectionStringName = connectionStringName;
+
+            var providerName = "System.Data.SqlClient";
+            if (ConfigurationManager.ConnectionStrings[_connectionStringName] != null) {
+                providerName = ConfigurationManager.ConnectionStrings[_connectionStringName].ProviderName ?? "System.Data.SqlClient";
+            } else {
+                throw new InvalidOperationException("Can't find a connection string with the name '" + _connectionStringName + "'");
+            }
+            _factory = DbProviderFactories.GetFactory(providerName);
+            _connectionString = ConfigurationManager.ConnectionStrings[_connectionStringName].ConnectionString;
+        }
+        string _primaryKeyField;
+        /// <summary>
+        /// Conventionally returns a PK field. The default is "ID" if you don't set one
+        /// </summary>
+        public string PrimaryKeyField {
+            get { return string.IsNullOrEmpty(_primaryKeyField) ? /*a bit of convention here*/ "ID" : /*oh well - did our best*/ _primaryKeyField; }
+            set { _primaryKeyField = value; }
+        }
+        /// <summary>
+        /// Conventionally introspects the object passed in for a field that 
+        /// looks like a PK. If you've named your PrimaryKeyField, this becomes easy
+        /// </summary>
+        public bool HasPrimaryKey(object o) {
+            var result = o.ToDictionary().ContainsKey(PrimaryKeyField);
+            return result;
+        }
+        /// <summary>
+        /// If the object passed in has a property with the same name as your PrimaryKeyField
+        /// it is returned here.
+        /// </summary>
+        public object GetPrimaryKey(object o) {
+            var d = o.ToDictionary();
+            object result = null;
+            d.TryGetValue(PrimaryKeyField, out result);
+            return result;
+        }
+        /// <summary>
+        /// The name of the Database table we're working with. This defaults to 
+        /// the class name - set this value if it's different
+        /// </summary>
+        public string TableName { get; set; }
+        /// <summary>
+        /// Adds a record to the database. You can pass in an Anonymous object, an ExpandoObject,
+        /// A regular old POCO, or a NameValueColletion from a Request.Form or Request.QueryString
+        /// </summary>
+        public dynamic Insert(object o) {
+            dynamic result = 0;
+            if (BeforeInsert(o)) {
+                using (var conn = OpenConnection()) {
+                    using (var cmd = CreateInsertCommand(o)) {
+                        cmd.Connection = conn;
+                        result = cmd.ExecuteScalar();
+                    }
+                    AfterInsert(o);
+                }
+            }
+            return result;
+        }
+
+        /// <summary>
+        /// Creates a command for use with transactions - internal stuff mostly, but here for you to play with
+        /// </summary>
+        public DbCommand CreateInsertCommand(object o) {
+            DbCommand result = null;
+            //turn this into an expando - we'll need that for the validators
+            var expando = o.ToExpando();
+            var settings = (IDictionary<string, object>)expando;
+            var sbKeys = new StringBuilder();
+            var sbVals = new StringBuilder();
+            var stub = "INSERT INTO {0} ({1}) \r\n VALUES ({2}); \r\nSELECT SCOPE_IDENTITY()";
+            result = CreateCommand(stub);
+
+            int counter = 0;
+            foreach (var item in settings) {
+                sbKeys.AppendFormat("{0},", item.Key);
+                sbVals.AppendFormat("@{0},", counter.ToString());
+                result.AddParam(item.Value);
+                counter++;
+            }
+            if (counter > 0) {
+                //strip off trailing commas
+                var keys = sbKeys.ToString().Substring(0, sbKeys.Length - 1);
+                var vals = sbVals.ToString().Substring(0, sbVals.Length - 1);
+                var sql = string.Format(stub, TableName, keys, vals);
+                result.CommandText = sql;
+            } else throw new InvalidOperationException("Can't parse this object to the database - there are no properties set");
+            return result;
+        }
+
+        /// <summary>
+        /// Creates a command for use with transactions - internal stuff mostly, but here for you to play with
+        /// </summary>
+        public DbCommand CreateUpdateCommand(object o, object key) {
+            var expando = o.ToExpando();
+            var settings = (IDictionary<string, object>)expando;
+            var sbKeys = new StringBuilder();
+            var stub = "UPDATE {0} SET {1} WHERE {2} = @{3}";
+            var args = new List<object>();
+            var result = CreateCommand(stub);
+            int counter = 0;
+            foreach (var item in settings) {
+                var val = item.Value;
+                if (!item.Key.Equals(PrimaryKeyField, StringComparison.CurrentCultureIgnoreCase) && item.Value != null) {
+                    result.AddParam(val);
+                    sbKeys.AppendFormat("{0} = @{1}, \r\n", item.Key, counter.ToString());
+                    counter++;
+                }
+            }
+            if (counter > 0) {
+                //add the key
+                result.AddParam(key);
+                //strip the last commas
+                var keys = sbKeys.ToString().Substring(0, sbKeys.Length - 4);
+                result.CommandText = string.Format(stub, TableName, keys, PrimaryKeyField, counter);
+            } else throw new InvalidOperationException("No parsable object was sent in - could not divine any name/value pairs");
+            return result;
+        }
+        /// <summary>
+        /// Updates a record in the database. You can pass in an Anonymous object, an ExpandoObject,
+        /// A regular old POCO, or a NameValueCollection from a Request.Form or Request.QueryString
+        /// </summary>
+        public int Update(object o, object key) {
+            //turn this into an expando - we'll need that for the validators
+            int result = 0;
+            if (BeforeUpdate(o)) {
+                using (var conn = OpenConnection()) {
+                    using (var cmd = CreateUpdateCommand(o, key)) {
+                        result = cmd.ExecuteNonQuery();
+                        AfterUpdate(o);
+                    }
+                }
+            }
+            return result;
+        }
+        /// <summary>
+        /// Updates a bunch of records in the database within a transaction. You can pass Anonymous objects, ExpandoObjects,
+        /// Regular old POCOs - these all have to have a PK set
+        /// </summary>
+        public int InsertMany(IEnumerable<object> things) {
+            int result = 0;
+            using (var conn = OpenConnection()) {
+                using (var tx = conn.BeginTransaction()) {
+                    foreach (var item in things) {
+                        if (BeforeInsert(item)) {
+                            using (var cmd = CreateInsertCommand(item)) {
+                                cmd.Connection = conn;
+                                cmd.Transaction = tx;
+                                cmd.ExecuteNonQuery();
+                            }
+                            AfterInsert(item);
+                        }
+                        result++;
+                    }
+                    tx.Commit();
+                }
+            }
+            return result;
+        }
+        /// <summary>
+        /// Updates a bunch of records in the database within a transaction. You can pass Anonymous objects, ExpandoObjects,
+        /// Regular old POCOs - these all have to have a PK set
+        /// </summary>
+        public int UpdateMany(IEnumerable<object> things) {
+            int result = 0;
+            using (var conn = OpenConnection()) {
+                using (var tx = conn.BeginTransaction()) {
+                    foreach (var item in things) {
+                        var pk = GetPrimaryKey(item);
+                        if (pk == null)
+                            throw new InvalidOperationException("Please be sure to set a value for the primary key");
+                        if (BeforeUpdate(item)) {
+                            using (var cmd = CreateUpdateCommand(item, pk)) {
+                                cmd.Connection = conn;
+                                cmd.Transaction = tx;
+                                cmd.ExecuteNonQuery();
+                            }
+                            AfterUpdate(item);
+                        }
+                        result++;
+                    }
+                    tx.Commit();
+                }
+            }
+            return result;
+        }
+        /// <summary>
+        /// If you're feeling lazy, or are just unsure about whether to use Update or Insert you can use
+        /// this method. It will look for a PrimaryKeyField with a set value to determine if this should
+        /// be an Insert or Save. You can pass in an Anonymous object, an ExpandoObject,
+        /// A regular old POCO, or a NameValueColletion from a Request.Form or Request.QueryString
+        /// </summary>
+        public dynamic Save(object o) {
+            dynamic result = 0;
+            if (BeforeSave(o)) {
+                var expando = o.ToExpando();
+                //decide insert or update
+                result = HasPrimaryKey(expando) ? Update(expando, GetPrimaryKey(o)) : Insert(expando);
+                AfterSave(o);
+            }
+            return result;
+        }
+        /// <summary>
+        /// Removes a record from the database
+        /// </summary>
+        public int Delete(object key) {
+            //execute
+            var sql = string.Format("DELETE FROM {0} WHERE {1} = @0", TableName, PrimaryKeyField);
+            var result = 0;
+            using (var conn = OpenConnection()) {
+                using (var cmd = CreateCommand(sql, key)) {
+                    cmd.Connection = conn;
+                    result = cmd.ExecuteNonQuery();
+                }
+            }
+            return result;
+        }
+        /// <summary>
+        /// Removes one or more records from the DB according to the passed-in WHERE
+        /// </summary>
+        public dynamic Delete(string where, params object[] args) {
+            //execute
+            var sql = string.Format("DELETE FROM {0} ", TableName);
+            sql += where.Trim().StartsWith("where", StringComparison.CurrentCultureIgnoreCase) ? where : "WHERE " + where;
+            var result = 0;
+            using (var conn = OpenConnection()) {
+                using (var cmd = CreateCommand(sql, args)) {
+                    cmd.Connection = conn;
+                    result = cmd.ExecuteNonQuery();
+                }
+            }
+            return result;
+        }
+        /// <summary>
+        /// Returns all records complying with the passed-in WHERE clause and arguments, 
+        /// ordered as specified, limited (TOP) by limit.
+        /// </summary>
+        public IEnumerable<dynamic> All(string where = "", string orderBy = "", int limit = 0, params object[] args) {
+            string sql = limit > 0 ? "SELECT TOP " + limit + " * FROM {0} " : "SELECT * FROM {0} ";
+            if (!string.IsNullOrEmpty(where))
+                sql += where.Trim().StartsWith("where", StringComparison.CurrentCultureIgnoreCase) ? where : "WHERE " + where;
+            if (!String.IsNullOrEmpty(orderBy))
+                sql += orderBy.Trim().StartsWith("order by", StringComparison.CurrentCultureIgnoreCase) ? orderBy : " ORDER BY " + orderBy;
+            return Query(string.Format(sql, TableName), args);
+        }
+        /// <summary>
+        /// Returns a single row from the database
+        /// </summary>
+        /// <returns>ExpandoObject</returns>
+        public dynamic Single(object key) {
+            var sql = string.Format("SELECT * FROM {0} WHERE {1} = @0", TableName, PrimaryKeyField);
+            return Query(sql, key).FirstOrDefault();
+        }
+        #region hooks
+        //hooks for save routines
+        public virtual bool BeforeInsert(object o) { return true; }
+        public virtual bool BeforeUpdate(object o) { return true; }
+        public virtual bool BeforeSave(object o) { return true; }
+        public virtual bool BeforeDelete(object key) { return true; }
+        public virtual void AfterInsert(object o) { }
+        public virtual void AfterUpdate(object o) { }
+        public virtual void AfterSave(object o) { }
+        public virtual void AfterDelete(object key) { }
+        #endregion
+    }
+}
\ No newline at end of file
diff --git a/trunk/packages/repositories.config b/trunk/packages/repositories.config
new file mode 100644 (file)
index 0000000..46c3084
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<repositories>
+  <repository path="..\Pithos.Client\packages.config" />
+  <repository path="..\Pithos.Network\packages.config" />
+</repositories>
\ No newline at end of file
diff --git a/trunk/pithos.snk b/trunk/pithos.snk
new file mode 100644 (file)
index 0000000..2069d32
Binary files /dev/null and b/trunk/pithos.snk differ