Merge pull request #266 from joncham/bug-struct-pack-size
authorZoltan Varga <vargaz@gmail.com>
Thu, 29 Mar 2012 17:13:16 +0000 (10:13 -0700)
committerZoltan Varga <vargaz@gmail.com>
Thu, 29 Mar 2012 17:13:16 +0000 (10:13 -0700)
Raise TypeLoadException for invalid StructLayout Pack size rather than a...

444 files changed:
.gitmodules [new file with mode: 0644]
LICENSE
Makefile.am
configure.in
external/Newtonsoft.Json [new submodule]
external/aspnetwebstack [new submodule]
mcs/.gitignore
mcs/class/Makefile
mcs/class/Mono.Security/Test/Mono.Security.Protocol.Ntlm/Type3MessageTest.cs
mcs/class/Mono.Security/Test/Mono.Security.X509/X509CertificateTest.cs
mcs/class/Mono.Security/Test/Mono.Security.X509/X509CrlTest.cs
mcs/class/Newtonsoft.Json/Makefile [new file with mode: 0644]
mcs/class/Newtonsoft.Json/Newtonsoft.Json.dll.sources [new file with mode: 0644]
mcs/class/System.Json-new/Assembly/AssemblyInfo.cs [deleted file]
mcs/class/System.Json-new/Assembly/ChangeLog [deleted file]
mcs/class/System.Json-new/Extensions/JsonValueExtensions.cs [deleted file]
mcs/class/System.Json-new/GlobalSuppressions.cs [deleted file]
mcs/class/System.Json-new/JXmlToJsonValueConverter.cs [deleted file]
mcs/class/System.Json-new/JsonArray.cs [deleted file]
mcs/class/System.Json-new/JsonObject.cs [deleted file]
mcs/class/System.Json-new/JsonPrimitive.cs [deleted file]
mcs/class/System.Json-new/JsonType.cs [deleted file]
mcs/class/System.Json-new/JsonValue.cs [deleted file]
mcs/class/System.Json-new/JsonValueChange.cs [deleted file]
mcs/class/System.Json-new/JsonValueChangeEventArgs.cs [deleted file]
mcs/class/System.Json-new/JsonValueDynamicMetaObject.cs [deleted file]
mcs/class/System.Json-new/JsonValueLinqExtensions.cs [deleted file]
mcs/class/System.Json-new/LICENSE [deleted file]
mcs/class/System.Json-new/Makefile [deleted file]
mcs/class/System.Json-new/NGenWrapper.cs [deleted file]
mcs/class/System.Json-new/Properties/AssemblyInfo.cs [deleted file]
mcs/class/System.Json-new/Properties/Resources.Designer.cs [deleted file]
mcs/class/System.Json-new/Properties/Resources.resources [deleted file]
mcs/class/System.Json-new/Properties/Resources.resx [deleted file]
mcs/class/System.Json-new/README.porting [deleted file]
mcs/class/System.Json-new/RS.cs [deleted file]
mcs/class/System.Json-new/Settings.StyleCop [deleted file]
mcs/class/System.Json-new/System.Json.csproj [deleted file]
mcs/class/System.Json-new/System.Json.dll.sources [deleted file]
mcs/class/System.Json-new/System.Json_test.dll.sources [deleted file]
mcs/class/System.Json/Assembly/AssemblyInfo.cs
mcs/class/System.Json/Makefile
mcs/class/System.Json/System.Json.dll.sources
mcs/class/System.Json/System.Json/ChangeLog [deleted file]
mcs/class/System.Json/System.Json/JsonArray.cs [deleted file]
mcs/class/System.Json/System.Json/JsonObject.cs [deleted file]
mcs/class/System.Json/System.Json/JsonPrimitive.cs [deleted file]
mcs/class/System.Json/System.Json/JsonType.cs [deleted file]
mcs/class/System.Json/System.Json/JsonValue.cs [deleted file]
mcs/class/System.Net.Http.Formatting/Extensions.cs [new file with mode: 0644]
mcs/class/System.Net.Http.Formatting/Makefile [new file with mode: 0644]
mcs/class/System.Net.Http.Formatting/System.Net.Http.Formatting.dll.sources [new file with mode: 0644]
mcs/class/System.Net.Http/System.Net.Http.Headers/ContentDispositionHeaderValue.cs [new file with mode: 0644]
mcs/class/System.Net.Http/System.Net.Http.Headers/HttpContentHeaders.cs
mcs/class/System.Net.Http/System.Net.Http.dll.sources
mcs/class/System.Net.Http/System.Net.Http/DelegatingHandler.cs [new file with mode: 0644]
mcs/class/System.Net.Http/System.Net.Http/HttpContent.cs
mcs/class/System.ServiceModel/Makefile
mcs/class/System.Web.Http/Makefile [new file with mode: 0644]
mcs/class/System.Web.Http/System.Web.Http.dll.sources [new file with mode: 0644]
mcs/class/System.Web.Mvc3/GlobalSuppressions.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Makefile [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/AcceptVerbsAttribute.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ActionDescriptor.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ActionExecutedContext.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ActionExecutingContext.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ActionFilterAttribute.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ActionMethodDispatcher.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ActionMethodDispatcherCache.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ActionMethodSelector.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ActionMethodSelectorAttribute.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ActionNameAttribute.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ActionNameSelectorAttribute.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ActionResult.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ActionSelector.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/AdditionalMetaDataAttribute.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Ajax/AjaxExtensions.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Ajax/AjaxOptions.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Ajax/InsertionMode.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/AjaxHelper.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/AjaxHelper`1.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/AjaxRequestExtensions.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/AllowHtmlAttribute.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/AreaHelpers.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/AreaRegistration.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/AreaRegistrationContext.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/AssociatedMetadataProvider.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/AssociatedValidatorProvider.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Async/ActionDescriptorCreator.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Async/AsyncActionDescriptor.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Async/AsyncActionMethodSelector.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Async/AsyncControllerActionInvoker.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Async/AsyncManager.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Async/AsyncResultWrapper.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Async/AsyncUtil.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Async/AsyncVoid.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Async/BeginInvokeDelegate.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Async/EndInvokeDelegate.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Async/EndInvokeDelegate`1.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Async/IAsyncActionInvoker.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Async/IAsyncController.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Async/IAsyncManagerContainer.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Async/OperationCounter.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Async/ReflectedAsyncActionDescriptor.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Async/ReflectedAsyncControllerDescriptor.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Async/SimpleAsyncResult.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Async/SingleEntryGate.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Async/SynchronizationContextUtil.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Async/SynchronousOperationException.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Async/Trigger.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Async/TriggerListener.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/AsyncController.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/AsyncTimeoutAttribute.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/AuthorizationContext.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/AuthorizeAttribute.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/BindAttribute.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/BuildManagerCompiledView.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/BuildManagerViewEngine.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/BuildManagerWrapper.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ByteArrayModelBinder.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ChildActionOnlyAttribute.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ChildActionValueProvider.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ChildActionValueProviderFactory.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ClientDataTypeModelValidatorProvider.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/CompareAttribute.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ContentResult.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Controller.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ControllerActionInvoker.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ControllerBase.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ControllerBuilder.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ControllerContext.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ControllerDescriptor.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ControllerDescriptorCache.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ControllerInstanceFilterProvider.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ControllerTypeCache.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/CustomModelBinderAttribute.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/DataAnnotationsModelMetadata.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/DataAnnotationsModelMetadataProvider.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/DataAnnotationsModelValidator.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/DataAnnotationsModelValidatorProvider.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/DataAnnotationsModelValidator`1.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/DataErrorInfoModelValidatorProvider.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/DataTypeUtil.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/DefaultControllerFactory.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/DefaultModelBinder.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/DefaultViewLocationCache.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/DependencyResolver.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/DependencyResolverExtensions.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/DescriptorUtil.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/DictionaryHelpers.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/DictionaryValueProvider`1.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/DynamicViewDataDictionary.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/EmptyModelMetadataProvider.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/EmptyModelValidatorProvider.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/EmptyResult.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Error.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ExceptionContext.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ExpressionHelper.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/BinaryExpressionFingerprint.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/CachedExpressionCompiler.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/ConditionalExpressionFingerprint.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/ConstantExpressionFingerprint.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/DefaultExpressionFingerprint.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/ExpressionFingerprint.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/ExpressionFingerprintChain.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/FingerprintingExpressionVisitor.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/HashCodeCombiner.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/Hoisted`2.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/HoistingExpressionVisitor.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/IndexExpressionFingerprint.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/LambdaExpressionFingerprint.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/MemberExpressionFingerprint.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/MethodCallExpressionFingerprint.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/ParameterExpressionFingerprint.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/TypeBinaryExpressionFingerprint.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/UnaryExpressionFingerprint.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/FieldValidationMetadata.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/FileContentResult.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/FilePathResult.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/FileResult.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/FileStreamResult.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Filter.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/FilterAttribute.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/FilterAttributeFilterProvider.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/FilterInfo.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/FilterProviderCollection.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/FilterProviders.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/FilterScope.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/FormCollection.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/FormContext.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/FormMethod.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/FormValueProvider.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/FormValueProviderFactory.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/GlobalFilterCollection.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/GlobalFilters.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/HandleErrorAttribute.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/HandleErrorInfo.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/HiddenInputAttribute.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Html/ChildActionExtensions.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Html/DefaultDisplayTemplates.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Html/DefaultEditorTemplates.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Html/DisplayExtensions.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Html/DisplayTextExtensions.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Html/EditorExtensions.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Html/FormExtensions.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Html/InputExtensions.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Html/LabelExtensions.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Html/LinkExtensions.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Html/MvcForm.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Html/PartialExtensions.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Html/RenderPartialExtensions.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Html/SelectExtensions.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Html/TemplateHelpers.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Html/TextAreaExtensions.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Html/ValidationExtensions.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/HtmlHelper.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/HtmlHelper`1.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/HttpDeleteAttribute.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/HttpFileCollectionValueProvider.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/HttpFileCollectionValueProviderFactory.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/HttpGetAttribute.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/HttpHandlerUtil.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/HttpNotFoundResult.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/HttpPostAttribute.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/HttpPostedFileBaseModelBinder.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/HttpPutAttribute.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/HttpRequestExtensions.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/HttpStatusCodeResult.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/HttpUnauthorizedResult.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/HttpVerbs.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/IActionFilter.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/IActionInvoker.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/IAuthorizationFilter.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/IBuildManager.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/IClientValidatable.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/IController.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/IControllerActivator.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/IControllerFactory.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/IDependencyResolver.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/IExceptionFilter.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/IFilterProvider.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/IMetadataAware.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/IModelBinder.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/IModelBinderProvider.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/IMvcControlBuilder.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/IMvcFilter.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/IResolver.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/IResultFilter.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/IRouteWithArea.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ITempDataProvider.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/IUniquelyIdentifiable.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/IUnvalidatedRequestValues.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/IUnvalidatedValueProvider.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/IValueProvider.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/IView.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/IViewDataContainer.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/IViewEngine.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/IViewLocationCache.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/IViewPageActivator.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/IViewStartPageChild.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/InputType.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/JavaScriptResult.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/JsonRequestBehavior.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/JsonResult.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/JsonValueProviderFactory.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/LinqBinaryModelBinder.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ModelBinderAttribute.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ModelBinderDictionary.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ModelBinderProviderCollection.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ModelBinderProviders.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ModelBinders.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ModelBindingContext.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ModelClientValidationEqualToRule.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ModelClientValidationRangeRule.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ModelClientValidationRegexRule.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ModelClientValidationRemoteRule.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ModelClientValidationRequiredRule.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ModelClientValidationRule.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ModelClientValidationStringLengthRule.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ModelError.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ModelErrorCollection.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ModelMetadata.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ModelMetadataProvider.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ModelMetadataProviders.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ModelState.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ModelStateDictionary.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ModelValidationResult.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ModelValidator.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ModelValidatorProvider.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ModelValidatorProviderCollection.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ModelValidatorProviders.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/MultiSelectList.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/MultiServiceResolver.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/MvcFilter.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/MvcHandler.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/MvcHtmlString.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/MvcHttpHandler.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/MvcRouteHandler.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/MvcWebRazorHostFactory.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/NameValueCollectionExtensions.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/NameValueCollectionValueProvider.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/NoAsyncTimeoutAttribute.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/NonActionAttribute.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/NullViewLocationCache.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/OutputCacheAttribute.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ParameterBindingInfo.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ParameterDescriptor.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ParameterInfoUtil.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/PartialViewResult.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/PathHelpers.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/PreApplicationStartCode.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/QueryStringValueProvider.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/QueryStringValueProviderFactory.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/RangeAttributeAdapter.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Razor/ModelSpan.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Razor/MvcCSharpRazorCodeGenerator.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Razor/MvcCSharpRazorCodeParser.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Razor/MvcVBRazorCodeGenerator.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Razor/MvcVBRazorCodeParser.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Razor/MvcWebPageRazorHost.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Razor/SetModelTypeCodeGenerator.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Razor/StartPageLookupDelegate.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/RazorView.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/RazorViewEngine.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ReaderWriterCache`2.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/RedirectResult.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/RedirectToRouteResult.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ReflectedActionDescriptor.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ReflectedAttributeCache.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ReflectedControllerDescriptor.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ReflectedParameterBindingInfo.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ReflectedParameterDescriptor.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/RegularExpressionAttributeAdapter.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/RemoteAttribute.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/RequireHttpsAttribute.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/RequiredAttributeAdapter.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Resources/MvcResources.Designer.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/Resources/MvcResources.resx [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ResultExecutedContext.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ResultExecutingContext.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/RouteCollectionExtensions.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/RouteDataValueProvider.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/RouteDataValueProviderFactory.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/RouteValuesHelpers.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/SecurityUtil.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/SelectList.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/SelectListItem.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/SessionStateAttribute.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/SessionStateTempDataProvider.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/SingleServiceResolver.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/StringLengthAttributeAdapter.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/TagBuilderExtensions.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/TempDataDictionary.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/TemplateInfo.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/TryGetValueDelegate.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/TypeCacheSerializer.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/TypeCacheUtil.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/TypeDescriptorHelper.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/TypeHelpers.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/UnvalidatedRequestValuesAccessor.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/UnvalidatedRequestValuesWrapper.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/UrlHelper.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/UrlParameter.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/UrlRewriterHelper.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ValidatableObjectAdapter.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ValidateAntiForgeryTokenAttribute.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ValidateInputAttribute.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ValueProviderCollection.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ValueProviderDictionary.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ValueProviderFactories.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ValueProviderFactory.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ValueProviderFactoryCollection.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ValueProviderResult.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ValueProviderUtil.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ViewContext.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ViewDataDictionary.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ViewDataDictionary`1.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ViewDataInfo.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ViewEngineCollection.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ViewEngineResult.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ViewEngines.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ViewMasterPage.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ViewMasterPageControlBuilder.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ViewMasterPage`1.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ViewPage.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ViewPageControlBuilder.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ViewPage`1.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ViewResult.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ViewResultBase.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ViewStartPage.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ViewTemplateUserControl.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ViewTemplateUserControl`1.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ViewType.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ViewTypeControlBuilder.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ViewTypeParserFilter.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ViewUserControl.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ViewUserControlControlBuilder.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/ViewUserControl`1.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/VirtualPathProviderViewEngine.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/WebFormView.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/WebFormViewEngine.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/WebViewPage.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Mvc/WebViewPage`1.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/Properties/AssemblyInfo.cs [new file with mode: 0644]
mcs/class/System.Web.Mvc3/System.Web.Mvc.csproj [new file with mode: 0644]
mcs/class/System.Web.Mvc3/System.Web.Mvc3.dll.sources [new file with mode: 0644]
mcs/class/System.Web.Razor/Assembly/AssemblyInfo.cs [new file with mode: 0644]
mcs/class/System.Web.Razor/Makefile [new file with mode: 0644]
mcs/class/System.Web.Razor/System.Web.Razor.dll.sources [new file with mode: 0644]
mcs/class/System.Web.WebPages.Deployment/Assembly/AssemblyInfo.cs [new file with mode: 0644]
mcs/class/System.Web.WebPages.Deployment/Makefile [new file with mode: 0644]
mcs/class/System.Web.WebPages.Deployment/System.Web.WebPages.Deployment.dll.sources [new file with mode: 0644]
mcs/class/System.Web.WebPages.Razor/Assembly/AssemblyInfo.cs [new file with mode: 0644]
mcs/class/System.Web.WebPages.Razor/Makefile [new file with mode: 0644]
mcs/class/System.Web.WebPages.Razor/System.Web.WebPages.Razor.dll.sources [new file with mode: 0644]
mcs/class/System.Web.WebPages/Assembly/AssemblyInfo.cs [new file with mode: 0644]
mcs/class/System.Web.WebPages/Makefile [new file with mode: 0644]
mcs/class/System.Web.WebPages/System.Web.WebPages.dll.sources [new file with mode: 0644]
mcs/class/System.Web/Makefile
mcs/class/System.XML/Makefile
mcs/class/System/System.Diagnostics/DefaultTraceListener.cs
mcs/class/System/System.Diagnostics/TraceImpl.cs
mcs/class/System/System.Diagnostics/TraceListener.cs
mcs/class/System/System.Diagnostics/TraceListenerCollection.cs
mcs/class/System/mobile_System.dll.sources
mcs/class/corlib/Makefile
mcs/class/corlib/System.IO/LogcatTextWriter.cs
mcs/mcs/anonymous.cs
mcs/mcs/async.cs
mcs/mcs/doc.cs
mcs/mcs/statement.cs
mcs/tests/test-debug-19-ref.xml
mcs/tests/test-xml-066-ref.xml [new file with mode: 0644]
mcs/tests/test-xml-066.cs [new file with mode: 0644]
mcs/tests/ver-il-net_4_5.xml
mono-core.spec.in
mono/metadata/metadata.c
mono/metadata/object.c
mono/metadata/sgen-fin-weak-hash.c
mono/metadata/sgen-gc.c
mono/metadata/sgen-nursery-allocator.c
mono/mini/debugger-agent.c
mono/mini/driver.c
mono/tests/libtest.c

diff --git a/.gitmodules b/.gitmodules
new file mode 100644 (file)
index 0000000..4f2410a
--- /dev/null
@@ -0,0 +1,6 @@
+[submodule "external/aspnetwebstack"]
+       path = external/aspnetwebstack
+       url = git://github.com/mono/aspnetwebstack.git
+[submodule "external/Newtonsoft.Json"]
+       path = external/Newtonsoft.Json
+       url = git://github.com/mono/Newtonsoft.Json.git
diff --git a/LICENSE b/LICENSE
index f8b52eb4f7f3c13d6ec88940bc75fd5d83466de6..0c52cc7dc9580339505658e89441c8d48e7cdf82 100644 (file)
--- a/LICENSE
+++ b/LICENSE
@@ -8,8 +8,8 @@ For comments, corrections and updates, please contact mono@xamarin.com
 
        Parts of Mono are dual licensed, they are available to the
        public in GPL or LGPL forms, but we also offer those pieces
-       under commercial terms from Novell for when the GPL and the
-       LGPL are not suitable.
+       under commercial terms from Xamarin for the cases wher the GPL
+       and the LGPL are not suitable.
 
        We have tried to pick the licenses that will maximize adoption
        of Mono, so we tend to use the MIT X11 or LGPL liceses.
@@ -22,6 +22,9 @@ For comments, corrections and updates, please contact mono@xamarin.com
        Contributions for other modules should be under the same license
        terms as the rest of the module, or under MIT X11 terms. 
 
+       For the actual license links in the Mono distribution see the
+       bottom of this file.
+
        If you need further information, please contact mono@xamarin.com
 
 * The Modules
@@ -31,7 +34,7 @@ For comments, corrections and updates, please contact mono@xamarin.com
        This code is dual licensed under the LGPL or commercial licenses. 
 
        The LGPL ensures that Mono can be used in most scenarios, but
-       gives Novell the flexibility to relicense the code for
+       gives Xamarin the flexibility to relicense the code for
        embedded systems, static linking or commercial settings where
        the LGPL can not be used.
 
@@ -39,7 +42,7 @@ For comments, corrections and updates, please contact mono@xamarin.com
        embedded system where the end user is not able to upgrade the
        Mono VM or Moonlight installation or distribution that is part
        of your product (Section 6 and 7), you would have to obtain a
-       commercial license from Novell (consider software burned into
+       commercial license from Xamarin (consider software burned into
        a ROM, systems where end users would not be able to upgrade,
        an embedded console, a game console that imposes limitations
        on the distribution and access to the code, a phone platform
index a68090098d93a27963c56aeeac3d71ef4a96aa6c..ed2ee3784a1f3c956417f384c8f8d569bb703df3 100644 (file)
@@ -25,7 +25,8 @@ EXTRA_DIST= \
            mkinstalldirs \
            mono-uninstalled.pc.in \
            winconfig.h \
-           mono-core.spec
+           mono-core.spec \
+           external
 
 DISTCHECK_CONFIGURE_FLAGS = EXTERNAL_MCS=false EXTERNAL_RUNTIME=false
 
index 8f96073379e7d55fcdb50f442677ec631620e7e1..5895fcb87c27486b8aead73bafeac55c102c2bec 100644 (file)
@@ -3147,6 +3147,11 @@ msvc/Makefile
 po/Makefile
 ])
 
+# Update all sub-modules recursively to ensure everything is checked out
+if test -d .git; then
+       git submodule update --init --recursive
+fi
+
 if test x$host_win32 = xyes; then
    # Get rid of 'cyg' prefixes in library names
    sed -e "s/\/cyg\//\/\//" libtool > libtool.new; mv libtool.new libtool; chmod 755 libtool
diff --git a/external/Newtonsoft.Json b/external/Newtonsoft.Json
new file mode 160000 (submodule)
index 0000000..471c3e0
--- /dev/null
@@ -0,0 +1 @@
+Subproject commit 471c3e0803a9f40a0acc8aeceb31de6ff93a52c4
diff --git a/external/aspnetwebstack b/external/aspnetwebstack
new file mode 160000 (submodule)
index 0000000..e0c13f3
--- /dev/null
@@ -0,0 +1 @@
+Subproject commit e0c13f388a36830888efaf9979634b4051901cce
index 76cdc5efbad87eafc5cf6c0261f812b6e8e64b40..404aa14ef19436d698ad8a398d3beafdcd632ea6 100644 (file)
@@ -6,6 +6,7 @@
 *_test_*.dll.config
 *_test_*.xml
 *.o
+*.resources
 TestResult-*.log
 TestResult-*.xml
 TestResult*.xml
index 0f2b9f949faac93b2a2a89747d57ef239e8dd566..bfc17fc7e60e0cfe4c65a1ffe810bf9e2765fac1 100644 (file)
@@ -179,7 +179,6 @@ net_4_0_dirs := \
        System.ServiceModel.Discovery \
        System.Runtime.Caching \
        System.Runtime.DurableInstancing \
-       Mono.CodeContracts \
        Mono.Parallel \
        Microsoft.Web.Infrastructure \
        WebMatrix.Data \
@@ -193,7 +192,16 @@ net_4_0_only_dirs := \
 net_4_5_dirs := \
        System.Threading.Tasks.Dataflow \
        System.ComponentModel.Composition.4.5 \
-       System.Net.Http
+       System.Net.Http \
+       System.Web.Razor \
+       System.Web.WebPages.Deployment \
+       System.Web.WebPages \
+       System.Web.WebPages.Razor \
+       System.Web.Mvc3 \
+       Newtonsoft.Json \
+       System.Net.Http.Formatting \
+       System.Web.Http \
+       Mono.CodeContracts
 
 net_2_0_SUBDIRS := $(common_dirs) $(net_2_0_dirs) $(net_2_0_only_dirs) aot-compiler
 moonlight_raw_SUBDIRS := $(moonlight_raw_dirs)
index 9aeeec781b5e05f0470c16c504c201d503c48c76..79bc2d9ca281c83f923810ab907c27c1bdef7382 100644 (file)
@@ -35,7 +35,7 @@ namespace MonoTests.Mono.Security.Protocol.Ntlm {
                        msg.Password = "WELCOME";
                        msg.Username = "username";
                        AssertEquals ("Type", 3, msg.Type);
-                       AssertEquals ("GetBytes", "4E-54-4C-4D-53-53-50-00-03-00-00-00-18-00-18-00-64-00-00-00-18-00-18-00-7C-00-00-00-0C-00-0C-00-40-00-00-00-10-00-10-00-4C-00-00-00-08-00-08-00-5C-00-00-00-00-00-00-00-94-00-00-00-01-82-00-00-44-00-4F-00-4D-00-41-00-49-00-4E-00-75-00-73-00-65-00-72-00-6E-00-61-00-6D-00-65-00-48-00-4F-00-53-00-54-00-CA-12-00-72-3C-41-D5-77-AB-18-C7-64-C6-DE-F3-4F-A6-1B-FA-06-71-EA-5F-C8-7A-CE-90-85-AB-CC-37-59-38-0B-1C-68-62-E3-98-C3-C0-EF-9C-FC-22-E8-A2-C2", BitConverter.ToString (msg.GetBytes ()));
+                       AssertEquals ("GetBytes", "4E-54-4C-4D-53-53-50-00-03-00-00-00-18-00-18-00-64-00-00-00-18-00-18-00-7C-00-00-00-0C-00-0C-00-40-00-00-00-10-00-10-00-4C-00-00-00-08-00-08-00-5C-00-00-00-00-00-00-00-94-00-00-00-01-B2-00-00-44-00-4F-00-4D-00-41-00-49-00-4E-00-75-00-73-00-65-00-72-00-6E-00-61-00-6D-00-65-00-48-00-4F-00-53-00-54-00-CA-12-00-72-3C-41-D5-77-AB-18-C7-64-C6-DE-F3-4F-A6-1B-FA-06-71-EA-5F-C8-7A-CE-90-85-AB-CC-37-59-38-0B-1C-68-62-E3-98-C3-C0-EF-9C-FC-22-E8-A2-C2", BitConverter.ToString (msg.GetBytes ()));
                }
 
                [Test]
@@ -49,7 +49,7 @@ namespace MonoTests.Mono.Security.Protocol.Ntlm {
                        msg.Password = "Beeblebrox";
                        msg.Username = "Zaphod";
                        AssertEquals ("Type", 3, msg.Type);
-                       AssertEquals ("GetBytes", "4E-54-4C-4D-53-53-50-00-03-00-00-00-18-00-18-00-72-00-00-00-18-00-18-00-8A-00-00-00-14-00-14-00-40-00-00-00-0C-00-0C-00-54-00-00-00-12-00-12-00-60-00-00-00-00-00-00-00-A2-00-00-00-01-82-00-00-55-00-52-00-53-00-41-00-2D-00-4D-00-49-00-4E-00-4F-00-52-00-5A-00-61-00-70-00-68-00-6F-00-64-00-4C-00-49-00-47-00-48-00-54-00-43-00-49-00-54-00-59-00-AD-87-CA-6D-EF-E3-46-85-B9-C4-3C-47-7A-8C-42-D6-00-66-7D-68-92-E7-E8-97-E0-E0-0D-E3-10-4A-1B-F2-05-3F-07-C7-DD-A8-2D-3C-48-9A-E9-89-E1-B0-00-D3", BitConverter.ToString (msg.GetBytes ()));
+                       AssertEquals ("GetBytes", "4E-54-4C-4D-53-53-50-00-03-00-00-00-18-00-18-00-72-00-00-00-18-00-18-00-8A-00-00-00-14-00-14-00-40-00-00-00-0C-00-0C-00-54-00-00-00-12-00-12-00-60-00-00-00-00-00-00-00-A2-00-00-00-01-B2-00-00-55-00-52-00-53-00-41-00-2D-00-4D-00-49-00-4E-00-4F-00-52-00-5A-00-61-00-70-00-68-00-6F-00-64-00-4C-00-49-00-47-00-48-00-54-00-43-00-49-00-54-00-59-00-AD-87-CA-6D-EF-E3-46-85-B9-C4-3C-47-7A-8C-42-D6-00-66-7D-68-92-E7-E8-97-E0-E0-0D-E3-10-4A-1B-F2-05-3F-07-C7-DD-A8-2D-3C-48-9A-E9-89-E1-B0-00-D3", BitConverter.ToString (msg.GetBytes ()));
                }
 
                [Test]
index 4370faccf84d841b0ab7c90b2cb45f80127464fc..caa8cf9b22fd4bd1023a8a16331173cf150cd18a 100644 (file)
@@ -107,7 +107,7 @@ namespace MonoTests.Mono.Security.X509 {
                        Assert.AreEqual ("<DSAKeyValue><P>3+URPtrptm4Q1uqd4p06sEe9RADHVsjMbtAzhFZHNT32VMjjwq27unXzLzMMpvkx7Gfj5Zlt/CluqleIcjTijgCQ4KOsZI7A9jwdj7TISkgwXn+qnHYmC9sTczODl8DFs+Y39T7/FQ3UoS66Mfirh9gLzHeYQm6sk5jCvS57NAs=</P><Q>zwYE2P+L6wDp9lwHlnP9lmU6Lwc=</Q><G>zOF8sM6SX2PsOLtEut2SNLZevmV72HF3BJ3sZnw7BM6281L+D5JVAu9OEqtdmi4vblbzcOxq7ZsiuKgTywycFurBCo4hJkSlDPmg7GLgcDHMaPULhaRKG2559MH5Nlo4b07vhFPfZ/3M91lij5yczRCPXKQPnLcH7GDzvq9+OZg=</G><Y>EfK52L5CK8WEvpECHPyMMnKLqGwh14iKFLowZXXAHD2CaWWnrJB6FB2Fe+VTwmD8sc9nr8HyLggyajjHkU47vDwJ0PlxbQjfJ0mNBXTYvUbQ21GlU7qH8/pdJYNPfwp15anjiadBd2NAXysshNLBcXgK22tXGeHnFAyexPYyOQ4=</Y></DSAKeyValue>", ca.DSA.ToXmlString (false), "DSA");
                        Assert.AreEqual (5, ca.Extensions.Count, "Extensions");
                        Assert.AreEqual ("20-98-19-23-3C-FC-D9-C9-02-BA-BE-C6-42-BF-87-15-54-A1-7A-39", BitConverter.ToString (ca.Hash), "Hash");
-                       Assert.IsTrue (ca.IsCurrent, "IsCurrent"); // true until 2011
+                       Assert.IsFalse (ca.IsCurrent, "IsCurrent"); // true until 2011
                        Assert.IsFalse (ca.IsSelfSigned, "IsSelfSigned");
                        Assert.AreEqual ("C=US, O=Test Certificates, CN=Trust Anchor", ca.IssuerName, "IssuerName");
                        Assert.AreEqual ("1.2.840.10040.4.1", ca.KeyAlgorithm, "KeyAlgorithm");
@@ -131,7 +131,7 @@ namespace MonoTests.Mono.Security.X509 {
                        X509Certificate ca = new X509Certificate (DSAParametersInheritedCACert_crt);
                        Assert.AreEqual (5, ca.Extensions.Count, "Extensions");
                        Assert.AreEqual ("F5-F0-0D-21-1E-87-B9-F6-E1-85-AB-04-5F-43-2A-FD-EA-96-BC-D9", BitConverter.ToString (ca.Hash), "Hash");
-                       Assert.IsTrue (ca.IsCurrent, "IsCurrent"); // true until 2011
+                       Assert.IsFalse (ca.IsCurrent, "IsCurrent"); // true until 2011
                        Assert.IsFalse (ca.IsSelfSigned, "IsSelfSigned");
                        Assert.AreEqual ("C=US, O=Test Certificates, CN=DSA CA", ca.IssuerName, "IssuerName");
                        Assert.AreEqual ("1.2.840.10040.4.1", ca.KeyAlgorithm, "KeyAlgorithm");
index ca1e5d46db1ac4fd074ce7d68b3edce13303455e..97a65bee7a5b8b36b358ce08ef9db4d6d2bc7d90 100644 (file)
@@ -71,7 +71,7 @@ namespace MonoTests.Mono.Security.X509 {
                        X509Crl crl = new X509Crl (basicConstraintsCriticalcAFalseCACRL_crl);
                        Assert.AreEqual (0, crl.Entries.Count, "Entries.Count");
                        Assert.AreEqual (2, crl.Extensions.Count, "Extensions.Count");
-                       Assert.IsTrue (crl.IsCurrent, "IsCurrent"); // true till 2011
+                       Assert.IsFalse (crl.IsCurrent, "IsCurrent"); // true till 2011
                        Assert.AreEqual ("C=US, O=Test Certificates, CN=basicConstraints Critical cA False CA", crl.IssuerName, "IssuerName");
                        Assert.AreEqual (634388218400000000, crl.NextUpdate.ToUniversalTime ().Ticks, "NextUpdate");
                        Assert.AreEqual ("32-BC-12-1F-84-D0-B6-3E-72-A0-FB-D9-75-99-CA-E5-2A-05-09-E6-C8-27-74-47-1C-DC-0C-D4-9F-BC-9F-B2-62-25-B4-6D-5B-E5-0B-E8-2A-8E-07-EB-3E-6B-C5-1E-9A-D2-14-FD-89-5B-C3-10-BF-19-77-67-0A-33-45-1B-BC-6C-ED-AF-84-30-59-FB-7C-71-95-63-60-31-9B-9B-0A-EA-77-F1-70-F1-B9-2E-D1-A9-04-42-66-94-B9-54-48-DB-44-56-56-1A-57-5A-01-0E-7C-4D-D7-C0-1F-5C-6F-13-F5-A3-57-88-6A-9A-71-CD-D5-AE-C3-00-B1-28", BitConverter.ToString (crl.Signature), "Signature");
diff --git a/mcs/class/Newtonsoft.Json/Makefile b/mcs/class/Newtonsoft.Json/Makefile
new file mode 100644 (file)
index 0000000..70442f5
--- /dev/null
@@ -0,0 +1,10 @@
+thisdir = class/Newtonsoft.Json
+SUBDIRS = 
+include ../../build/rules.make
+
+LIBRARY = Newtonsoft.Json.dll
+
+LIB_MCS_FLAGS = -r:System.Core.dll -r:System.dll -r:System.Runtime.Serialization.dll -r:System.Xml.dll -r:System.Xml.Linq.dll -r:System.Data.dll \
+               -d:SIGNED -keyfile:../mono.pub -delaysign
+
+include ../../build/library.make
diff --git a/mcs/class/Newtonsoft.Json/Newtonsoft.Json.dll.sources b/mcs/class/Newtonsoft.Json/Newtonsoft.Json.dll.sources
new file mode 100644 (file)
index 0000000..e1f0967
--- /dev/null
@@ -0,0 +1,156 @@
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonBinaryType.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonBinaryWriter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonReader.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonToken.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonType.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonWriter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Bson/BsonObjectId.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/BinaryConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/DataSetConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/DataTableConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/CustomCreationConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/DateTimeConverterBase.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/EntityKeyMemberConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/ExpandoObjectConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/KeyValuePairConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/BsonObjectIdConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/RegexConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/StringEnumConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/ConstructorHandling.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/VersionConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/DateFormatHandling.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/DateTimeZoneHandling.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Formatting.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConstructorAttribute.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonPosition.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JPropertyKeyedCollection.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicProxy.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JPath.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JRaw.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Required.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonDynamicContract.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonFormatterConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonISerializableContract.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonLinqContract.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonPrimitiveContract.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/DynamicValueProvider.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/ErrorEventArgs.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JPropertyDescriptor.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/DefaultReferenceResolver.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/PreserveReferencesHandling.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/IJsonLineInfo.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonArrayAttribute.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonContainerAttribute.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/DefaultValueHandling.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConverterAttribute.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonObjectAttribute.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonSerializerSettings.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonValidatingReader.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/IJEnumerable.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JTokenEqualityComparer.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/MemberSerialization.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/ObjectCreationHandling.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/IsoDateTimeConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/JavaScriptDateTimeConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonTextReader.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonPropertyAttribute.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonIgnoreAttribute.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonTextWriter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonWriterException.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonReaderException.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConverter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConverterCollection.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonReader.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonConvert.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonSerializationException.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonSerializer.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/Extensions.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JConstructor.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JContainer.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JEnumerable.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JObject.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JArray.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JTokenReader.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JTokenWriter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JToken.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JProperty.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JTokenType.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Linq/JValue.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/Extensions.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaException.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaModel.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaModelBuilder.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaNodeCollection.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaNode.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaResolver.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaWriter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/UndefinedSchemaIdHandling.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/ValidationEventArgs.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/ValidationEventHandler.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/CamelCasePropertyNamesContractResolver.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/DefaultSerializationBinder.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/ErrorContext.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/IContractResolver.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/IValueProvider.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonContract.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonProperty.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonPropertyCollection.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/MissingMemberHandling.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/NullValueHandling.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/ReferenceLoopHandling.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchema.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaBuilder.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaConstants.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaGenerator.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/IReferenceResolver.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Schema/JsonSchemaType.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalBase.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonSerializerProxy.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonStringContract.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/CachedAttributeGetter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/LateBoundMetadataTypeAttribute.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/ReflectionValueProvider.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/OnErrorAttribute.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/Base64Encoder.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicProxyMetaObject.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicUtils.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicWrapper.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DynamicReflectionDelegateFactory.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Serialization/ObjectConstructor.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ILGeneratorExtensions.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ReflectionDelegateFactory.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/LateBoundReflectionDelegateFactory.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/MethodCall.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/StringReference.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ThreadSafeStore.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/TypeNameHandling.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/BidirectionalDictionary.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/CollectionWrapper.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DateTimeUtils.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/DictionaryWrapper.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/EnumUtils.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/EnumValue.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/EnumValues.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/JavaScriptUtils.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonToken.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/JsonWriter.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/StringBuffer.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/CollectionUtils.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ListWrapper.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/MathUtils.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/MiscellaneousUtils.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/StringUtils.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/TypeExtensions.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/Utilities/ValidationUtils.cs
+../../../external/Newtonsoft.Json/Src/Newtonsoft.Json/WriteState.cs
diff --git a/mcs/class/System.Json-new/Assembly/AssemblyInfo.cs b/mcs/class/System.Json-new/Assembly/AssemblyInfo.cs
deleted file mode 100755 (executable)
index b8c49cd..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-//
-// AssemblyInfo.cs
-//
-// Authors:
-//     Marek Safar (marek.safar@gmail.com)
-//
-// Copyright (C) 2007 Novell, Inc (http://www.novell.com)
-//
-// 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.
-//
-
-using System;
-using System.Reflection;
-using System.Resources;
-using System.Security;
-using System.Security.Permissions;
-using System.Diagnostics;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about the System.Json assembly
-
-[assembly: AssemblyTitle ("System.Json.dll")]
-[assembly: AssemblyDescription ("System.Json.dll")]
-[assembly: AssemblyDefaultAlias ("System.Json.dll")]
-
-[assembly: AssemblyCompany (Consts.MonoCompany)]
-[assembly: AssemblyProduct (Consts.MonoProduct)]
-[assembly: AssemblyCopyright (Consts.MonoCopyright)]
-[assembly: AssemblyVersion (Consts.FxVersion)]
-[assembly: SatelliteContractVersion (Consts.FxVersion)]
-[assembly: AssemblyInformationalVersion (Consts.FxFileVersion)]
-[assembly: AssemblyFileVersion (Consts.FxFileVersion)]
-
-[assembly: NeutralResourcesLanguage ("en-US")]
-[assembly: AssemblyDelaySign (true)]
-[assembly: AssemblyKeyFile ("../winfx.pub")]
-
-[assembly: ComVisible (false)]
-
-[assembly: SecurityCritical]
diff --git a/mcs/class/System.Json-new/Assembly/ChangeLog b/mcs/class/System.Json-new/Assembly/ChangeLog
deleted file mode 100755 (executable)
index 1fcfb76..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-2010-03-10  Atsushi Enomoto  <atsushi@ximian.com>
-
-       * AssemblyInfo.cs : use the same pub key in 2.0 (dummy), to ease
-         testing locally.
-
-2008-05-07  Sebastien Pouliot  <sebastien@ximian.com>
-
-       * AssemblyInfo.cs: Remove AssemblyDelaySign(true) since it's
-       not always needed and can be controlled from the Makefile.
-       Adjust public key for System.Windows (InternalsVisibleTo)
-
-2008-04-13  Jb Evain  <jbevain@novell.com>
-
-       * AssemblyInfo.cs: agmono is renamed to Mono.Moonlight.
-       Merged from the Moonlight 2 branch.
-
diff --git a/mcs/class/System.Json-new/Extensions/JsonValueExtensions.cs b/mcs/class/System.Json-new/Extensions/JsonValueExtensions.cs
deleted file mode 100644 (file)
index f4ff3ea..0000000
+++ /dev/null
@@ -1,382 +0,0 @@
-#if NET_4_0 || MONODROID
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Diagnostics.CodeAnalysis;
-using System.Dynamic;
-using System.IO;
-using System.Json;
-using System.Linq.Expressions;
-
-namespace System.Runtime.Serialization.Json
-{
-    /// <summary>
-    /// This class extends the functionality of the <see cref="JsonValue"/> type. 
-    /// </summary>
-    [EditorBrowsable(EditorBrowsableState.Never)]
-    public static class JsonValueExtensions
-    {
-        /// <summary>
-        /// Creates a <see cref="System.Json.JsonValue"/> object based on an arbitrary CLR object.
-        /// </summary>
-        /// <param name="value">The object to be converted to <see cref="System.Json.JsonValue"/>.</param>
-        /// <returns>The <see cref="System.Json.JsonValue"/> which represents the given object.</returns>
-        /// <remarks>The conversion is done through the <see cref="System.Runtime.Serialization.Json.DataContractJsonSerializer"/>;
-        /// the object is first serialized into JSON using the serializer, then parsed into a <see cref="System.Json.JsonValue"/>
-        /// object.</remarks>
-        public static JsonValue CreateFrom(object value)
-        {
-            JsonValue jsonValue = null;
-
-            if (value != null)
-            {
-                jsonValue = value as JsonValue;
-
-                if (jsonValue == null)
-                {
-                    jsonValue = JsonValueExtensions.CreatePrimitive(value);
-
-                    if (jsonValue == null)
-                    {
-                        jsonValue = JsonValueExtensions.CreateFromDynamic(value);
-
-                        if (jsonValue == null)
-                        {
-                            jsonValue = JsonValueExtensions.CreateFromComplex(value);
-                        }
-                    }
-                }
-            }
-
-            return jsonValue;
-        }
-
-        /// <summary>
-        /// Attempts to convert this <see cref="System.Json.JsonValue"/> instance into the type T.
-        /// </summary>
-        /// <typeparam name="T">The type to which the conversion is being performed.</typeparam>
-        /// <param name="jsonValue">The <see cref="JsonValue"/> instance this method extension is to be applied to.</param>
-        /// <param name="valueOfT">An instance of T initialized with this instance, or the default
-        /// value of T, if the conversion cannot be performed.</param>
-        /// <returns>true if this <see cref="System.Json.JsonValue"/> instance can be read as type T; otherwise, false.</returns>
-        public static bool TryReadAsType<T>(this JsonValue jsonValue, out T valueOfT)
-        {
-            if (jsonValue == null)
-            {
-                throw new ArgumentNullException("jsonValue");
-            }
-
-            object value;
-            if (JsonValueExtensions.TryReadAsType(jsonValue, typeof(T), out value))
-            {
-                valueOfT = (T)value;
-                return true;
-            }
-
-            valueOfT = default(T);
-            return false;
-        }
-
-        /// <summary>
-        /// Attempts to convert this <see cref="System.Json.JsonValue"/> instance into the type T.
-        /// </summary>
-        /// <typeparam name="T">The type to which the conversion is being performed.</typeparam>
-        /// <param name="jsonValue">The <see cref="JsonValue"/> instance this method extension is to be applied to.</param>
-        /// <returns>An instance of T initialized with the <see cref="System.Json.JsonValue"/> value
-        /// specified if the conversion.</returns>
-        /// <exception cref="System.NotSupportedException">If this <see cref="System.Json.JsonValue"/> value cannot be
-        /// converted into the type T.</exception>
-        [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter",
-            Justification = "The generic parameter is used to specify the output type")]
-        public static T ReadAsType<T>(this JsonValue jsonValue)
-        {
-            if (jsonValue == null)
-            {
-                throw new ArgumentNullException("jsonValue");
-            }
-
-            return (T)JsonValueExtensions.ReadAsType(jsonValue, typeof(T));
-        }
-
-        /// <summary>
-        /// Attempts to convert this <see cref="System.Json.JsonValue"/> instance into the type T, returning a fallback value
-        /// if the conversion fails.
-        /// </summary>
-        /// <typeparam name="T">The type to which the conversion is being performed.</typeparam>
-        /// <param name="jsonValue">The <see cref="JsonValue"/> instance this method extension is to be applied to.</param>
-        /// <param name="fallback">A fallback value to be retuned in case the conversion cannot be performed.</param>
-        /// <returns>An instance of T initialized with the <see cref="System.Json.JsonValue"/> value
-        /// specified if the conversion succeeds or the specified fallback value if it fails.</returns>
-        public static T ReadAsType<T>(this JsonValue jsonValue, T fallback)
-        {
-            if (jsonValue == null)
-            {
-                throw new ArgumentNullException("jsonValue");
-            }
-
-            T outVal;
-            if (JsonValueExtensions.TryReadAsType<T>(jsonValue, out outVal))
-            {
-                return outVal;
-            }
-
-            return fallback;
-        }
-
-        /// <summary>
-        /// Attempts to convert this <see cref="System.Json.JsonValue"/> instance into an instance of the specified type.
-        /// </summary>
-        /// <param name="jsonValue">The <see cref="JsonValue"/> instance this method extension is to be applied to.</param>
-        /// <param name="type">The type to which the conversion is being performed.</param>
-        /// <returns>An object instance initialized with the <see cref="System.Json.JsonValue"/> value
-        /// specified if the conversion.</returns>
-        /// <exception cref="System.NotSupportedException">If this <see cref="System.Json.JsonValue"/> value cannot be
-        /// converted into the type T.</exception>
-        public static object ReadAsType(this JsonValue jsonValue, Type type)
-        {
-            if (jsonValue == null)
-            {
-                throw new ArgumentNullException("jsonValue");
-            }
-
-            if (type == null)
-            {
-                throw new ArgumentNullException("type");
-            }
-
-            object result;
-            if (JsonValueExtensions.TryReadAsType(jsonValue, type, out result))
-            {
-                return result;
-            }
-
-            throw new NotSupportedException(RS.Format(System.Json.Properties.Resources.CannotReadAsType, jsonValue.GetType().FullName, type.FullName));
-        }
-
-        /// <summary>
-        /// Attempts to convert this <see cref="System.Json.JsonValue"/> instance into an instance of the specified type.
-        /// </summary>
-        /// <param name="jsonValue">The <see cref="JsonValue"/> instance this method extension is to be applied to.</param>
-        /// <param name="type">The type to which the conversion is being performed.</param>
-        /// <param name="value">An object to be initialized with this instance or null if the conversion cannot be performed.</param>
-        /// <returns>true if this <see cref="System.Json.JsonValue"/> instance can be read as the specified type; otherwise, false.</returns>
-        [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate",
-            Justification = "This is the non-generic version of the method.")]
-        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Exception translates to fail.")]
-        public static bool TryReadAsType(this JsonValue jsonValue, Type type, out object value)
-        {
-            if (jsonValue == null)
-            {
-                throw new ArgumentNullException("jsonValue");
-            }
-
-            if (type == null)
-            {
-                throw new ArgumentNullException("type");
-            }
-
-            if (type == typeof(JsonValue) || type == typeof(object))
-            {
-                value = jsonValue;
-                return true;
-            }
-
-            if (type == typeof(object[]) || type == typeof(Dictionary<string, object>))
-            {
-                if (!JsonValueExtensions.CanConvertToClrCollection(jsonValue, type))
-                {
-                    value = null;
-                    return false;
-                }
-            }
-
-            if (jsonValue.TryReadAs(type, out value))
-            {
-                return true;
-            }
-
-            try
-            {
-                using (MemoryStream ms = new MemoryStream())
-                {
-                    jsonValue.Save(ms);
-                    ms.Position = 0;
-                    DataContractJsonSerializer dcjs = new DataContractJsonSerializer(type);
-                    value = dcjs.ReadObject(ms);
-                }
-
-                return true;
-            }
-            catch (Exception)
-            {
-                value = null;
-                return false;
-            }
-        }
-
-        /// <summary>
-        /// Determines whether the specified <see cref="JsonValue"/> instance can be converted to the specified collection <see cref="Type"/>.
-        /// </summary>
-        /// <param name="jsonValue">The instance to be converted.</param>
-        /// <param name="collectionType">The collection type to convert the instance to.</param>
-        /// <returns>true if the instance can be converted, false otherwise</returns>
-        private static bool CanConvertToClrCollection(JsonValue jsonValue, Type collectionType)
-        {
-            if (jsonValue != null)
-            {
-                return (jsonValue.JsonType == JsonType.Object && collectionType == typeof(Dictionary<string, object>)) ||
-                       (jsonValue.JsonType == JsonType.Array && collectionType == typeof(object[]));
-            }
-
-            return false;
-        }
-
-        private static JsonValue CreatePrimitive(object value)
-        {
-            JsonPrimitive jsonPrimitive;
-
-            if (JsonPrimitive.TryCreate(value, out jsonPrimitive))
-            {
-                return jsonPrimitive;
-            }
-
-            return null;
-        }
-
-        private static JsonValue CreateFromComplex(object value)
-        {
-            DataContractJsonSerializer dcjs = new DataContractJsonSerializer(value.GetType());
-            using (MemoryStream ms = new MemoryStream())
-            {
-                dcjs.WriteObject(ms, value);
-                ms.Position = 0;
-                return JsonValue.Load(ms);
-            }
-        }
-
-        [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification = "value is not the same")]
-        private static JsonValue CreateFromDynamic(object value)
-        {
-            JsonObject parent = null;
-            DynamicObject dynObj = value as DynamicObject;
-
-            if (dynObj != null)
-            {
-                parent = new JsonObject();
-                Stack<CreateFromTypeStackInfo> infoStack = new Stack<CreateFromTypeStackInfo>();
-                IEnumerator<string> keys = null;
-
-                do
-                {
-                    if (keys == null)
-                    {
-                        keys = dynObj.GetDynamicMemberNames().GetEnumerator();
-                    }
-
-                    while (keys.MoveNext())
-                    {
-                        JsonValue child = null;
-                        string key = keys.Current;
-                        SimpleGetMemberBinder binder = new SimpleGetMemberBinder(key);
-
-                        if (dynObj.TryGetMember(binder, out value))
-                        {
-                            DynamicObject childDynObj = value as DynamicObject;
-
-                            if (childDynObj != null)
-                            {
-                                child = new JsonObject();
-                                parent.Add(key, child);
-
-                                infoStack.Push(new CreateFromTypeStackInfo(parent, dynObj, keys));
-
-                                parent = child as JsonObject;
-                                dynObj = childDynObj;
-                                keys = null;
-
-                                break;
-                            }
-                            else
-                            {
-                                if (value != null)
-                                {
-                                    child = value as JsonValue;
-
-                                    if (child == null)
-                                    {
-                                        child = JsonValueExtensions.CreatePrimitive(value);
-
-                                        if (child == null)
-                                        {
-                                            child = JsonValueExtensions.CreateFromComplex(value);
-                                        }
-                                    }
-                                }
-
-                                parent.Add(key, child);
-                            }
-                        }
-                    }
-
-                    if (infoStack.Count > 0 && keys != null)
-                    {
-                        CreateFromTypeStackInfo info = infoStack.Pop();
-
-                        parent = info.JsonObject;
-                        dynObj = info.DynamicObject;
-                        keys = info.Keys;
-                    }
-                }
-                while (infoStack.Count > 0);
-            }
-
-            return parent;
-        }
-
-        private class CreateFromTypeStackInfo
-        {
-            public CreateFromTypeStackInfo(JsonObject jsonObject, DynamicObject dynamicObject, IEnumerator<string> keyEnumerator)
-            {
-                JsonObject = jsonObject;
-                DynamicObject = dynamicObject;
-                Keys = keyEnumerator;
-            }
-
-            /// <summary>
-            /// Gets of sets
-            /// </summary>
-            public JsonObject JsonObject { get; set; }
-
-            /// <summary>
-            /// Gets of sets
-            /// </summary>
-            public DynamicObject DynamicObject { get; set; }
-
-            /// <summary>
-            /// Gets of sets
-            /// </summary>
-            public IEnumerator<string> Keys { get; set; }
-        }
-
-        private class SimpleGetMemberBinder : GetMemberBinder
-        {
-            public SimpleGetMemberBinder(string name)
-                : base(name, false)
-            {
-            }
-
-            public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
-            {
-                if (target != null && errorSuggestion == null)
-                {
-                    string exceptionMessage = RS.Format(System.Json.Properties.Resources.DynamicPropertyNotDefined, target.LimitType, Name);
-                    Expression throwExpression = Expression.Throw(Expression.Constant(new InvalidOperationException(exceptionMessage)), typeof(object));
-
-                    errorSuggestion = new DynamicMetaObject(throwExpression, target.Restrictions);
-                }
-
-                return errorSuggestion;
-            }
-        }
-    }
-}
-#endif
diff --git a/mcs/class/System.Json-new/GlobalSuppressions.cs b/mcs/class/System.Json-new/GlobalSuppressions.cs
deleted file mode 100644 (file)
index d0ff21a..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-using System.Diagnostics.CodeAnalysis;
-
-[assembly: SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames", Justification = "These assemblies are delay-signed.")]
-[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Justification = "Classes are grouped logically for user clarity.", Scope = "namespace", Target = "System.Runtime.Serialization.Json")]
diff --git a/mcs/class/System.Json-new/JXmlToJsonValueConverter.cs b/mcs/class/System.Json-new/JXmlToJsonValueConverter.cs
deleted file mode 100644 (file)
index cd3dddb..0000000
+++ /dev/null
@@ -1,302 +0,0 @@
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Runtime.Serialization.Json;
-using System.Text;
-using System.Xml;
-
-namespace System.Json
-{
-    internal static class JXmlToJsonValueConverter
-    {
-        internal const string RootElementName = "root";
-        internal const string ItemElementName = "item";
-        internal const string TypeAttributeName = "type";
-        internal const string ArrayAttributeValue = "array";
-        internal const string BooleanAttributeValue = "boolean";
-        internal const string NullAttributeValue = "null";
-        internal const string NumberAttributeValue = "number";
-        internal const string ObjectAttributeValue = "object";
-        internal const string StringAttributeValue = "string";
-        private const string TypeHintAttributeName = "__type";
-
-        private static readonly char[] _floatingPointChars = new char[] { '.', 'e', 'E' };
-
-        public static JsonValue JXMLToJsonValue(Stream jsonStream)
-        {
-            if (jsonStream == null)
-            {
-                throw new ArgumentNullException("jsonStream");
-            }
-
-            return JXMLToJsonValue(jsonStream, null);
-        }
-
-        public static JsonValue JXMLToJsonValue(string jsonString)
-        {
-            if (jsonString == null)
-            {
-                throw new ArgumentNullException("jsonString");
-            }
-
-            if (jsonString.Length == 0)
-            {
-                throw new ArgumentException(Properties.Resources.JsonStringCannotBeEmpty, "jsonString");
-            }
-
-            byte[] jsonBytes = Encoding.UTF8.GetBytes(jsonString);
-
-            return JXMLToJsonValue(null, jsonBytes);
-        }
-
-        public static JsonValue JXMLToJsonValue(XmlDictionaryReader jsonReader)
-        {
-            if (jsonReader == null)
-            {
-                throw new ArgumentNullException("jsonReader");
-            }
-
-            const string RootObjectName = "RootObject";
-            Stack<JsonValue> jsonStack = new Stack<JsonValue>();
-            string nodeType = null;
-            bool isEmptyElement = false;
-
-            JsonValue parent = new JsonObject();
-            jsonStack.Push(parent);
-            string currentName = RootObjectName;
-
-            try
-            {
-                MoveToRootNode(jsonReader);
-
-                while (jsonStack.Count > 0 && jsonReader.NodeType != XmlNodeType.None)
-                {
-                    if (parent is JsonObject && currentName == null)
-                    {
-                        currentName = GetMemberName(jsonReader);
-                    }
-
-                    nodeType = jsonReader.GetAttribute(TypeAttributeName) ?? StringAttributeValue;
-
-                    if (parent is JsonArray)
-                    {
-                        // For arrays, the element name has to be "item"
-                        if (jsonReader.Name != ItemElementName)
-                        {
-                            throw new FormatException(Properties.Resources.IncorrectJsonFormat);
-                        }
-                    }
-
-                    switch (nodeType)
-                    {
-                        case NullAttributeValue:
-                        case BooleanAttributeValue:
-                        case StringAttributeValue:
-                        case NumberAttributeValue:
-                            JsonPrimitive jsonPrimitive = ReadPrimitive(nodeType, jsonReader);
-                            InsertJsonValue(jsonStack, ref parent, ref currentName, jsonPrimitive, true);
-                            break;
-                        case ArrayAttributeValue:
-                            JsonArray jsonArray = CreateJsonArray(jsonReader, ref isEmptyElement);
-                            InsertJsonValue(jsonStack, ref parent, ref currentName, jsonArray, isEmptyElement);
-                            break;
-                        case ObjectAttributeValue:
-                            JsonObject jsonObject = CreateObjectWithTypeHint(jsonReader, ref isEmptyElement);
-                            InsertJsonValue(jsonStack, ref parent, ref currentName, jsonObject, isEmptyElement);
-                            break;
-                        default:
-                            throw new FormatException(Properties.Resources.IncorrectJsonFormat);
-                    }
-
-                    while (jsonReader.NodeType == XmlNodeType.EndElement && jsonStack.Count > 0)
-                    {
-                        jsonReader.Read();
-                        SkipWhitespace(jsonReader);
-                        jsonStack.Pop();
-                        if (jsonStack.Count > 0)
-                        {
-                            parent = jsonStack.Peek();
-                        }
-                    }
-                }
-            }
-            catch (XmlException xmlException)
-            {
-                throw new FormatException(Properties.Resources.IncorrectJsonFormat, xmlException);
-            }
-
-            if (jsonStack.Count != 1)
-            {
-                throw new FormatException(Properties.Resources.IncorrectJsonFormat);
-            }
-
-            return parent[RootObjectName];
-        }
-
-        private static JsonValue JXMLToJsonValue(Stream jsonStream, byte[] jsonBytes)
-        {
-            try
-            {
-                using (XmlDictionaryReader jsonReader =
-                    jsonStream != null
-                        ? JsonReaderWriterFactory.CreateJsonReader(jsonStream, XmlDictionaryReaderQuotas.Max)
-                        : JsonReaderWriterFactory.CreateJsonReader(jsonBytes, XmlDictionaryReaderQuotas.Max))
-                {
-                    return JXMLToJsonValue(jsonReader);
-                }
-            }
-            catch (XmlException)
-            {
-                throw new FormatException(Properties.Resources.IncorrectJsonFormat);
-            }
-        }
-
-        private static void InsertJsonValue(Stack<JsonValue> jsonStack, ref JsonValue parent, ref string currentName, JsonValue jsonValue, bool isEmptyElement)
-        {
-            if (parent is JsonArray)
-            {
-                ((JsonArray)parent).Add(jsonValue);
-            }
-            else
-            {
-                if (currentName != null)
-                {
-                    ((JsonObject)parent)[currentName] = jsonValue;
-                    currentName = null;
-                }
-            }
-
-            if (!isEmptyElement)
-            {
-                jsonStack.Push(jsonValue);
-                parent = jsonValue;
-            }
-        }
-
-        private static string GetMemberName(XmlDictionaryReader jsonReader)
-        {
-            string name;
-            if (jsonReader.NamespaceURI == ItemElementName && jsonReader.LocalName == ItemElementName)
-            {
-                // JXML special case for names which aren't valid XML names
-                name = jsonReader.GetAttribute(ItemElementName);
-
-                if (name == null)
-                {
-                    throw new FormatException(Properties.Resources.IncorrectJsonFormat);
-                }
-            }
-            else
-            {
-                name = jsonReader.Name;
-            }
-
-            return name;
-        }
-
-        private static JsonObject CreateObjectWithTypeHint(XmlDictionaryReader jsonReader, ref bool isEmptyElement)
-        {
-            JsonObject jsonObject = new JsonObject();
-            string typeHintAttribute = jsonReader.GetAttribute(TypeHintAttributeName);
-            isEmptyElement = jsonReader.IsEmptyElement;
-            jsonReader.ReadStartElement();
-            SkipWhitespace(jsonReader);
-
-            if (typeHintAttribute != null)
-            {
-                jsonObject.Add(TypeHintAttributeName, typeHintAttribute);
-            }
-
-            return jsonObject;
-        }
-
-        private static JsonArray CreateJsonArray(XmlDictionaryReader jsonReader, ref bool isEmptyElement)
-        {
-            JsonArray jsonArray = new JsonArray();
-            isEmptyElement = jsonReader.IsEmptyElement;
-            jsonReader.ReadStartElement();
-            SkipWhitespace(jsonReader);
-            return jsonArray;
-        }
-
-        private static void MoveToRootNode(XmlDictionaryReader jsonReader)
-        {
-            while (!jsonReader.EOF && (jsonReader.NodeType == XmlNodeType.None || jsonReader.NodeType == XmlNodeType.XmlDeclaration))
-            {
-                // read into <root> node
-                jsonReader.Read();
-                SkipWhitespace(jsonReader);
-            }
-
-            if (jsonReader.NodeType != XmlNodeType.Element || !String.IsNullOrEmpty(jsonReader.NamespaceURI) || jsonReader.Name != RootElementName)
-            {
-                throw new FormatException(Properties.Resources.IncorrectJsonFormat);
-            }
-        }
-
-        private static JsonPrimitive ReadPrimitive(string type, XmlDictionaryReader jsonReader)
-        {
-            JsonValue result = null;
-            switch (type)
-            {
-                case NullAttributeValue:
-                    jsonReader.Skip();
-                    result = null;
-                    break;
-                case BooleanAttributeValue:
-                    result = jsonReader.ReadElementContentAsBoolean();
-                    break;
-                case StringAttributeValue:
-                    result = jsonReader.ReadElementContentAsString();
-                    break;
-                case NumberAttributeValue:
-                    string temp = jsonReader.ReadElementContentAsString();
-                    result = ConvertStringToJsonNumber(temp);
-                    break;
-            }
-
-            SkipWhitespace(jsonReader);
-            return (JsonPrimitive)result;
-        }
-
-        private static void SkipWhitespace(XmlDictionaryReader reader)
-        {
-            while (!reader.EOF && (reader.NodeType == XmlNodeType.Whitespace || reader.NodeType == XmlNodeType.SignificantWhitespace))
-            {
-                reader.Read();
-            }
-        }
-
-        private static JsonValue ConvertStringToJsonNumber(string value)
-        {
-            if (value.IndexOfAny(_floatingPointChars) < 0)
-            {
-                int intVal;
-                if (Int32.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out intVal))
-                {
-                    return intVal;
-                }
-
-                long longVal;
-                if (Int64.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out longVal))
-                {
-                    return longVal;
-                }
-            }
-
-            decimal decValue;
-            if (Decimal.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out decValue) && decValue != 0)
-            {
-                return decValue;
-            }
-
-            double dblValue;
-            if (Double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out dblValue))
-            {
-                return dblValue;
-            }
-
-            throw new ArgumentException(RS.Format(Properties.Resources.InvalidJsonPrimitive, value.ToString()), "value");
-        }
-    }
-}
diff --git a/mcs/class/System.Json-new/JsonArray.cs b/mcs/class/System.Json-new/JsonArray.cs
deleted file mode 100644 (file)
index a1857c0..0000000
+++ /dev/null
@@ -1,387 +0,0 @@
-using System.Collections;
-using System.Collections.Generic;
-using System.Diagnostics.CodeAnalysis;
-using System.Globalization;
-using System.Runtime.Serialization;
-using System.Xml;
-
-namespace System.Json
-{
-    /// <summary>
-    /// A JsonArray is an ordered sequence of zero or more <see cref="System.Json.JsonValue"/> objects.
-    /// </summary>
-    [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix",
-        Justification = "Array already conveys the meaning of collection")]
-    [DataContract]
-    public sealed class JsonArray : JsonValue, IList<JsonValue>
-    {
-        [DataMember]
-        private List<JsonValue> values = new List<JsonValue>();
-
-        /// <summary>
-        /// Creates an instance of the <see cref="System.Json.JsonArray"/> class initialized by
-        /// an <see cref="System.Collections.Generic.IEnumerable{T}"/> enumeration of
-        /// objects of type <see cref="System.Json.JsonValue"/>.
-        /// </summary>
-        /// <param name="items">The <see cref="System.Collections.Generic.IEnumerable{T}"/> enumeration
-        /// of objects of type <see cref="System.Json.JsonValue"/> used to initialize the JavaScript Object Notation (JSON)
-        /// array.</param>
-        /// <exception cref="System.ArgumentNullException">If items is null.</exception>
-        /// <exception cref="System.ArgumentException">If any of the items in the collection
-        /// is a <see cref="System.Json.JsonValue"/> with <see cref="System.Json.JsonValue.JsonType"/> property of
-        /// value <see cref="F:System.Json.JsonType.Default"/>.</exception>
-        public JsonArray(IEnumerable<JsonValue> items)
-        {
-            AddRange(items);
-        }
-
-        /// <summary>
-        /// Creates an instance of the <see cref="System.Json.JsonArray"/> class, initialized by an array of type <see cref="System.Json.JsonValue"/>.
-        /// </summary>
-        /// <param name="items">The array of type <see cref="System.Json.JsonValue"/> used to initialize the
-        /// JavaScript Object Notation (JSON) array.</param>
-        /// <exception cref="System.ArgumentException">If any of the items in the collection
-        /// is a <see cref="System.Json.JsonValue"/> with <see cref="System.Json.JsonValue.JsonType"/> property of
-        /// value <see cref="F:System.Json.JsonType.Default"/>.</exception>
-        public JsonArray(params JsonValue[] items)
-        {
-            if (items != null)
-            {
-                AddRange(items);
-            }
-        }
-
-        /// <summary>
-        /// Gets the JSON type of this <see cref="System.Json.JsonArray"/>. The return value
-        /// is always <see cref="F:System.Json.JsonType.Array"/>.
-        /// </summary>
-        public override JsonType JsonType
-        {
-            get { return JsonType.Array; }
-        }
-
-        /// <summary>
-        /// Gets a value indicating whether the <see cref="System.Json.JsonArray"/> is read-only.
-        /// </summary>
-        public bool IsReadOnly
-        {
-            get { return ((IList)values).IsReadOnly; }
-        }
-
-        /// <summary>
-        /// Returns the number of <see cref="System.Json.JsonValue"/> elements in the array.
-        /// </summary>
-        public override int Count
-        {
-            get { return values.Count; }
-        }
-
-        /// <summary>
-        /// Gets or sets the JSON value at a specified index.
-        /// </summary>
-        /// <param name="index">The zero-based index of the element to get or set.</param>
-        /// <returns>The <see cref="System.Json.JsonValue"/> element at the specified index.</returns>
-        /// <exception cref="System.ArgumentOutOfRangeException">If index is not a valid index for this array.</exception>
-        /// <exception cref="System.ArgumentException">The property is set and the value is a
-        /// <see cref="System.Json.JsonValue"/> with <see cref="System.Json.JsonValue.JsonType"/>
-        /// property of value <see cref="F:System.Json.JsonType.Default"/>.</exception>
-        public override JsonValue this[int index]
-        {
-            get { return values[index]; }
-
-            set
-            {
-                if (value != null && value.JsonType == JsonType.Default)
-                {
-                    throw new ArgumentNullException("value", Properties.Resources.UseOfDefaultNotAllowed);
-                }
-
-                JsonValue oldValue = values[index];
-                RaiseItemChanging(value, JsonValueChange.Replace, index);
-                values[index] = value;
-                RaiseItemChanged(oldValue, JsonValueChange.Replace, index);
-            }
-        }
-
-        /// <summary>
-        /// Adds the elements from a collection of type <see cref="System.Json.JsonValue"/> to this instance.
-        /// </summary>
-        /// <param name="items">Collection of items to add.</param>
-        /// <exception cref="System.ArgumentNullException">If items is null.</exception>
-        /// <exception cref="System.ArgumentException">If any of the items in the collection
-        /// is a <see cref="System.Json.JsonValue"/> with <see cref="System.Json.JsonValue.JsonType"/> property of
-        /// value <see cref="F:System.Json.JsonType.Default"/>.</exception>
-        public void AddRange(IEnumerable<JsonValue> items)
-        {
-            if (items == null)
-            {
-                throw new ArgumentNullException("items");
-            }
-
-            if (ChangingListenersCount > 0)
-            {
-                int index = Count;
-                foreach (JsonValue toBeAdded in items)
-                {
-                    RaiseItemChanging(toBeAdded, JsonValueChange.Add, index++);
-                }
-            }
-
-            foreach (JsonValue item in items)
-            {
-                if (item != null && item.JsonType == JsonType.Default)
-                {
-                    throw new ArgumentNullException("items", Properties.Resources.UseOfDefaultNotAllowed);
-                }
-
-                values.Add(item);
-                RaiseItemChanged(item, JsonValueChange.Add, values.Count - 1);
-            }
-        }
-
-        /// <summary>
-        /// Adds the elements from an array of type <see cref="System.Json.JsonValue"/> to this instance.
-        /// </summary>
-        /// <param name="items">The array of type JsonValue to be added to this instance.</param>
-        /// <exception cref="System.ArgumentNullException">If items is null.</exception>
-        /// <exception cref="System.ArgumentException">If any of the items in the array
-        /// is a <see cref="System.Json.JsonValue"/> with <see cref="System.Json.JsonValue.JsonType"/> property of
-        /// value <see cref="F:System.Json.JsonType.Default"/>.</exception>
-        public void AddRange(params JsonValue[] items)
-        {
-            AddRange(items as IEnumerable<JsonValue>);
-        }
-
-        /// <summary>
-        /// Searches for a specified object and returns the zero-based index of its first
-        /// occurrence within this <see cref="System.Json.JsonArray"/>.
-        /// </summary>
-        /// <param name="item">The <see cref="System.Json.JsonValue"/> object to look up.</param>
-        /// <returns>The zero-based index of the first occurrence of item within the
-        /// <see cref="System.Json.JsonArray"/>, if found; otherwise, -1.</returns>
-        public int IndexOf(JsonValue item)
-        {
-            return values.IndexOf(item);
-        }
-
-        /// <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="System.Json.JsonValue"/> object to insert.</param>
-        /// <exception cref="System.ArgumentOutOfRangeException">If index is less than zero or larger than
-        /// the size of the array.</exception>
-        /// <exception cref="System.ArgumentException">If the object to insert has a
-        /// <see cref="System.Json.JsonValue.JsonType"/> property of value
-        /// <see cref="F:System.Json.JsonType.Default"/>.</exception>
-        public void Insert(int index, JsonValue item)
-        {
-            if (item != null && item.JsonType == JsonType.Default)
-            {
-                throw new ArgumentNullException("item", Properties.Resources.UseOfDefaultNotAllowed);
-            }
-
-            RaiseItemChanging(item, JsonValueChange.Add, index);
-            values.Insert(index, item);
-            RaiseItemChanged(item, JsonValueChange.Add, index);
-        }
-
-        /// <summary>
-        /// Remove the JSON value at a specified index of <see cref="System.Json.JsonArray"/>.
-        /// </summary>
-        /// <param name="index">The zero-based index at which to remove the <see cref="System.Json.JsonValue"/>.</param>
-        /// <exception cref="System.ArgumentOutOfRangeException">If index is less than zero or index
-        /// is equal or larger than the size of the array.</exception>
-        public void RemoveAt(int index)
-        {
-            JsonValue item = values[index];
-            RaiseItemChanging(item, JsonValueChange.Remove, index);
-            values.RemoveAt(index);
-            RaiseItemChanged(item, JsonValueChange.Remove, index);
-        }
-
-        /// <summary>
-        /// Adds a <see cref="System.Json.JsonValue"/> object to the end of the array.
-        /// </summary>
-        /// <param name="item">The <see cref="System.Json.JsonValue"/> object to add.</param>
-        /// <exception cref="System.ArgumentException">If the object to add has a
-        /// <see cref="System.Json.JsonValue.JsonType"/> property of value
-        /// <see cref="F:System.Json.JsonType.Default"/>.</exception>
-        public void Add(JsonValue item)
-        {
-            if (item != null && item.JsonType == JsonType.Default)
-            {
-                throw new ArgumentNullException("item", Properties.Resources.UseOfDefaultNotAllowed);
-            }
-
-            int index = Count;
-            RaiseItemChanging(item, JsonValueChange.Add, index);
-            values.Add(item);
-            RaiseItemChanged(item, JsonValueChange.Add, index);
-        }
-
-        /// <summary>
-        /// Removes all JSON CLR types from the <see cref="System.Json.JsonArray"/>.
-        /// </summary>
-        public void Clear()
-        {
-            RaiseItemChanging(null, JsonValueChange.Clear, 0);
-            values.Clear();
-            RaiseItemChanged(null, JsonValueChange.Clear, 0);
-        }
-
-        /// <summary>
-        /// Checks whether a specified JSON CLR type is in the <see cref="System.Json.JsonArray"/>.
-        /// </summary>
-        /// <param name="item">The <see cref="System.Json.JsonValue"/> to check for in the array.</param>
-        /// <returns>true if item is found in the <see cref="System.Json.JsonArray"/>; otherwise, false.</returns>
-        public bool Contains(JsonValue item)
-        {
-            return values.Contains(item);
-        }
-
-        /// <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 array to which the elements of the current
-        /// <see cref="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>
-        public void CopyTo(JsonValue[] array, int arrayIndex)
-        {
-            values.CopyTo(array, arrayIndex);
-        }
-
-        /// <summary>
-        /// Removes the first occurrence of the specified JSON value from the array.
-        /// </summary>
-        /// <param name="item">The <see cref="System.Json.JsonValue"/> to remove from the <see cref="System.Json.JsonArray"/>.</param>
-        /// <returns>true if item is successfully removed; otherwise, false. This method
-        /// also returns false if item was not found in the <see cref="System.Json.JsonArray"/>.</returns>
-        public bool Remove(JsonValue item)
-        {
-            int index = -1;
-            if (ChangingListenersCount > 0 || ChangedListenersCount > 0)
-            {
-                index = IndexOf(item);
-            }
-
-            if (index >= 0)
-            {
-                RaiseItemChanging(item, JsonValueChange.Remove, index);
-            }
-
-            bool result = values.Remove(item);
-            if (index >= 0)
-            {
-                RaiseItemChanged(item, JsonValueChange.Remove, index);
-            }
-
-            return result;
-        }
-
-        /// <summary>
-        /// Returns an enumerator that iterates through the <see cref="System.Json.JsonValue"/> objects in the array.
-        /// </summary>
-        /// <returns>Returns an <see cref="System.Collections.IEnumerator"/> object that
-        /// iterates through the <see cref="System.Json.JsonValue"/> elements in this <see cref="System.Json.JsonArray"/>.</returns>
-        IEnumerator IEnumerable.GetEnumerator()
-        {
-            return values.GetEnumerator();
-        }
-
-        /// <summary>
-        /// Safe indexer for the <see cref="System.Json.JsonValue"/> type. 
-        /// </summary>
-        /// <param name="index">The zero-based index of the element to get.</param>
-        /// <returns>If the index is within the array bounds and the value corresponding to the
-        /// index is not null, then it will return that value. Otherwise it will return a
-        /// <see cref="System.Json.JsonValue"/> instance with <see cref="System.Json.JsonValue.JsonType"/>
-        /// equals to <see cref="F:System.Json.JsonType.Default"/>.</returns>
-        public override JsonValue ValueOrDefault(int index)
-        {
-            if (index >= 0 && index < Count && this[index] != null)
-            {
-                return this[index];
-            }
-
-            return base.ValueOrDefault(index);
-        }
-
-        /// <summary>
-        /// Returns an enumerator that iterates through the <see cref="System.Json.JsonValue"/> objects in the array.
-        /// </summary>
-        /// <returns>Returns an <see cref="System.Collections.Generic.IEnumerator{T}"/> object that
-        /// iterates through the <see cref="System.Json.JsonValue"/> elements in this <see cref="System.Json.JsonArray"/>.</returns>
-        public new IEnumerator<JsonValue> GetEnumerator()
-        {
-            return values.GetEnumerator();
-        }
-
-        /// <summary>
-        /// Returns an enumerator which iterates through the values in this object.
-        /// </summary>
-        /// <returns>An <see cref="System.Collections.Generic.IEnumerator{T}"/> which iterates through the values in this object.</returns>
-        /// <remarks>The enumerator returned by this class contains one pair for each element
-        /// in this array, whose key is the element index (as a string), and the value is the
-        /// element itself.</remarks>
-        protected override IEnumerator<KeyValuePair<string, JsonValue>> GetKeyValuePairEnumerator()
-        {
-            for (int i = 0; i < values.Count; i++)
-            {
-                yield return new KeyValuePair<string, JsonValue>(i.ToString(CultureInfo.InvariantCulture), values[i]);
-            }
-        }
-
-        /// <summary>
-        /// Callback method called to let an instance write the proper JXML attribute when saving this
-        /// instance.
-        /// </summary>
-        /// <param name="jsonWriter">The JXML writer used to write JSON.</param>
-        internal override void WriteAttributeString(XmlDictionaryWriter jsonWriter)
-        {
-            if (jsonWriter == null)
-            {
-                throw new ArgumentNullException("jsonWriter");
-            }
-
-            jsonWriter.WriteAttributeString(JXmlToJsonValueConverter.TypeAttributeName, JXmlToJsonValueConverter.ArrayAttributeValue);
-        }
-
-        /// <summary>
-        /// Callback method called during Save operations to let the instance write the start element
-        /// and return the next element in the collection.
-        /// </summary>
-        /// <param name="jsonWriter">The JXML writer used to write JSON.</param>
-        /// <param name="currentIndex">The index within this collection.</param>
-        /// <returns>The next item in the collection, or null of there are no more items.</returns>
-        internal override JsonValue WriteStartElementAndGetNext(XmlDictionaryWriter jsonWriter, int currentIndex)
-        {
-            if (jsonWriter == null)
-            {
-                throw new ArgumentNullException("jsonWriter");
-            }
-
-            jsonWriter.WriteStartElement(JXmlToJsonValueConverter.ItemElementName);
-            JsonValue nextValue = this[currentIndex];
-            return nextValue;
-        }
-
-        private void RaiseItemChanging(JsonValue child, JsonValueChange change, int index)
-        {
-            if (ChangingListenersCount > 0)
-            {
-                RaiseChangingEvent(this, new JsonValueChangeEventArgs(child, change, index));
-            }
-        }
-
-        private void RaiseItemChanged(JsonValue child, JsonValueChange change, int index)
-        {
-            if (ChangedListenersCount > 0)
-            {
-                RaiseChangedEvent(this, new JsonValueChangeEventArgs(child, change, index));
-            }
-        }
-    }
-}
diff --git a/mcs/class/System.Json-new/JsonObject.cs b/mcs/class/System.Json-new/JsonObject.cs
deleted file mode 100644 (file)
index de69582..0000000
+++ /dev/null
@@ -1,472 +0,0 @@
-using System.Collections;
-using System.Collections.Generic;
-using System.Diagnostics.CodeAnalysis;
-using System.Runtime.Serialization;
-using System.Xml;
-using WrappedPair = System.Json.NGenWrapper<System.Collections.Generic.KeyValuePair<string, System.Json.JsonValue>>;
-
-namespace System.Json
-{
-    /// <summary>
-    /// A JsonObject is an unordered collection of zero or more key/value pairs.
-    /// </summary>
-    /// <remarks>A JsonObject is an unordered collection of zero or more key/value pairs,
-    /// where each key is a String and each value is a <see cref="System.Json.JsonValue"/>, which can be a
-    /// <see cref="System.Json.JsonPrimitive"/>, a <see cref="System.Json.JsonArray"/>, or a JsonObject.</remarks>
-    [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix",
-        Justification = "Object in the context of JSON already conveys the meaning of dictionary")]
-    [DataContract]
-    public sealed class JsonObject : JsonValue, IDictionary<string, JsonValue>
-    {
-        [DataMember]
-        private Dictionary<string, JsonValue> values = new Dictionary<string, JsonValue>(StringComparer.Ordinal);
-
-        private List<WrappedPair> indexedPairs;
-        private int instanceSaveCount;
-        private object saveLock = new object();
-
-        /// <summary>
-        /// Creates an instance of the <see cref="System.Json.JsonObject"/> class initialized with an
-        /// <see cref="System.Collections.Generic.IEnumerable{T}"/> collection of key/value pairs.
-        /// </summary>
-        /// <param name="items">The <see cref="System.Collections.Generic.IEnumerable{T}"/> collection of
-        /// <see cref="System.Collections.Generic.KeyValuePair{K, V}"/> used to initialize the
-        /// key/value pairs</param>
-        /// <exception cref="System.ArgumentNullException">If items is null.</exception>
-        /// <exception cref="System.ArgumentException">If any of the values in the collection
-        /// is a <see cref="System.Json.JsonValue"/> with <see cref="System.Json.JsonValue.JsonType"/> property of
-        /// value <see cref="F:System.Json.JsonType.Default"/>.</exception>
-        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures",
-            Justification = "There's no complexity using this design because nested generic type is atomic type not another collection")]
-        public JsonObject(IEnumerable<KeyValuePair<string, JsonValue>> items)
-        {
-            AddRange(items);
-        }
-
-        /// <summary>
-        /// Creates an instance of the <see cref="System.Json.JsonObject"/> class initialized with a collection of key/value pairs.
-        /// </summary>
-        /// <param name="items">The <see cref="System.Collections.Generic.KeyValuePair{K, V}"/> objects used to initialize the key/value pairs.</param>
-        /// <exception cref="System.ArgumentException">If any of the values in the collection
-        /// is a <see cref="System.Json.JsonValue"/> with <see cref="System.Json.JsonValue.JsonType"/> property of
-        /// value <see cref="F:System.Json.JsonType.Default"/>.</exception>
-        public JsonObject(params KeyValuePair<string, JsonValue>[] items)
-        {
-            if (items != null)
-            {
-                AddRange(items);
-            }
-        }
-
-        /// <summary>
-        /// Gets the JSON type of this <see cref="System.Json.JsonObject"/>. The return value
-        /// is always <see cref="F:System.Json.JsonType.Object"/>.
-        /// </summary>
-        public override JsonType JsonType
-        {
-            get { return JsonType.Object; }
-        }
-
-        /// <summary>
-        /// Gets a collection that contains the keys in this <see cref="System.Json.JsonObject"/>.
-        /// </summary>
-        public ICollection<string> Keys
-        {
-            get { return values.Keys; }
-        }
-
-        /// <summary>
-        /// Gets a collection that contains the values in this <see cref="System.Json.JsonObject"/>.
-        /// </summary>
-        public ICollection<JsonValue> Values
-        {
-            get { return values.Values; }
-        }
-
-        /// <summary>
-        /// Returns the number of key/value pairs in this <see cref="System.Json.JsonObject"/>.
-        /// </summary>
-        public override int Count
-        {
-            get { return values.Count; }
-        }
-
-        /// <summary>
-        /// Gets a value indicating whether this JSON CLR object is read-only.
-        /// </summary>
-        bool ICollection<KeyValuePair<string, JsonValue>>.IsReadOnly
-        {
-            get { return ((ICollection<KeyValuePair<string, JsonValue>>)values).IsReadOnly; }
-        }
-
-        /// <summary>
-        /// Gets or sets the value associated with the specified key.
-        /// </summary>
-        /// <param name="key">The key of the value to get or set.</param>
-        /// <returns>The <see cref="System.Json.JsonValue"/> associated to the specified key.</returns>
-        /// <exception cref="System.ArgumentNullException">If key is null.</exception>
-        /// <exception cref="System.ArgumentException">The property is set and the value is a
-        /// <see cref="System.Json.JsonValue"/> with <see cref="System.Json.JsonValue.JsonType"/>
-        /// property of value <see cref="F:System.Json.JsonType.Default"/>.</exception>
-        public override JsonValue this[string key]
-        {
-            get
-            {
-                if (key == null)
-                {
-                    throw new ArgumentNullException("key");
-                }
-
-                return values[key];
-            }
-
-            set
-            {
-                if (value != null && value.JsonType == JsonType.Default)
-                {
-                    throw new ArgumentNullException("value", Properties.Resources.UseOfDefaultNotAllowed);
-                }
-
-                if (key == null)
-                {
-                    throw new ArgumentNullException("key");
-                }
-
-                bool replacement = values.ContainsKey(key);
-                JsonValue oldValue = null;
-                if (replacement)
-                {
-                    oldValue = values[key];
-                    RaiseItemChanging(value, JsonValueChange.Replace, key);
-                }
-                else
-                {
-                    RaiseItemChanging(value, JsonValueChange.Add, key);
-                }
-
-                values[key] = value;
-                if (replacement)
-                {
-                    RaiseItemChanged(oldValue, JsonValueChange.Replace, key);
-                }
-                else
-                {
-                    RaiseItemChanged(value, JsonValueChange.Add, key);
-                }
-            }
-        }
-
-        /// <summary>
-        /// Safe string indexer for the <see cref="System.Json.JsonValue"/> type. 
-        /// </summary>
-        /// <param name="key">The key of the element to get.</param>
-        /// <returns>If this instance contains the given key and the value corresponding to
-        /// the key is not null, then it will return that value. Otherwise it will return a
-        /// <see cref="System.Json.JsonValue"/> instance with <see cref="System.Json.JsonValue.JsonType"/>
-        /// equals to <see cref="F:System.Json.JsonType.Default"/>.</returns>
-        public override JsonValue ValueOrDefault(string key)
-        {
-            if (key != null && ContainsKey(key) && this[key] != null)
-            {
-                return this[key];
-            }
-
-            return base.ValueOrDefault(key);
-        }
-
-        /// <summary>
-        /// Adds a specified collection of key/value pairs to this instance.
-        /// </summary>
-        /// <param name="items">The collection of key/value pairs to add.</param>
-        /// <exception cref="System.ArgumentNullException">If items is null.</exception>
-        /// <exception cref="System.ArgumentException">If the value of any of the items in the collection
-        /// is a <see cref="System.Json.JsonValue"/> with <see cref="System.Json.JsonValue.JsonType"/> property of
-        /// value <see cref="F:System.Json.JsonType.Default"/>.</exception>
-        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures",
-            Justification = "There's no complexity using this design because nested generic type is atomic type not another collection")]
-        public void AddRange(IEnumerable<KeyValuePair<string, JsonValue>> items)
-        {
-            if (items == null)
-            {
-                throw new ArgumentNullException("items");
-            }
-
-            if (ChangingListenersCount > 0)
-            {
-                foreach (KeyValuePair<string, JsonValue> item in items)
-                {
-                    RaiseItemChanging(item.Value, JsonValueChange.Add, item.Key);
-                }
-            }
-
-            foreach (KeyValuePair<string, JsonValue> item in items)
-            {
-                if (item.Value != null && item.Value.JsonType == JsonType.Default)
-                {
-                    throw new ArgumentNullException("items", Properties.Resources.UseOfDefaultNotAllowed);
-                }
-
-                values.Add(item.Key, item.Value);
-                RaiseItemChanged(item.Value, JsonValueChange.Add, item.Key);
-            }
-        }
-
-        /// <summary>
-        /// Adds the elements from an array of type <see cref="System.Json.JsonValue"/> to this instance.
-        /// </summary>
-        /// <param name="items">The array of key/value paris to be added to this instance.</param>
-        /// <exception cref="System.ArgumentException">If the value of any of the items in the array
-        /// is a <see cref="System.Json.JsonValue"/> with <see cref="System.Json.JsonValue.JsonType"/> property of
-        /// value <see cref="F:System.Json.JsonType.Default"/>.</exception>
-        public void AddRange(params KeyValuePair<string, JsonValue>[] items)
-        {
-            AddRange(items as IEnumerable<KeyValuePair<string, JsonValue>>);
-        }
-
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <returns></returns>
-        IEnumerator IEnumerable.GetEnumerator()
-        {
-            return ((IEnumerable)values).GetEnumerator();
-        }
-
-        /// <summary>
-        /// Adds a key/value pair to this <see cref="System.Json.JsonObject"/> instance.
-        /// </summary>
-        /// <param name="key">The key for the element added.</param>
-        /// <param name="value">The <see cref="System.Json.JsonValue"/> for the element added.</param>
-        /// <exception cref="System.ArgumentException">If the value is a <see cref="System.Json.JsonValue"/>
-        /// with <see cref="System.Json.JsonValue.JsonType"/> property of
-        /// value <see cref="F:System.Json.JsonType.Default"/>.</exception>
-        public void Add(string key, JsonValue value)
-        {
-            if (value != null && value.JsonType == JsonType.Default)
-            {
-                throw new ArgumentNullException("value", Properties.Resources.UseOfDefaultNotAllowed);
-            }
-
-            RaiseItemChanging(value, JsonValueChange.Add, key);
-            values.Add(key, value);
-            RaiseItemChanged(value, JsonValueChange.Add, key);
-        }
-
-        /// <summary>
-        /// Adds a key/value pair to this <see cref="System.Json.JsonObject"/> instance.
-        /// </summary>
-        /// <param name="item">The key/value pair to be added.</param>
-        /// <exception cref="System.ArgumentException">If the value of the pair is a
-        /// <see cref="System.Json.JsonValue"/> with <see cref="System.Json.JsonValue.JsonType"/>
-        /// property of value <see cref="F:System.Json.JsonType.Default"/>.</exception>
-        public void Add(KeyValuePair<string, JsonValue> item)
-        {
-            Add(item.Key, item.Value);
-        }
-
-        /// <summary>
-        /// Checks whether a key/value pair with a specified key exists in this <see cref="System.Json.JsonObject"/> instance.
-        /// </summary>
-        /// <param name="key">The key to check for.</param>
-        /// <returns>true if this instance contains the key; otherwise, false.</returns>
-        public override bool ContainsKey(string key)
-        {
-            return values.ContainsKey(key);
-        }
-
-        /// <summary>
-        /// Removes the key/value pair with a specified key from this <see cref="System.Json.JsonObject"/> instance.
-        /// </summary>
-        /// <param name="key">The key of the item to remove.</param>
-        /// <returns>true if the element is successfully found and removed; otherwise, false.
-        /// This method returns false if key is not found in this <see cref="System.Json.JsonObject"/> instance.</returns>
-        public bool Remove(string key)
-        {
-            JsonValue original = null;
-            bool containsKey = false;
-            if (ChangingListenersCount > 0 || ChangedListenersCount > 0)
-            {
-                containsKey = TryGetValue(key, out original);
-            }
-
-            if (containsKey && ChangingListenersCount > 0)
-            {
-                RaiseItemChanging(original, JsonValueChange.Remove, key);
-            }
-
-            bool result = values.Remove(key);
-
-            if (containsKey && ChangedListenersCount > 0)
-            {
-                RaiseItemChanged(original, JsonValueChange.Remove, key);
-            }
-
-            return result;
-        }
-
-        /// <summary>
-        /// Attempts to get the value that corresponds to the specified key.
-        /// </summary>
-        /// <param name="key">The key of the value to retrieve.</param>
-        /// <param name="value">The primitive or structured <see cref="System.Json.JsonValue"/> object that has the key
-        /// specified. If this object does not contain a key/value pair with the given key,
-        /// this parameter is set to null.</param>
-        /// <returns>true if the instance of the <see cref="System.Json.JsonObject"/> contains an element with the
-        /// specified key; otherwise, false.</returns>
-        public bool TryGetValue(string key, out JsonValue value)
-        {
-            return values.TryGetValue(key, out value);
-        }
-
-        /// <summary>
-        /// Removes all key/value pairs from this <see cref="System.Json.JsonObject"/> instance.
-        /// </summary>
-        public void Clear()
-        {
-            RaiseItemChanging(null, JsonValueChange.Clear, null);
-            values.Clear();
-            RaiseItemChanged(null, JsonValueChange.Clear, null);
-        }
-
-        bool ICollection<KeyValuePair<string, JsonValue>>.Contains(KeyValuePair<string, JsonValue> item)
-        {
-            return ((ICollection<KeyValuePair<string, JsonValue>>)values).Contains(item);
-        }
-
-        /// <summary>
-        /// Copies the contents of this <see cref="System.Json.JsonObject"/> instance into a specified
-        /// key/value destination array beginning at a specified index.
-        /// </summary>
-        /// <param name="array">The destination array of type <see cref="System.Collections.Generic.KeyValuePair{K, V}"/>
-        /// to which the elements of this <see cref="System.Json.JsonObject"/> are copied.</param>
-        /// <param name="arrayIndex">The zero-based index at which to begin the insertion of the
-        /// contents from this <see cref="System.Json.JsonObject"/> instance.</param>
-        public void CopyTo(KeyValuePair<string, JsonValue>[] array, int arrayIndex)
-        {
-            ((ICollection<KeyValuePair<string, JsonValue>>)values).CopyTo(array, arrayIndex);
-        }
-
-        bool ICollection<KeyValuePair<string, JsonValue>>.Remove(KeyValuePair<string, JsonValue> item)
-        {
-            if (ChangingListenersCount > 0)
-            {
-                if (ContainsKey(item.Key) && EqualityComparer<JsonValue>.Default.Equals(item.Value, values[item.Key]))
-                {
-                    RaiseItemChanging(item.Value, JsonValueChange.Remove, item.Key);
-                }
-            }
-
-            bool result = ((ICollection<KeyValuePair<string, JsonValue>>)values).Remove(item);
-            if (result)
-            {
-                RaiseItemChanged(item.Value, JsonValueChange.Remove, item.Key);
-            }
-
-            return result;
-        }
-
-        /// <summary>
-        /// Returns an enumerator over the key/value pairs contained in this <see cref="System.Json.JsonObject"/> instance.
-        /// </summary>
-        /// <returns>An <see cref="System.Collections.Generic.IEnumerator{T}"/> which iterates
-        /// through the members of this instance.</returns>
-        protected override IEnumerator<KeyValuePair<string, JsonValue>> GetKeyValuePairEnumerator()
-        {
-            return values.GetEnumerator();
-        }
-
-        /// <summary>
-        /// Callback method called when a Save operation is starting for this instance.
-        /// </summary>
-        protected override void OnSaveStarted()
-        {
-            lock (saveLock)
-            {
-                instanceSaveCount++;
-                if (indexedPairs == null)
-                {
-                    indexedPairs = new List<WrappedPair>();
-
-                    foreach (KeyValuePair<string, JsonValue> item in values)
-                    {
-                        indexedPairs.Add(new WrappedPair(item));
-                    }
-                }
-            }
-        }
-
-        /// <summary>
-        /// Callback method called when a Save operation is finished for this instance.
-        /// </summary>
-        protected override void OnSaveEnded()
-        {
-            lock (saveLock)
-            {
-                instanceSaveCount--;
-                if (instanceSaveCount == 0)
-                {
-                    indexedPairs = null;
-                }
-            }
-        }
-
-        /// <summary>
-        /// Callback method called to let an instance write the proper JXML attribute when saving this
-        /// instance.
-        /// </summary>
-        /// <param name="jsonWriter">The JXML writer used to write JSON.</param>
-        internal override void WriteAttributeString(XmlDictionaryWriter jsonWriter)
-        {
-            jsonWriter.WriteAttributeString(JXmlToJsonValueConverter.TypeAttributeName, JXmlToJsonValueConverter.ObjectAttributeValue);
-        }
-
-        /// <summary>
-        /// Callback method called during Save operations to let the instance write the start element
-        /// and return the next element in the collection.
-        /// </summary>
-        /// <param name="jsonWriter">The JXML writer used to write JSON.</param>
-        /// <param name="currentIndex">The index within this collection.</param>
-        /// <returns>The next item in the collection, or null of there are no more items.</returns>
-        internal override JsonValue WriteStartElementAndGetNext(XmlDictionaryWriter jsonWriter, int currentIndex)
-        {
-            KeyValuePair<string, JsonValue> currentPair = indexedPairs[currentIndex];
-            string currentKey = currentPair.Key;
-
-            if (currentKey.Length == 0)
-            {
-                // special case in JXML world
-                jsonWriter.WriteStartElement(JXmlToJsonValueConverter.ItemElementName, JXmlToJsonValueConverter.ItemElementName);
-                jsonWriter.WriteAttributeString(JXmlToJsonValueConverter.ItemElementName, String.Empty);
-            }
-            else
-            {
-                jsonWriter.WriteStartElement(currentKey);
-            }
-
-            return currentPair.Value;
-        }
-
-        [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", Justification = "Context is required by CLR for this to work.")]
-        [OnDeserialized]
-        private void OnDeserialized(StreamingContext context)
-        {
-            saveLock = new object();
-        }
-
-        private void RaiseItemChanging(JsonValue child, JsonValueChange change, string key)
-        {
-            if (ChangingListenersCount > 0)
-            {
-                RaiseChangingEvent(this, new JsonValueChangeEventArgs(child, change, key));
-            }
-        }
-
-        private void RaiseItemChanged(JsonValue child, JsonValueChange change, string key)
-        {
-            if (ChangedListenersCount > 0)
-            {
-                RaiseChangedEvent(this, new JsonValueChangeEventArgs(child, change, key));
-            }
-        }
-    }
-}
diff --git a/mcs/class/System.Json-new/JsonPrimitive.cs b/mcs/class/System.Json-new/JsonPrimitive.cs
deleted file mode 100644 (file)
index 679f479..0000000
+++ /dev/null
@@ -1,1149 +0,0 @@
-using System.Collections.Generic;
-using System.Diagnostics.CodeAnalysis;
-using System.Diagnostics.Contracts;
-using System.Globalization;
-using System.Runtime.Serialization;
-using System.Text;
-using System.Xml;
-
-namespace System.Json
-{
-    /// <summary>
-    /// Represents a JavaScript Object Notation (JSON) primitive type in the common language runtime (CLR).
-    /// </summary>
-    [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix",
-        Justification = "JsonPrimitive does not represent a collection.")]
-    [DataContract]
-    public sealed class JsonPrimitive : JsonValue
-    {
-        internal const string DateTimeIsoFormat = "yyyy-MM-ddTHH:mm:ss.fffK";
-        private const string UtcString = "UTC";
-        private const string GmtString = "GMT";
-        private static readonly long UnixEpochTicks = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks;
-        private static readonly char[] FloatingPointChars = new char[] { '.', 'e', 'E' };
-        private static readonly Type jsonPrimitiveType = typeof(JsonPrimitive);
-        private static readonly Type uriType = typeof(Uri);
-
-        private static readonly Dictionary<Type, Func<string, ConvertResult>> stringConverters = new Dictionary<Type, Func<string, ConvertResult>>
-        {
-            { typeof(bool), new Func<string, ConvertResult>(StringToBool) },
-            { typeof(byte), new Func<string, ConvertResult>(StringToByte) },
-            { typeof(char), new Func<string, ConvertResult>(StringToChar) },
-            { typeof(sbyte), new Func<string, ConvertResult>(StringToSByte) },
-            { typeof(short), new Func<string, ConvertResult>(StringToShort) },
-            { typeof(int), new Func<string, ConvertResult>(StringToInt) },
-            { typeof(long), new Func<string, ConvertResult>(StringToLong) },
-            { typeof(ushort), new Func<string, ConvertResult>(StringToUShort) },
-            { typeof(uint), new Func<string, ConvertResult>(StringToUInt) },
-            { typeof(ulong), new Func<string, ConvertResult>(StringToULong) },
-            { typeof(float), new Func<string, ConvertResult>(StringToFloat) },
-            { typeof(double), new Func<string, ConvertResult>(StringToDouble) },
-            { typeof(decimal), new Func<string, ConvertResult>(StringToDecimal) },
-            { typeof(DateTime), new Func<string, ConvertResult>(StringToDateTime) },
-            { typeof(DateTimeOffset), new Func<string, ConvertResult>(StringToDateTimeOffset) },
-            { typeof(Guid), new Func<string, ConvertResult>(StringToGuid) },
-            { typeof(Uri), new Func<string, ConvertResult>(StringToUri) },
-        };
-
-        [DataMember]
-        private object value;
-
-        [DataMember]
-        private JsonType jsonType;
-
-        /// <summary>
-        /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.Boolean"/> type.
-        /// </summary>
-        /// <param name="value">The <see cref="System.Boolean"/> object that initializes the new instance.</param>
-        /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it.
-        /// When initialized with a <see cref="System.Boolean"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.Boolean"/>, which can be
-        /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/>
-        /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.Boolean"/>.</remarks>
-        public JsonPrimitive(bool value)
-        {
-            jsonType = JsonType.Boolean;
-            this.value = value;
-        }
-
-        /// <summary>
-        /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.Byte"/> type.
-        /// </summary>
-        /// <param name="value">The <see cref="System.Byte"/> object that initializes the new instance.</param>
-        /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it.
-        /// When initialized with a <see cref="System.Byte"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.Number"/>, which can be
-        /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/>
-        /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.Byte"/>.</remarks>
-        public JsonPrimitive(byte value)
-        {
-            jsonType = JsonType.Number;
-            this.value = value;
-        }
-
-        /// <summary>
-        /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.SByte"/> type.
-        /// </summary>
-        /// <param name="value">The <see cref="System.SByte"/> object that initializes the new instance.</param>
-        /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it.
-        /// When initialized with a <see cref="System.SByte"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.Number"/>, which can be
-        /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/>
-        /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.SByte"/>.</remarks>
-        [CLSCompliant(false)]
-        public JsonPrimitive(sbyte value)
-        {
-            jsonType = JsonType.Number;
-            this.value = value;
-        }
-
-        /// <summary>
-        /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.Decimal"/> type.
-        /// </summary>
-        /// <param name="value">The <see cref="System.Decimal"/> object that initializes the new instance.</param>
-        /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it.
-        /// When initialized with a <see cref="System.Decimal"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.Number"/>, which can be
-        /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/>
-        /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.Decimal"/>.</remarks>
-        public JsonPrimitive(decimal value)
-        {
-            jsonType = JsonType.Number;
-            this.value = value;
-        }
-
-        /// <summary>
-        /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.Int16"/> type.
-        /// </summary>
-        /// <param name="value">The <see cref="System.Int16"/> object that initializes the new instance.</param>
-        /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it.
-        /// When initialized with a <see cref="System.Int16"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.Number"/>, which can be
-        /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/>
-        /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.Int16"/>.</remarks>
-        public JsonPrimitive(short value)
-        {
-            jsonType = JsonType.Number;
-            this.value = value;
-        }
-
-        /// <summary>
-        /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.UInt16"/> type.
-        /// </summary>
-        /// <param name="value">The <see cref="System.UInt16"/> object that initializes the new instance.</param>
-        /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it.
-        /// When initialized with a <see cref="System.UInt16"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.Number"/>, which can be
-        /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/>
-        /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.UInt16"/>.</remarks>
-        [CLSCompliant(false)]
-        public JsonPrimitive(ushort value)
-        {
-            jsonType = JsonType.Number;
-            this.value = value;
-        }
-
-        /// <summary>
-        /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.Int32"/> type.
-        /// </summary>
-        /// <param name="value">The <see cref="System.Int32"/> object that initializes the new instance.</param>
-        /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it.
-        /// When initialized with a <see cref="System.Int32"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.Number"/>, which can be
-        /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/>
-        /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.Int32"/>.</remarks>
-        public JsonPrimitive(int value)
-        {
-            jsonType = JsonType.Number;
-            this.value = value;
-        }
-
-        /// <summary>
-        /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.UInt32"/> type.
-        /// </summary>
-        /// <param name="value">The <see cref="System.UInt32"/> object that initializes the new instance.</param>
-        /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it.
-        /// When initialized with a <see cref="System.UInt32"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.Number"/>, which can be
-        /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/>
-        /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.UInt32"/>.</remarks>
-        [CLSCompliant(false)]
-        public JsonPrimitive(uint value)
-        {
-            jsonType = JsonType.Number;
-            this.value = value;
-        }
-
-        /// <summary>
-        /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.Int64"/> type.
-        /// </summary>
-        /// <param name="value">The <see cref="System.Int64"/> object that initializes the new instance.</param>
-        /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it.
-        /// When initialized with a <see cref="System.Int64"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.Number"/>, which can be
-        /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/>
-        /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.Int64"/>.</remarks>
-        public JsonPrimitive(long value)
-        {
-            jsonType = JsonType.Number;
-            this.value = value;
-        }
-
-        /// <summary>
-        /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.UInt64"/> type.
-        /// </summary>
-        /// <param name="value">The <see cref="System.UInt64"/> object that initializes the new instance.</param>
-        /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it.
-        /// When initialized with a <see cref="System.UInt64"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.Number"/>, which can be
-        /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/>
-        /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.UInt64"/>.</remarks>
-        [CLSCompliant(false)]
-        public JsonPrimitive(ulong value)
-        {
-            jsonType = JsonType.Number;
-            this.value = value;
-        }
-
-        /// <summary>
-        /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.Single"/> type.
-        /// </summary>
-        /// <param name="value">The <see cref="System.Single"/> object that initializes the new instance.</param>
-        /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it.
-        /// When initialized with a <see cref="System.Single"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.Number"/>, which can be
-        /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/>
-        /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.Single"/>.</remarks>
-        public JsonPrimitive(float value)
-        {
-            jsonType = JsonType.Number;
-            this.value = value;
-        }
-
-        /// <summary>
-        /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.Double"/> type.
-        /// </summary>
-        /// <param name="value">The <see cref="System.Double"/> object that initializes the new instance.</param>
-        /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it.
-        /// When initialized with a <see cref="System.Double"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.Number"/>, which can be
-        /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/>
-        /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.Double"/>.</remarks>
-        public JsonPrimitive(double value)
-        {
-            jsonType = JsonType.Number;
-            this.value = value;
-        }
-
-        /// <summary>
-        /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.String"/> type.
-        /// </summary>
-        /// <param name="value">The <see cref="System.String"/> object that initializes the new instance.</param>
-        /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it.
-        /// When initialized with a <see cref="System.String"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.String"/>, which can be
-        /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/>
-        /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.String"/>.</remarks>
-        /// <exception cref="System.ArgumentNullException">value is null.</exception>
-        [SuppressMessage("Microsoft.Design", "CA1057:StringUriOverloadsCallSystemUriOverloads",
-            Justification = "This operator does not intend to represent a Uri overload.")]
-        public JsonPrimitive(string value)
-        {
-            if (value == null)
-            {
-                throw new ArgumentNullException("value");
-            }
-
-            jsonType = JsonType.String;
-            this.value = value;
-        }
-
-        /// <summary>
-        /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.Char"/> type.
-        /// </summary>
-        /// <param name="value">The <see cref="System.Char"/> object that initializes the new instance.</param>
-        /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it.
-        /// When initialized with a <see cref="System.Char"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.String"/>, which can be
-        /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/>
-        /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.Char"/>.</remarks>
-        public JsonPrimitive(char value)
-        {
-            jsonType = JsonType.String;
-            this.value = value;
-        }
-
-        /// <summary>
-        /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.DateTime"/> type.
-        /// </summary>
-        /// <param name="value">The <see cref="System.DateTime"/> object that initializes the new instance.</param>
-        /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it.
-        /// When initialized with a <see cref="System.DateTime"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.String"/>, which can be
-        /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/>
-        /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.DateTime"/>.</remarks>
-        public JsonPrimitive(DateTime value)
-        {
-            jsonType = JsonType.String;
-            this.value = value;
-        }
-
-        /// <summary>
-        /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.DateTimeOffset"/> type.
-        /// </summary>
-        /// <param name="value">The <see cref="System.DateTimeOffset"/> object that initializes the new instance.</param>
-        /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it.
-        /// When initialized with a <see cref="System.DateTimeOffset"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.String"/>, which can be
-        /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/>
-        /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.DateTimeOffset"/>.</remarks>
-        public JsonPrimitive(DateTimeOffset value)
-        {
-            jsonType = JsonType.String;
-            this.value = value;
-        }
-
-        /// <summary>
-        /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.Uri"/> type.
-        /// </summary>
-        /// <param name="value">The <see cref="System.Uri"/> object that initializes the new instance.</param>
-        /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it.
-        /// When initialized with a <see cref="System.Uri"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.String"/>, which can be
-        /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/>
-        /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.Uri"/>.</remarks>
-        /// <exception cref="System.ArgumentNullException">value is null.</exception>
-        public JsonPrimitive(Uri value)
-        {
-            if (value == null)
-            {
-                throw new ArgumentNullException("value");
-            }
-
-            jsonType = JsonType.String;
-            this.value = value;
-        }
-
-        /// <summary>
-        /// Initializes a new instance of a <see cref="System.Json.JsonPrimitive"/> type with a <see cref="System.Guid"/> type.
-        /// </summary>
-        /// <param name="value">The <see cref="System.Guid"/> object that initializes the new instance.</param>
-        /// <remarks>A <see cref="System.Json.JsonPrimitive"/> object stores a <see cref="System.Json.JsonType"/> and the value used to initialize it.
-        /// When initialized with a <see cref="System.Guid"/> object, the <see cref="System.Json.JsonType"/> is a <see cref="F:System.Json.JsonType.String"/>, which can be
-        /// recovered using the <see cref="System.Json.JsonPrimitive.JsonType"/> property. The value used to initialize the <see cref="System.Json.JsonPrimitive"/>
-        /// object can be recovered by casting the <see cref="System.Json.JsonPrimitive"/> to <see cref="System.Guid"/>.</remarks>
-        public JsonPrimitive(Guid value)
-        {
-            jsonType = JsonType.String;
-            this.value = value;
-        }
-
-        private JsonPrimitive(object value, JsonType type)
-        {
-            jsonType = type;
-            this.value = value;
-        }
-
-        private enum ReadAsFailureKind
-        {
-            NoFailure,
-            InvalidCast,
-            InvalidDateFormat,
-            InvalidFormat,
-            InvalidUriFormat,
-            Overflow,
-        }
-
-        /// <summary>
-        /// Gets the JsonType that is associated with this <see cref="System.Json.JsonPrimitive"/> object.
-        /// </summary>
-        public override JsonType JsonType
-        {
-            get { return jsonType; }
-        }
-
-        /// <summary>
-        /// Gets the value represented by this instance.
-        /// </summary>
-        [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods",
-            Justification = "Value in this context clearly refers to the underlying CLR value")]
-        public object Value
-        {
-            get { return value; }
-        }
-
-        /// <summary>
-        /// Attempts to create a <see cref="JsonPrimitive"/> instance from the specified <see cref="object"/> value.
-        /// </summary>
-        /// <param name="value">The <see cref="object"/> value to create the <see cref="JsonPrimitive"/> instance.</param>
-        /// <param name="result">The resulting <see cref="JsonPrimitive"/> instance on success, null otherwise.</param>
-        /// <returns>true if the operation is successful, false otherwise.</returns>
-        public static bool TryCreate(object value, out JsonPrimitive result)
-        {
-            bool allowedType = true;
-            JsonType jsonType = default(JsonType);
-
-            if (value != null)
-            {
-                Type type = value.GetType();
-                switch (Type.GetTypeCode(type))
-                {
-                    case TypeCode.Boolean:
-                        jsonType = JsonType.Boolean;
-                        break;
-                    case TypeCode.Byte:
-                    case TypeCode.SByte:
-                    case TypeCode.Decimal:
-                    case TypeCode.Double:
-                    case TypeCode.Int16:
-                    case TypeCode.Int32:
-                    case TypeCode.Int64:
-                    case TypeCode.UInt16:
-                    case TypeCode.UInt32:
-                    case TypeCode.UInt64:
-                    case TypeCode.Single:
-                        jsonType = JsonType.Number;
-                        break;
-                    case TypeCode.String:
-                    case TypeCode.Char:
-                    case TypeCode.DateTime:
-                        jsonType = JsonType.String;
-                        break;
-                    default:
-                        if (type == typeof(Uri) || type == typeof(Guid) || type == typeof(DateTimeOffset))
-                        {
-                            jsonType = JsonType.String;
-                        }
-                        else
-                        {
-                            allowedType = false;
-                        }
-
-                        break;
-                }
-            }
-            else
-            {
-                allowedType = false;
-            }
-
-            if (allowedType)
-            {
-                result = new JsonPrimitive(value, jsonType);
-                return true;
-            }
-            else
-            {
-                result = null;
-                return false;
-            }
-        }
-
-        /// <summary>
-        /// Attempts to convert this <see cref="System.Json.JsonPrimitive"/> instance into an instance of the specified type.
-        /// </summary>
-        /// <param name="type">The type to which the conversion is being performed.</param>
-        /// <returns>An object instance initialized with the <see cref="System.Json.JsonValue"/> value
-        /// specified if the conversion.</returns>
-        /// <exception cref="System.UriFormatException">If T is <see cref="System.Uri"/> and this value does
-        /// not represent a valid Uri.</exception>
-        /// <exception cref="OverflowException">If T is a numeric type, and a narrowing conversion would result
-        /// in a loss of data. For example, if this instance holds an <see cref="System.Int32"/> value of 10000,
-        /// and T is <see cref="System.Byte"/>, this operation would throw an <see cref="System.OverflowException"/>
-        /// because 10000 is outside the range of the <see cref="System.Byte"/> data type.</exception>
-        /// <exception cref="System.FormatException">If the conversion from the string representation of this
-        /// value into another fails because the string is not in the proper format.</exception>
-        /// <exception cref="System.InvalidCastException">If this instance cannot be read as type T.</exception>
-        public override object ReadAs(Type type)
-        {
-            if (type == null)
-            {
-                throw new ArgumentNullException("type");
-            }
-
-            object result;
-            ReadAsFailureKind failure = TryReadAsInternal(type, out result);
-            if (failure == ReadAsFailureKind.NoFailure)
-            {
-                return result;
-            }
-            else
-            {
-                string valueStr = value.ToString();
-                string typeOfTName = type.Name;
-                switch (failure)
-                {
-                    case ReadAsFailureKind.InvalidFormat:
-                        throw new FormatException(RS.Format(Properties.Resources.CannotReadPrimitiveAsType, valueStr, typeOfTName));
-                    case ReadAsFailureKind.InvalidDateFormat:
-                        throw new FormatException(RS.Format(Properties.Resources.InvalidDateFormat, valueStr, typeOfTName));
-                    case ReadAsFailureKind.InvalidUriFormat:
-                        throw new UriFormatException(RS.Format(Properties.Resources.InvalidUriFormat, jsonPrimitiveType.Name, valueStr, typeOfTName, uriType.Name));
-                    case ReadAsFailureKind.Overflow:
-                        throw new OverflowException(RS.Format(Properties.Resources.OverflowReadAs, valueStr, typeOfTName));
-                    case ReadAsFailureKind.InvalidCast:
-                    default:
-                        throw new InvalidCastException(RS.Format(Properties.Resources.CannotReadPrimitiveAsType, valueStr, typeOfTName));
-                }
-            }
-        }
-
-        /// <summary>
-        /// Attempts to convert this <see cref="System.Json.JsonPrimitive"/> instance into an instance of the specified type.
-        /// </summary>
-        /// <param name="type">The type to which the conversion is being performed.</param>
-        /// <param name="value">An object instance to be initialized with this instance or null if the conversion cannot be performed.</param>
-        /// <returns>true if this <see cref="System.Json.JsonPrimitive"/> instance can be read as the specified type; otherwise, false.</returns>
-        [SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "value",
-            Justification = "field is used with 'this' and arg is out param which makes it harder to be misused.")]
-        public override bool TryReadAs(Type type, out object value)
-        {
-            return TryReadAsInternal(type, out value) == ReadAsFailureKind.NoFailure;
-        }
-
-        /// <summary>
-        /// Returns the value this object wraps (if any).
-        /// </summary>
-        /// <returns>The value wrapped by this instance or null if none.</returns>
-        internal override object Read()
-        {
-            return value;
-        }
-
-        internal override void Save(XmlDictionaryWriter jsonWriter)
-        {
-            if (value == null)
-            {
-                throw new ArgumentNullException("jsonWriter");
-            }
-
-            switch (jsonType)
-            {
-                case JsonType.Boolean:
-                    jsonWriter.WriteAttributeString(JXmlToJsonValueConverter.TypeAttributeName, JXmlToJsonValueConverter.BooleanAttributeValue);
-                    break;
-                case JsonType.Number:
-                    jsonWriter.WriteAttributeString(JXmlToJsonValueConverter.TypeAttributeName, JXmlToJsonValueConverter.NumberAttributeValue);
-                    break;
-                default:
-                    jsonWriter.WriteAttributeString(JXmlToJsonValueConverter.TypeAttributeName, JXmlToJsonValueConverter.StringAttributeValue);
-                    break;
-            }
-
-            WriteValue(jsonWriter);
-        }
-
-        private static ConvertResult StringToBool(string valueString)
-        {
-            ConvertResult result = new ConvertResult();
-            bool tempBool;
-            result.ReadAsFailureKind = Boolean.TryParse(valueString, out tempBool) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidFormat;
-            result.Value = tempBool;
-            return result;
-        }
-
-        private static ConvertResult StringToByte(string valueString)
-        {
-            ConvertResult result = new ConvertResult();
-            byte tempByte;
-            result.ReadAsFailureKind = Byte.TryParse(valueString, out tempByte) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidCast;
-            if (result.ReadAsFailureKind != ReadAsFailureKind.NoFailure)
-            {
-                result.ReadAsFailureKind = StringToNumberConverter<byte>(valueString, out tempByte);
-            }
-
-            result.Value = tempByte;
-            return result;
-        }
-
-        private static ConvertResult StringToChar(string valueString)
-        {
-            ConvertResult result = new ConvertResult();
-            char tempChar;
-            result.ReadAsFailureKind = Char.TryParse(valueString, out tempChar) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidFormat;
-            result.Value = tempChar;
-            return result;
-        }
-
-        private static ConvertResult StringToDecimal(string valueString)
-        {
-            ConvertResult result = new ConvertResult();
-            decimal tempDecimal;
-            result.ReadAsFailureKind = Decimal.TryParse(valueString, NumberStyles.Float, NumberFormatInfo.InvariantInfo, out tempDecimal) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidCast;
-            if (result.ReadAsFailureKind != ReadAsFailureKind.NoFailure)
-            {
-                result.ReadAsFailureKind = StringToNumberConverter<decimal>(valueString, out tempDecimal);
-            }
-
-            result.Value = tempDecimal;
-            return result;
-        }
-
-        private static ConvertResult StringToDateTime(string valueString)
-        {
-            ConvertResult result = new ConvertResult();
-            DateTime tempDateTime;
-            result.ReadAsFailureKind = TryParseDateTime(valueString, out tempDateTime) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidDateFormat;
-            result.Value = tempDateTime;
-            return result;
-        }
-
-        private static ConvertResult StringToDateTimeOffset(string valueString)
-        {
-            ConvertResult result = new ConvertResult();
-            DateTimeOffset tempDateTimeOffset;
-            result.ReadAsFailureKind = TryParseDateTimeOffset(valueString, out tempDateTimeOffset) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidDateFormat;
-            result.Value = tempDateTimeOffset;
-            return result;
-        }
-
-        private static ConvertResult StringToDouble(string valueString)
-        {
-            ConvertResult result = new ConvertResult();
-            double tempDouble;
-            result.ReadAsFailureKind = Double.TryParse(valueString, NumberStyles.Float, NumberFormatInfo.InvariantInfo, out tempDouble) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidCast;
-            if (result.ReadAsFailureKind != ReadAsFailureKind.NoFailure)
-            {
-                result.ReadAsFailureKind = StringToNumberConverter<double>(valueString, out tempDouble);
-            }
-
-            result.Value = tempDouble;
-            return result;
-        }
-
-       private static bool TryGuidParse (string value, out Guid guid)
-       {
-#if NET_4_0
-               return Guid.TryParse (value, out guid);
-#else
-               try {
-                       guid = new Guid (value);
-                       return true;
-               } catch (Exception) {
-                       guid = Guid.Empty;
-                       return false;
-               }
-#endif
-       }
-
-        private static ConvertResult StringToGuid(string valueString)
-        {
-            ConvertResult result = new ConvertResult();
-            Guid tempGuid;
-            result.ReadAsFailureKind = TryGuidParse(valueString, out tempGuid) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidFormat;
-            result.Value = tempGuid;
-            return result;
-        }
-
-        private static ConvertResult StringToShort(string valueString)
-        {
-            ConvertResult result = new ConvertResult();
-            short tempShort;
-            result.ReadAsFailureKind = Int16.TryParse(valueString, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out tempShort) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidCast;
-            if (result.ReadAsFailureKind != ReadAsFailureKind.NoFailure)
-            {
-                result.ReadAsFailureKind = StringToNumberConverter<short>(valueString, out tempShort);
-            }
-
-            result.Value = tempShort;
-            return result;
-        }
-
-        private static ConvertResult StringToInt(string valueString)
-        {
-            ConvertResult result = new ConvertResult();
-            int tempInt;
-            result.ReadAsFailureKind = Int32.TryParse(valueString, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out tempInt) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidCast;
-            if (result.ReadAsFailureKind != ReadAsFailureKind.NoFailure)
-            {
-                result.ReadAsFailureKind = StringToNumberConverter<int>(valueString, out tempInt);
-            }
-
-            result.Value = tempInt;
-            return result;
-        }
-
-        private static ConvertResult StringToLong(string valueString)
-        {
-            ConvertResult result = new ConvertResult();
-            long tempLong;
-            result.ReadAsFailureKind = Int64.TryParse(valueString, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out tempLong) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidCast;
-            if (result.ReadAsFailureKind != ReadAsFailureKind.NoFailure)
-            {
-                result.ReadAsFailureKind = StringToNumberConverter<long>(valueString, out tempLong);
-            }
-
-            result.Value = tempLong;
-            return result;
-        }
-
-        private static ConvertResult StringToSByte(string valueString)
-        {
-            ConvertResult result = new ConvertResult();
-            sbyte tempSByte;
-            result.ReadAsFailureKind = SByte.TryParse(valueString, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out tempSByte) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidCast;
-            if (result.ReadAsFailureKind != ReadAsFailureKind.NoFailure)
-            {
-                result.ReadAsFailureKind = StringToNumberConverter<sbyte>(valueString, out tempSByte);
-            }
-
-            result.Value = tempSByte;
-            return result;
-        }
-
-        private static ConvertResult StringToFloat(string valueString)
-        {
-            ConvertResult result = new ConvertResult();
-            float tempFloat;
-            result.ReadAsFailureKind = Single.TryParse(valueString, NumberStyles.Float, NumberFormatInfo.InvariantInfo, out tempFloat) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidCast;
-            if (result.ReadAsFailureKind != ReadAsFailureKind.NoFailure)
-            {
-                result.ReadAsFailureKind = StringToNumberConverter<float>(valueString, out tempFloat);
-            }
-
-            result.Value = tempFloat;
-            return result;
-        }
-
-        private static ConvertResult StringToUShort(string valueString)
-        {
-            ConvertResult result = new ConvertResult();
-            ushort tempUShort;
-            result.ReadAsFailureKind = UInt16.TryParse(valueString, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out tempUShort) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidCast;
-            if (result.ReadAsFailureKind != ReadAsFailureKind.NoFailure)
-            {
-                result.ReadAsFailureKind = StringToNumberConverter<ushort>(valueString, out tempUShort);
-            }
-
-            result.Value = tempUShort;
-            return result;
-        }
-
-        private static ConvertResult StringToUInt(string valueString)
-        {
-            ConvertResult result = new ConvertResult();
-            uint tempUInt;
-            result.ReadAsFailureKind = UInt32.TryParse(valueString, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out tempUInt) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidCast;
-            if (result.ReadAsFailureKind != ReadAsFailureKind.NoFailure)
-            {
-                result.ReadAsFailureKind = StringToNumberConverter<uint>(valueString, out tempUInt);
-            }
-
-            result.Value = tempUInt;
-            return result;
-        }
-
-        private static ConvertResult StringToULong(string valueString)
-        {
-            ConvertResult result = new ConvertResult();
-            ulong tempULong;
-            result.ReadAsFailureKind = UInt64.TryParse(valueString, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out tempULong) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidCast;
-            if (result.ReadAsFailureKind != ReadAsFailureKind.NoFailure)
-            {
-                result.ReadAsFailureKind = StringToNumberConverter<ulong>(valueString, out tempULong);
-            }
-
-            result.Value = tempULong;
-            return result;
-        }
-
-        private static ConvertResult StringToUri(string valueString)
-        {
-            ConvertResult result = new ConvertResult();
-            Uri tempUri;
-            result.ReadAsFailureKind = Uri.TryCreate(valueString, UriKind.RelativeOrAbsolute, out tempUri) ? ReadAsFailureKind.NoFailure : ReadAsFailureKind.InvalidUriFormat;
-            result.Value = tempUri;
-            return result;
-        }
-
-        private static ReadAsFailureKind StringToNumberConverter<T>(string valueString, out T valueNumber)
-        {
-            string str = valueString.Trim();
-
-            if (str.IndexOfAny(FloatingPointChars) < 0)
-            {
-                long longVal;
-                if (Int64.TryParse(str, NumberStyles.Float, CultureInfo.InvariantCulture, out longVal))
-                {
-                    return NumberToNumberConverter<T>(longVal, out valueNumber);
-                }
-            }
-
-            decimal decValue;
-            if (Decimal.TryParse(str, NumberStyles.Float, CultureInfo.InvariantCulture, out decValue) && decValue != 0)
-            {
-                return NumberToNumberConverter<T>(decValue, out valueNumber);
-            }
-
-            double dblValue;
-            if (Double.TryParse(str, NumberStyles.Float, CultureInfo.InvariantCulture, out dblValue))
-            {
-                return NumberToNumberConverter<T>(dblValue, out valueNumber);
-            }
-
-            valueNumber = default(T);
-            return ReadAsFailureKind.InvalidFormat;
-        }
-
-        private static ReadAsFailureKind NumberToNumberConverter<T>(object valueObject, out T valueNumber)
-        {
-            object value;
-            ReadAsFailureKind failureKind = NumberToNumberConverter(typeof(T), valueObject, out value);
-            if (failureKind == ReadAsFailureKind.NoFailure)
-            {
-                valueNumber = (T)value;
-            }
-            else
-            {
-                valueNumber = default(T);
-            }
-
-            return failureKind;
-        }
-
-        private static ReadAsFailureKind NumberToNumberConverter(Type type, object valueObject, out object valueNumber)
-        {
-            try
-            {
-                valueNumber = System.Convert.ChangeType(valueObject, type, CultureInfo.InvariantCulture);
-                return ReadAsFailureKind.NoFailure;
-            }
-            catch (OverflowException)
-            {
-                valueNumber = null;
-                return ReadAsFailureKind.Overflow;
-            }
-        }
-
-        private static bool TryParseDateTime(string valueString, out DateTime dateTime)
-        {
-            string filteredValue = valueString.EndsWith(UtcString, StringComparison.Ordinal) ? valueString.Replace(UtcString, GmtString) : valueString;
-
-            if (DateTime.TryParse(filteredValue, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out dateTime))
-            {
-                return true;
-            }
-
-            if (TryParseAspNetDateTimeFormat(valueString, out dateTime))
-            {
-                return true;
-            }
-
-            return false;
-        }
-
-        private static bool TryParseDateTimeOffset(string valueString, out DateTimeOffset dateTimeOffset)
-        {
-            string filteredValue = valueString.EndsWith(UtcString, StringComparison.Ordinal) ? valueString.Replace(UtcString, GmtString) : valueString;
-
-            if (DateTimeOffset.TryParse(filteredValue, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out dateTimeOffset))
-            {
-                return true;
-            }
-
-            if (TryParseAspNetDateTimeFormat(valueString, out dateTimeOffset))
-            {
-                return true;
-            }
-
-            return false;
-        }
-
-        private static bool TryParseAspNetDateTimeFormat(string valueString, out DateTime dateTime)
-        {
-            // Reference to the format is available at these sources:
-            // http://msdn.microsoft.com/en-us/library/bb299886.aspx#intro_to_json_sidebarb
-            // http://msdn.microsoft.com/en-us/library/bb412170.aspx
-
-            // The format for the value is given by the following regex:
-            // \/Date\((?<milliseconds>\-?\d+)(?<offset>[\+\-]?\d{4})\)\/
-            // where milliseconds is the number of milliseconds since 1970/01/01:00:00:00.000 UTC (the "unix baseline")
-            // and offset is an optional which indicates whether the value is local or UTC.
-            // The actual value of the offset is ignored, since the ticks represent the UTC offset. The value is converted to local time based on that info.
-            const string DateTimePrefix = "/Date(";
-            const int DateTimePrefixLength = 6;
-            const string DateTimeSuffix = ")/";
-            const int DateTimeSuffixLength = 2;
-
-            if (valueString.StartsWith(DateTimePrefix, StringComparison.Ordinal) && valueString.EndsWith(DateTimeSuffix, StringComparison.Ordinal))
-            {
-                string ticksValue = valueString.Substring(DateTimePrefixLength, valueString.Length - DateTimePrefixLength - DateTimeSuffixLength);
-                DateTimeKind dateTimeKind = DateTimeKind.Utc;
-
-                int indexOfTimeZoneOffset = ticksValue.IndexOf('+', 1);
-
-                if (indexOfTimeZoneOffset < 0)
-                {
-                    indexOfTimeZoneOffset = ticksValue.IndexOf('-', 1);
-                }
-
-                // If an offset is present, verify it is properly formatted. Actual value is ignored (see spec).
-                if (indexOfTimeZoneOffset != -1)
-                {
-                    if (indexOfTimeZoneOffset + 5 == ticksValue.Length
-                        && IsLatinDigit(ticksValue[indexOfTimeZoneOffset + 1])
-                        && IsLatinDigit(ticksValue[indexOfTimeZoneOffset + 2])
-                        && IsLatinDigit(ticksValue[indexOfTimeZoneOffset + 3])
-                        && IsLatinDigit(ticksValue[indexOfTimeZoneOffset + 4]))
-                    {
-                        ticksValue = ticksValue.Substring(0, indexOfTimeZoneOffset);
-                        dateTimeKind = DateTimeKind.Local;
-                    }
-                    else
-                    {
-                        dateTime = new DateTime();
-                        return false;
-                    }
-                }
-
-                long millisecondsSinceUnixEpoch;
-                if (Int64.TryParse(ticksValue, NumberStyles.Integer, CultureInfo.InvariantCulture, out millisecondsSinceUnixEpoch))
-                {
-                    long ticks = (millisecondsSinceUnixEpoch * 10000) + UnixEpochTicks;
-                    if (ticks < DateTime.MaxValue.Ticks)
-                    {
-                        dateTime = new DateTime(ticks, DateTimeKind.Utc);
-                        if (dateTimeKind == DateTimeKind.Local)
-                        {
-                            dateTime = dateTime.ToLocalTime();
-                        }
-
-                        return true;
-                    }
-                }
-            }
-
-            dateTime = new DateTime();
-            return false;
-        }
-
-        private static bool TryParseAspNetDateTimeFormat(string valueString, out DateTimeOffset dateTimeOffset)
-        {
-            DateTime dateTime;
-            if (TryParseAspNetDateTimeFormat(valueString, out dateTime))
-            {
-                dateTimeOffset = new DateTimeOffset(dateTime);
-                return true;
-            }
-
-            dateTimeOffset = new DateTimeOffset();
-            return false;
-        }
-
-        private static bool IsLatinDigit(char c)
-        {
-            return (c >= '0') && (c <= '9');
-        }
-
-        private static string UnescapeJsonString(string val)
-        {
-            if (val == null)
-            {
-                return null;
-            }
-
-            StringBuilder sb = null;
-            int startIndex = 0, count = 0;
-            for (int i = 0; i < val.Length; i++)
-            {
-                if (val[i] == '\\')
-                {
-                    i++;
-                    if (sb == null)
-                    {
-                        sb = new StringBuilder();
-                    }
-
-                    sb.Append(val, startIndex, count);
-#if NET_4_0
-                    Contract.Assert(i < val.Length, "Found that a '\' was the last character in a string, which is invalid JSON. Verify the calling method uses a valid JSON string as the input parameter of this method.");
-#endif
-                    switch (val[i])
-                    {
-                        case '"':
-                        case '\'':
-                        case '/':
-                        case '\\':
-                            sb.Append(val[i]);
-                            break;
-                        case 'b':
-                            sb.Append('\b');
-                            break;
-                        case 'f':
-                            sb.Append('\f');
-                            break;
-                        case 'n':
-                            sb.Append('\n');
-                            break;
-                        case 'r':
-                            sb.Append('\r');
-                            break;
-                        case 't':
-                            sb.Append('\t');
-                            break;
-                        case 'u':
-#if NET_4_0
-                            Contract.Assert((i + 3) < val.Length, String.Format(CultureInfo.CurrentCulture, "Unexpected char {0} at position {1}. The unicode escape sequence should be followed by 4 digits.", val[i], i));
-#endif
-                            sb.Append(ParseChar(val.Substring(i + 1, 4), NumberStyles.HexNumber));
-                            i += 4;
-                            break;
-                    }
-
-                    startIndex = i + 1;
-                    count = 0;
-                }
-                else
-                {
-                    count++;
-                }
-            }
-
-            if (sb == null)
-            {
-                return val;
-            }
-
-            if (count > 0)
-            {
-                sb.Append(val, startIndex, count);
-            }
-
-            return sb.ToString();
-        }
-
-        private static char ParseChar(string value, NumberStyles style)
-        {
-            try
-            {
-                int intValue = Int32.Parse(value, style, NumberFormatInfo.InvariantInfo);
-                return System.Convert.ToChar(intValue);
-            }
-            catch (ArgumentException exception)
-            {
-                throw new InvalidCastException(exception.Message, exception);
-            }
-            catch (FormatException exception)
-            {
-                throw new InvalidCastException(exception.Message, exception);
-            }
-            catch (OverflowException exception)
-            {
-                throw new InvalidCastException(exception.Message, exception);
-            }
-        }
-
-        [SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "value",
-            Justification = "field is used with 'this' and arg is out param which makes it harder to be misused.")]
-        private ReadAsFailureKind TryReadAsInternal(Type type, out object value)
-        {
-            if (base.TryReadAs(type, out value))
-            {
-                return ReadAsFailureKind.NoFailure;
-            }
-
-            if (type == this.value.GetType())
-            {
-                value = this.value;
-                return ReadAsFailureKind.NoFailure;
-            }
-
-            if (jsonType == JsonType.Number)
-            {
-                switch (Type.GetTypeCode(type))
-                {
-                    case TypeCode.Byte:
-                    case TypeCode.SByte:
-                    case TypeCode.Int16:
-                    case TypeCode.Int32:
-                    case TypeCode.Int64:
-                    case TypeCode.UInt16:
-                    case TypeCode.UInt32:
-                    case TypeCode.UInt64:
-                    case TypeCode.Single:
-                    case TypeCode.Double:
-                    case TypeCode.Decimal:
-                        return NumberToNumberConverter(type, this.value, out value);
-                    case TypeCode.String:
-                        value = ToString();
-                        return ReadAsFailureKind.NoFailure;
-                }
-            }
-
-            if (jsonType == JsonType.Boolean)
-            {
-                if (type == typeof(string))
-                {
-                    value = ToString();
-                    return ReadAsFailureKind.NoFailure;
-                }
-            }
-
-            if (jsonType == JsonType.String)
-            {
-                string str = UnescapeJsonString(ToString());
-#if NET_4_0
-                Contract.Assert(str.Length >= 2 && str.StartsWith("\"", StringComparison.Ordinal) && str.EndsWith("\"", StringComparison.Ordinal), "The unescaped string must begin and end with quotes.");
-#endif
-                str = str.Substring(1, str.Length - 2);
-
-                if (stringConverters.ContainsKey(type))
-                {
-                    ConvertResult result = stringConverters[type].Invoke(str);
-                    value = result.Value;
-                    return result.ReadAsFailureKind;
-                }
-
-                if (type == typeof(string))
-                {
-                    value = str;
-                    return ReadAsFailureKind.NoFailure;
-                }
-            }
-
-            value = null;
-            return ReadAsFailureKind.InvalidCast;
-        }
-
-        private void WriteValue(XmlDictionaryWriter jsonWriter)
-        {
-            Type valueType = value.GetType();
-            switch (Type.GetTypeCode(valueType))
-            {
-                case TypeCode.Boolean:
-                    jsonWriter.WriteValue((bool)value);
-                    break;
-                case TypeCode.Byte:
-                case TypeCode.Int16:
-                case TypeCode.Int32:
-                case TypeCode.Int64:
-                case TypeCode.SByte:
-                case TypeCode.UInt16:
-                case TypeCode.UInt32:
-                case TypeCode.UInt64:
-                case TypeCode.Decimal:
-                    jsonWriter.WriteValue(String.Format(CultureInfo.InvariantCulture, "{0}", value));
-                    break;
-                case TypeCode.Single:
-                case TypeCode.Double:
-                    jsonWriter.WriteValue(String.Format(CultureInfo.InvariantCulture, "{0:R}", value));
-                    break;
-                case TypeCode.Char:
-                    jsonWriter.WriteValue(new string((char)value, 1));
-                    break;
-                case TypeCode.String:
-                    jsonWriter.WriteValue((string)value);
-                    break;
-                case TypeCode.DateTime:
-                    jsonWriter.WriteValue(((DateTime)value).ToString(DateTimeIsoFormat, CultureInfo.InvariantCulture));
-                    break;
-                default:
-                    if (valueType == typeof(Uri))
-                    {
-                        Uri uri = (Uri)value;
-                        jsonWriter.WriteValue(uri.GetComponents(UriComponents.SerializationInfoString, UriFormat.UriEscaped));
-                    }
-                    else if (valueType == typeof(DateTimeOffset))
-                    {
-                        jsonWriter.WriteValue(((DateTimeOffset)value).ToString(DateTimeIsoFormat, CultureInfo.InvariantCulture));
-                    }
-                    else
-                    {
-                        jsonWriter.WriteValue(value);
-                    }
-
-                    break;
-            }
-        }
-
-        private class ConvertResult
-        {
-            public ReadAsFailureKind ReadAsFailureKind { get; set; }
-
-            public object Value { get; set; }
-        }
-    }
-}
diff --git a/mcs/class/System.Json-new/JsonType.cs b/mcs/class/System.Json-new/JsonType.cs
deleted file mode 100644 (file)
index eceedd7..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-namespace System.Json
-{
-    /// <summary>
-    /// An enumeration that specifies primitive and structured JavaScript Object 
-    /// Notation (JSON) common language runtime (CLR) types.
-    /// </summary>
-    public enum JsonType
-    {
-        /// <summary>
-        /// Specifies the JSON string CLR type.
-        /// </summary>
-        String,
-
-        /// <summary>
-        /// Specifies the JSON number CLR type.
-        /// </summary>
-        Number,
-
-        /// <summary>
-        /// Specifies the JSON object CLR type that consists of an unordered collection
-        /// of key/value pairs, where the key is of type String and the value is of
-        /// type <see cref="System.Json.JsonValue"/>, which can, in turn, be either a
-        /// primitive or a structured JSON type.
-        /// </summary>
-        Object,
-
-        /// <summary>
-        /// Specifies the JSON array CLR type that consists of an ordered collection of
-        /// <see cref="System.Json.JsonValue"/>types, which can, in turn, be either
-        /// primitive or structured JSON types.
-        /// </summary>
-        Array,
-
-        /// <summary>
-        /// Specifies the JSON Boolean CLR type.
-        /// </summary>
-        Boolean,
-
-        /// <summary>
-        /// Specifies the type returned by calls to <see cref="System.Json.JsonValue.ValueOrDefault(string)"/>
-        /// or <see cref="System.Json.JsonValue.ValueOrDefault(int)"/>
-        /// when the element searches doesn't exist in the JSON collection. This is a special
-        /// value which does not represent any JSON element, and cannot be added to any
-        /// JSON collections.
-        /// </summary>
-        Default
-    }
-}
diff --git a/mcs/class/System.Json-new/JsonValue.cs b/mcs/class/System.Json-new/JsonValue.cs
deleted file mode 100644 (file)
index 2513383..0000000
+++ /dev/null
@@ -1,1247 +0,0 @@
-using System.Collections;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Diagnostics.CodeAnalysis;
-#if NET_4_0 || MONODROID
-using System.Dynamic;
-#endif
-using System.Globalization;
-using System.IO;
-using System.Linq.Expressions;
-using System.Runtime.Serialization;
-using System.Runtime.Serialization.Json;
-using System.Text;
-using System.Xml;
-
-namespace System.Json
-{
-    /// <summary>
-    /// This is the base class for JavaScript Object Notation (JSON) common language runtime (CLR) types. 
-    /// </summary>
-    [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix",
-        Justification = "JsonValue is by definition either a collection or a single object.")]
-    [DataContract]
-#if NET_4_0 || MONODROID
-    public class JsonValue : IEnumerable<KeyValuePair<string, JsonValue>>, IDynamicMetaObjectProvider
-#else
-    public class JsonValue : IEnumerable<KeyValuePair<string, JsonValue>>
-#endif
-    {
-        private static JsonValue defaultInstance = new JsonValue();
-        private int changingListenersCount;
-        private int changedListenersCount;
-
-        internal JsonValue()
-        {
-        }
-
-        /// <summary>
-        /// Raised when this <see cref="System.Json.JsonValue"/> or any of its members have changed.
-        /// </summary>
-        /// <remarks><p>Events are raised when elements are added or removed to <see cref="System.Json.JsonValue"/>
-        /// instances. It applies to both complex descendants of <see cref="System.Json.JsonValue"/>: <see cref="System.Json.JsonArray"/>
-        /// and <see cref="System.Json.JsonObject"/>.</p>
-        /// <p>You should be careful when modifying a <see cref="System.Json.JsonValue"/> tree within one of these events,
-        /// because doing this might lead to unexpected results. For example, if you receive a Changing event, and while
-        /// the event is being processed you remove the node from the tree, you might not receive the Changed event. When
-        /// an event is being processed, it is valid to modify a tree other than the one that contains the node that is
-        /// receiving the event; it is even valid to modify the same tree provided the modifications do not affect the
-        /// specific nodes on which the event was raised. However, if you modify the area of the tree that contains the
-        /// node receiving the event, the events that you receive and the impact to the tree are undefined.</p></remarks>
-        public event EventHandler<JsonValueChangeEventArgs> Changed
-        {
-            add
-            {
-                changedListenersCount++;
-                OnChanged += value;
-            }
-
-            remove
-            {
-                changedListenersCount--;
-                OnChanged -= value;
-            }
-        }
-
-        /// <summary>
-        /// Raised when this <see cref="System.Json.JsonValue"/> or any of its members are about to be changed.
-        /// </summary>
-        /// <remarks><p>Events are raised when elements are added or removed to <see cref="System.Json.JsonValue"/>
-        /// instances. It applies to both complex descendants of <see cref="System.Json.JsonValue"/>: <see cref="System.Json.JsonArray"/>
-        /// and <see cref="System.Json.JsonObject"/>.</p>
-        /// <p>You should be careful when modifying a <see cref="System.Json.JsonValue"/> tree within one of these events,
-        /// because doing this might lead to unexpected results. For example, if you receive a Changing event, and while
-        /// the event is being processed you remove the node from the tree, you might not receive the Changed event. When
-        /// an event is being processed, it is valid to modify a tree other than the one that contains the node that is
-        /// receiving the event; it is even valid to modify the same tree provided the modifications do not affect the
-        /// specific nodes on which the event was raised. However, if you modify the area of the tree that contains the
-        /// node receiving the event, the events that you receive and the impact to the tree are undefined.</p></remarks>
-        public event EventHandler<JsonValueChangeEventArgs> Changing
-        {
-            add
-            {
-                changingListenersCount++;
-                OnChanging += value;
-            }
-
-            remove
-            {
-                changingListenersCount--;
-                OnChanging -= value;
-            }
-        }
-
-        private event EventHandler<JsonValueChangeEventArgs> OnChanged;
-        private event EventHandler<JsonValueChangeEventArgs> OnChanging;
-
-        /// <summary>
-        /// Gets the JSON CLR type represented by this instance.
-        /// </summary>
-        public virtual JsonType JsonType
-        {
-            get { return JsonType.Default; }
-        }
-
-        /// <summary>
-        /// Gets the number of items in this object.
-        /// </summary>
-        public virtual int Count
-        {
-            get { return 0; }
-        }
-
-        /// <summary>
-        /// Gets the number of listeners to the <see cref="Changing"/> event for this instance.
-        /// </summary>
-        protected int ChangingListenersCount
-        {
-            get { return changingListenersCount; }
-        }
-
-        /// <summary>
-        /// Gets the number of listeners to the <see cref="Changed"/> event for this instance.
-        /// </summary>
-        protected int ChangedListenersCount
-        {
-            get { return changedListenersCount; }
-        }
-
-        /// <summary>
-        /// Gets the default JsonValue instance.  
-        /// This instance enables safe-chaining of JsonValue operations and resolves to 'null'
-        /// when this instance is used as dynamic, mapping to the JavaScript 'null' value.
-        /// </summary>
-        private static JsonValue DefaultInstance
-        {
-            get { return defaultInstance; }
-        }
-
-        /// <summary>
-        /// This indexer is not supported for this base class and throws an exception.
-        /// </summary>
-        /// <param name="key">The key of the element to get or set.</param>
-        /// <returns><see cref="System.Json.JsonValue"/>.</returns>
-        /// <remarks>The exception thrown is the <see cref="System.InvalidOperationException"/>.
-        /// This method is overloaded in the implementation of the <see cref="System.Json.JsonObject"/>
-        /// class, which inherits from this class.</remarks>
-        public virtual JsonValue this[string key]
-        {
-            get { throw new InvalidOperationException(RS.Format(Properties.Resources.IndexerNotSupportedOnJsonType, typeof(string), JsonType)); }
-
-            set { throw new InvalidOperationException(RS.Format(Properties.Resources.IndexerNotSupportedOnJsonType, typeof(string), JsonType)); }
-        }
-
-        /// <summary>
-        /// This indexer is not supported for this base class and throws an exception.
-        /// </summary>
-        /// <param name="index">The zero-based index of the element to get or set.</param>
-        /// <returns><see cref="System.Json.JsonValue"/>.</returns>
-        /// <remarks>The exception thrown is the <see cref="System.InvalidOperationException"/>.
-        /// This method is overloaded in the implementation of the <see cref="System.Json.JsonArray"/>
-        /// class, which inherits from this class.</remarks>
-        public virtual JsonValue this[int index]
-        {
-            get { throw new InvalidOperationException(RS.Format(Properties.Resources.IndexerNotSupportedOnJsonType, typeof(int), JsonType)); }
-
-            set { throw new InvalidOperationException(RS.Format(Properties.Resources.IndexerNotSupportedOnJsonType, typeof(int), JsonType)); }
-        }
-
-        /// <summary>
-        /// Deserializes text-based JSON into a JSON CLR type.
-        /// </summary>
-        /// <param name="json">The text-based JSON to be parsed into a JSON CLR type.</param>
-        /// <returns>The <see cref="System.Json.JsonValue"/> object that represents the parsed
-        /// text-based JSON as a CLR type.</returns>
-        /// <exception cref="System.ArgumentException">The length of jsonString is zero.</exception>
-        /// <exception cref="System.ArgumentNullException">jsonString is null.</exception>
-        /// <remarks>The result will be an instance of either <see cref="System.Json.JsonArray"/>,
-        /// <see cref="System.Json.JsonObject"/> or <see cref="System.Json.JsonPrimitive"/>,
-        /// depending on the text-based JSON supplied to the method.</remarks>
-        public static JsonValue Parse(string json)
-        {
-            return JXmlToJsonValueConverter.JXMLToJsonValue(json);
-        }
-
-        /// <summary>
-        /// Deserializes text-based JSON from a text reader into a JSON CLR type.
-        /// </summary>
-        /// <param name="textReader">A <see cref="System.IO.TextReader"/> over text-based JSON content.</param>
-        /// <returns>The <see cref="System.Json.JsonValue"/> object that represents the parsed
-        /// text-based JSON as a CLR type.</returns>
-        /// <exception cref="System.ArgumentNullException">textReader is null.</exception>
-        /// <remarks>The result will be an instance of either <see cref="System.Json.JsonArray"/>,
-        /// <see cref="System.Json.JsonObject"/> or <see cref="System.Json.JsonPrimitive"/>,
-        /// depending on the text-based JSON supplied to the method.</remarks>
-        public static JsonValue Load(TextReader textReader)
-        {
-            if (textReader == null)
-            {
-                throw new ArgumentNullException("textReader");
-            }
-
-            return JsonValue.Parse(textReader.ReadToEnd());
-        }
-
-        /// <summary>
-        /// Deserializes text-based JSON from a stream into a JSON CLR type.
-        /// </summary>
-        /// <param name="stream">A <see cref="System.IO.Stream"/> that contains text-based JSON content.</param>
-        /// <returns>The <see cref="System.Json.JsonValue"/> object that represents the parsed
-        /// text-based JSON as a CLR type.</returns>
-        /// <exception cref="System.ArgumentNullException">stream is null.</exception>
-        /// <remarks>The result will be an instance of either <see cref="System.Json.JsonArray"/>,
-        /// <see cref="System.Json.JsonObject"/> or <see cref="System.Json.JsonPrimitive"/>,
-        /// depending on the text-based JSON supplied to the method.</remarks>
-        public static JsonValue Load(Stream stream)
-        {
-            return JXmlToJsonValueConverter.JXMLToJsonValue(stream);
-        }
-
-        /// <summary>
-        /// Performs a cast operation from a <see cref="JsonValue"/> instance into the specified type parameter./>
-        /// </summary>
-        /// <typeparam name="T">The type to cast the instance to.</typeparam>
-        /// <param name="value">The <see cref="System.Json.JsonValue"/> instance.</param>
-        /// <returns>An object of type T initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns>
-        /// <remarks>This method is to support the framework and is not intended to be used externally, use explicit type cast instead.</remarks>
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter",
-            Justification = "The generic parameter is used to specify the output type")]
-        public static T CastValue<T>(JsonValue value)
-        {
-            Type typeofT = typeof(T);
-
-            if ((value != null && typeofT.IsAssignableFrom(value.GetType())) || typeofT == typeof(object))
-            {
-                return (T)(object)value;
-            }
-
-            if (value == null || value.JsonType == JsonType.Default)
-            {
-                if (typeofT.IsValueType)
-                {
-                    throw new InvalidCastException(RS.Format(Properties.Resources.InvalidCastNonNullable, typeofT.FullName));
-                }
-                else
-                {
-                    return default(T);
-                }
-            }
-
-            try
-            {
-                return value.ReadAs<T>();
-            }
-            catch (Exception ex)
-            {
-                if (ex is FormatException || ex is NotSupportedException || ex is InvalidCastException)
-                {
-                    throw new InvalidCastException(RS.Format(Properties.Resources.CannotCastJsonValue, value.GetType().FullName, typeofT.FullName), ex);
-                }
-
-                throw;
-            }
-        }
-
-        /// <summary>
-        /// Returns an enumerator which iterates through the values in this object.
-        /// </summary>
-        /// <returns>An enumerator which which iterates through the values in this object.</returns>
-        /// <remarks>The enumerator returned by this class is empty; subclasses will override this method to return appropriate enumerators for themselves.</remarks>
-        public IEnumerator<KeyValuePair<string, JsonValue>> GetEnumerator()
-        {
-            return GetKeyValuePairEnumerator();
-        }
-
-        /// <summary>
-        /// Returns an enumerator which iterates through the values in this object.
-        /// </summary>
-        /// <returns>An <see cref="System.Collections.IEnumerator"/> which iterates through the values in this object.</returns>
-        /// <remarks>The enumerator returned by this class is empty; subclasses will override this method to return appropriate enumerators for themselves.</remarks>
-        IEnumerator IEnumerable.GetEnumerator()
-        {
-            return GetKeyValuePairEnumerator();
-        }
-
-#if NET_4_0 || MONODROID
-        /// <summary>
-        /// Gets this instance as a <code>dynamic</code> object.
-        /// </summary>
-        /// <returns>This instance as <code>dynamic</code>.</returns>
-        public dynamic AsDynamic()
-        {
-            return this;
-        }
-#endif
-
-        /// <summary>
-        /// Attempts to convert this <see cref="System.Json.JsonValue"/> instance into the type T.
-        /// </summary>
-        /// <typeparam name="T">The type to which the conversion is being performed.</typeparam>
-        /// <param name="valueOfT">An instance of T initialized with this instance, or the default value of T if the conversion cannot be performed.</param>
-        /// <returns>true if this <see cref="System.Json.JsonValue"/> instance can be read as type T; otherwise, false.</returns>
-        public bool TryReadAs<T>(out T valueOfT)
-        {
-            object value;
-            if (TryReadAs(typeof(T), out value))
-            {
-                valueOfT = (T)value;
-                return true;
-            }
-
-            valueOfT = default(T);
-            return false;
-        }
-
-        /// <summary>
-        /// Attempts to convert this <see cref="System.Json.JsonValue"/> instance into the type T.
-        /// </summary>
-        /// <typeparam name="T">The type to which the conversion is being performed.</typeparam>
-        /// <returns>An instance of T initialized with the value from the conversion of this instance.</returns>
-        /// <exception cref="System.NotSupportedException">If this <see cref="System.Json.JsonValue"/> value cannot be converted into the type T.</exception>
-        [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter",
-            Justification = "The generic parameter is used to specify the output type")]
-        public T ReadAs<T>()
-        {
-            return (T)ReadAs(typeof(T));
-        }
-
-        /// <summary>
-        /// Attempts to convert this <see cref="System.Json.JsonValue"/> instance into the type T.
-        /// </summary>
-        /// <typeparam name="T">The type to which the conversion is being performed.</typeparam>
-        /// <param name="fallback">The fallback value to be returned if the conversion cannot be made.</param>
-        /// <returns>An instance of T initialized with the value from the conversion of this instance, or the specified fallback value if the conversion cannot be made.</returns>
-        public T ReadAs<T>(T fallback)
-        {
-            return (T)ReadAs(typeof(T), fallback);
-        }
-
-        /// <summary>
-        /// Attempts to convert this <see cref="System.Json.JsonValue"/> instance to an instance of the specified type.
-        /// </summary>
-        /// <param name="type">The type to which the conversion is being performed.</param>
-        /// <param name="fallback">The fallback value to be returned if the conversion cannot be made.</param>
-        /// <returns>An instance of the specified type initialized with the value from the conversion of this instance, or the specified fallback value if the conversion cannot be made.</returns>
-        public object ReadAs(Type type, object fallback)
-        {
-            if (type == null)
-            {
-                throw new ArgumentNullException("type");
-            }
-
-            object result;
-            if (JsonType != JsonType.Default && TryReadAs(type, out result))
-            {
-                return result;
-            }
-            else
-            {
-                return fallback;
-            }
-        }
-
-        /// <summary>
-        /// Attempts to convert this <see cref="System.Json.JsonValue"/> instance into an instance of the specified type.
-        /// </summary>
-        /// <param name="type">The type to which the conversion is being performed.</param>
-        /// <returns>An instance of the specified type initialized with the value from the conversion of this instance.</returns>
-        /// <exception cref="System.NotSupportedException">If this <see cref="System.Json.JsonValue"/> value cannot be converted into the type T.</exception>
-        public virtual object ReadAs(Type type)
-        {
-            if (type == null)
-            {
-                throw new ArgumentNullException("type");
-            }
-
-            object result;
-            if (TryReadAs(type, out result))
-            {
-                return result;
-            }
-
-            throw new NotSupportedException(RS.Format(Properties.Resources.CannotReadAsType, GetType().FullName, type.FullName));
-        }
-
-        /// <summary>
-        /// Attempts to convert this <see cref="System.Json.JsonValue"/> instance into an instance of the specified type.
-        /// </summary>
-        /// <param name="type">The type to which the conversion is being performed.</param>
-        /// <param name="value">An object to be initialized with this instance or null if the conversion cannot be performed.</param>
-        /// <returns>true if this <see cref="System.Json.JsonValue"/> instance can be read as the specified type; otherwise, false.</returns>
-        [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate",
-            Justification = "This is the non-generic version of the method.")]
-        public virtual bool TryReadAs(Type type, out object value)
-        {
-            if (type == null)
-            {
-                throw new ArgumentNullException("type");
-            }
-
-            if (type.IsAssignableFrom(GetType()) || type == typeof(object))
-            {
-                value = this;
-                return true;
-            }
-
-            value = null;
-            return false;
-        }
-
-        /// <summary>
-        /// Writes this <see cref="System.Json.JsonValue"/> instance to a <see cref="System.IO.Stream"/>.
-        /// </summary>
-        /// <param name="stream">Stream to which to write text-based JSON.</param>
-        public void Save(Stream stream)
-        {
-            if (JsonType == JsonType.Default)
-            {
-                throw new InvalidOperationException(Properties.Resources.UseOfDefaultNotAllowed);
-            }
-
-            if (stream == null)
-            {
-                throw new ArgumentNullException("stream");
-            }
-
-            using (XmlDictionaryWriter jsonWriter = JsonReaderWriterFactory.CreateJsonWriter(stream, Encoding.UTF8, false))
-            {
-                jsonWriter.WriteStartElement(JXmlToJsonValueConverter.RootElementName);
-                Save(jsonWriter);
-                jsonWriter.WriteEndElement();
-            }
-        }
-
-        /// <summary>
-        /// Writes <see cref="System.Json.JsonValue"/> instance to a <see cref="TextWriter"/>.
-        /// </summary>
-        /// <param name="textWriter">The <see cref="System.IO.TextWriter"/> used to write text-based JSON.</param>
-        public void Save(TextWriter textWriter)
-        {
-            if (JsonType == JsonType.Default)
-            {
-                throw new InvalidOperationException(Properties.Resources.UseOfDefaultNotAllowed);
-            }
-
-            if (textWriter == null)
-            {
-                throw new ArgumentNullException("textWriter");
-            }
-
-            using (MemoryStream ms = new MemoryStream())
-            {
-                Save(ms);
-                ms.Position = 0;
-                textWriter.Write(new StreamReader(ms).ReadToEnd());
-            }
-        }
-
-        /// <summary>
-        /// Provides a textual representation of this <see cref="System.Json.JsonValue"/> instance.
-        /// </summary>
-        /// <returns>A <see cref="System.String"/> containing text-based JSON.</returns>
-        public override string ToString()
-        {
-            if (JsonType == JsonType.Default)
-            {
-                return "Default";
-            }
-
-            using (MemoryStream ms = new MemoryStream())
-            {
-                Save(ms);
-                ms.Position = 0;
-                return new StreamReader(ms).ReadToEnd();
-            }
-        }
-
-        /// <summary>
-        /// Checks whether a key/value pair with a specified key exists in the JSON CLR object type.
-        /// </summary>
-        /// <param name="key">The key to check for.</param>
-        /// <returns>false in this class; subclasses may override this method to return other values.</returns>
-        /// <remarks>This method is overloaded in the implementation of the <see cref="System.Json.JsonObject"/>
-        /// class, which inherits from this class.</remarks>
-        public virtual bool ContainsKey(string key)
-        {
-            return false;
-        }
-
-        /// <summary>
-        /// Returns the value returned by the safe string indexer for this instance.
-        /// </summary>
-        /// <param name="key">The key of the element to get.</param>
-        /// <returns>If this is an instance of <see cref="System.Json.JsonObject"/>, it contains
-        /// the given key and the value corresponding to the key is not null, then it will return that value.
-        /// Otherwise it will return a <see cref="System.Json.JsonValue"/> instance with <see cref="System.Json.JsonValue.JsonType"/>
-        /// equals to <see cref="F:System.Json.JsonType.Default"/>.</returns>
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public virtual JsonValue GetValue(string key)
-        {
-            return ValueOrDefault(key);
-        }
-
-        /// <summary>
-        /// Returns the value returned by the safe int indexer for this instance.
-        /// </summary>
-        /// <param name="index">The zero-based index of the element to get.</param>
-        /// <returns>If this is an instance of <see cref="System.Json.JsonArray"/>, the index is within the array
-        /// bounds, and the value corresponding to the index is not null, then it will return that value.
-        /// Otherwise it will return a <see cref="System.Json.JsonValue"/> instance with <see cref="System.Json.JsonValue.JsonType"/>
-        /// equals to <see cref="F:System.Json.JsonType.Default"/>.</returns>
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public virtual JsonValue GetValue(int index)
-        {
-            return ValueOrDefault(index);
-        }
-
-        /// <summary>
-        /// Sets the value and returns it.
-        /// </summary>
-        /// <param name="key">The key of the element to set.</param>
-        /// <param name="value">The value to be set.</param>
-        /// <returns>The value, converted into a JsonValue, set in this collection.</returns>
-        /// <exception cref="System.ArgumentException">If the value cannot be converted into a JsonValue.</exception>
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public virtual JsonValue SetValue(string key, object value)
-        {
-            this[key] = ResolveObject(value);
-            return this[key];
-        }
-
-        /// <summary>
-        /// Sets the value and returns it.
-        /// </summary>
-        /// <param name="index">The zero-based index of the element to set.</param>
-        /// <param name="value">The value to be set.</param>
-        /// <returns>The value, converted into a JsonValue, set in this collection.</returns>
-        /// <exception cref="System.ArgumentException">If the value cannot be converted into a JsonValue.</exception>
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public virtual JsonValue SetValue(int index, object value)
-        {
-            this[index] = ResolveObject(value);
-            return this[index];
-        }
-
-        /// <summary>
-        /// Safe string indexer for the <see cref="System.Json.JsonValue"/> type. 
-        /// </summary>
-        /// <param name="key">The key of the element to get.</param>
-        /// <returns>If this is an instance of <see cref="System.Json.JsonObject"/>, it contains
-        /// the given key and the value corresponding to the key is not null, then it will return that value.
-        /// Otherwise it will return a <see cref="System.Json.JsonValue"/> instance with <see cref="System.Json.JsonValue.JsonType"/>
-        /// equals to <see cref="F:System.Json.JsonType.Default"/>.</returns>
-        public virtual JsonValue ValueOrDefault(string key)
-        {
-            return JsonValue.DefaultInstance;
-        }
-
-        /// <summary>
-        /// Safe indexer for the <see cref="System.Json.JsonValue"/> type. 
-        /// </summary>
-        /// <param name="index">The zero-based index of the element to get.</param>
-        /// <returns>If this is an instance of <see cref="System.Json.JsonArray"/>, the index is within the array
-        /// bounds, and the value corresponding to the index is not null, then it will return that value.
-        /// Otherwise it will return a <see cref="System.Json.JsonValue"/> instance with <see cref="System.Json.JsonValue.JsonType"/>
-        /// equals to <see cref="F:System.Json.JsonType.Default"/>.</returns>
-        public virtual JsonValue ValueOrDefault(int index)
-        {
-            return JsonValue.DefaultInstance;
-        }
-
-        /// <summary>
-        /// Safe deep indexer for the <see cref="JsonValue"/> type.
-        /// </summary>
-        /// <param name="indexes">The indices to index this type. The indices can be
-        /// of type <see cref="System.Int32"/> or <see cref="System.String"/>.</param>
-        /// <returns>A <see cref="JsonValue"/> which is equivalent to calling<see cref="ValueOrDefault(int)"/> or
-        /// <see cref="ValueOrDefault(string)"/> on the first index, then calling it again on the result
-        /// for the second index and so on.</returns>
-        /// <exception cref="System.ArgumentException">If any of the indices is not of type
-        /// <see cref="System.Int32"/> or <see cref="System.String"/>.</exception>
-        public JsonValue ValueOrDefault(params object[] indexes)
-        {
-            if (indexes == null)
-            {
-                return JsonValue.DefaultInstance;
-            }
-
-            if (indexes.Length == 0)
-            {
-                return this;
-            }
-
-            JsonValue result = this;
-            for (int i = 0; i < indexes.Length; i++)
-            {
-                object index = indexes[i];
-                if (index == null)
-                {
-                    result = JsonValue.DefaultInstance;
-                    continue;
-                }
-
-                Type indexType = index.GetType();
-
-                switch (Type.GetTypeCode(indexType))
-                {
-                    case TypeCode.Char:
-                    case TypeCode.Int16:
-                    case TypeCode.UInt16:
-                    case TypeCode.Byte:
-                    case TypeCode.SByte:
-                        index = System.Convert.ChangeType(index, typeof(int), CultureInfo.InvariantCulture);
-                        goto case TypeCode.Int32;
-
-                    case TypeCode.Int32:
-                        result = result.ValueOrDefault((int)index);
-                        break;
-
-                    case TypeCode.String:
-                        result = result.ValueOrDefault((string)index);
-                        break;
-
-                    default:
-                        throw new ArgumentException(RS.Format(Properties.Resources.InvalidIndexType, index.GetType()), "indexes");
-                }
-            }
-
-            return result;
-        }
-
-#if NET_4_0 || MONODROID
-        [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes",
-            Justification = "Cannot make this class sealed, it needs to have subclasses. But its subclasses are sealed themselves.")]
-        DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter)
-        {
-            if (parameter == null)
-            {
-                throw new ArgumentNullException("parameter");
-            }
-
-            return new JsonValueDynamicMetaObject(parameter, this);
-        }
-#endif
-
-        /// <summary>
-        /// Resolves the specified object to an appropriate JsonValue instance.
-        /// </summary>
-        /// <param name="value">The object to resolve.</param>
-        /// <returns>A <see cref="JsonValue"/> instance resolved from the specified object.</returns>
-        internal static JsonValue ResolveObject(object value)
-        {
-            JsonPrimitive primitive;
-
-            if (value == null)
-            {
-                return null;
-            }
-
-            JsonValue jsonValue = value as JsonValue;
-
-            if (jsonValue != null)
-            {
-                return jsonValue;
-            }
-
-            if (JsonPrimitive.TryCreate(value, out primitive))
-            {
-                return primitive;
-            }
-
-            throw new ArgumentException(Properties.Resources.TypeNotSupported, "value");
-        }
-
-        /// <summary>
-        /// Determines whether an explicit cast to JsonValue is provided from the specified type.
-        /// </summary>
-        /// <param name="type">The type to check.</param>
-        /// <returns>true if an explicit cast exists for the specified type, false otherwise.</returns>
-        internal static bool IsSupportedExplicitCastType(Type type)
-        {
-            TypeCode typeCode = Type.GetTypeCode(type);
-
-            switch (typeCode)
-            {
-                case TypeCode.Boolean:
-                case TypeCode.Byte:
-                case TypeCode.Char:
-                case TypeCode.DateTime:
-                case TypeCode.Decimal:
-                case TypeCode.Double:
-                case TypeCode.Int16:
-                case TypeCode.Int32:
-                case TypeCode.Int64:
-                case TypeCode.SByte:
-                case TypeCode.Single:
-                case TypeCode.String:
-                case TypeCode.UInt16:
-                case TypeCode.UInt32:
-                case TypeCode.UInt64:
-                    return true;
-
-                default:
-                    return type == typeof(DateTimeOffset) || type == typeof(Guid) || type == typeof(Uri) ||
-                           type == typeof(List<object>) || type == typeof(Array) || type == typeof(object[]) ||
-                           type == typeof(Dictionary<string, object>);
-            }
-        }
-
-        /// <summary>
-        /// Returns the value this object wraps (if any).
-        /// </summary>
-        /// <returns>The value wrapped by this instance or null if none.</returns>
-        internal virtual object Read()
-        {
-            return null;
-        }
-
-        /// <summary>
-        /// Serializes this object into the specified <see cref="XmlDictionaryWriter"/> instance.
-        /// </summary>
-        /// <param name="jsonWriter">An <see cref="XmlDictionaryWriter"/> instance to serialize this instance into.</param>
-        internal virtual void Save(XmlDictionaryWriter jsonWriter)
-        {
-            if (jsonWriter == null)
-            {
-                throw new ArgumentNullException("jsonWriter");
-            }
-
-            Stack<JsonValue> objectStack = new Stack<JsonValue>();
-            Stack<int> indexStack = new Stack<int>();
-            int currentIndex = 0;
-            JsonValue currentValue = this;
-
-            OnSaveStarted();
-
-            WriteAttributeString(jsonWriter);
-
-            while (currentIndex < currentValue.Count || objectStack.Count > 0)
-            {
-                if (currentValue.Count > currentIndex)
-                {
-                    JsonValue nextValue = currentValue.WriteStartElementAndGetNext(jsonWriter, currentIndex);
-
-                    if (JsonValue.IsJsonCollection(nextValue))
-                    {
-                        nextValue.OnSaveStarted();
-                        nextValue.WriteAttributeString(jsonWriter);
-
-                        objectStack.Push(currentValue);
-                        indexStack.Push(currentIndex);
-                        currentValue = nextValue;
-                        currentIndex = 0;
-                    }
-                    else
-                    {
-                        if (nextValue == null)
-                        {
-                            jsonWriter.WriteAttributeString(JXmlToJsonValueConverter.TypeAttributeName, JXmlToJsonValueConverter.NullAttributeValue);
-                        }
-                        else
-                        {
-                            nextValue.Save(jsonWriter);
-                        }
-
-                        currentIndex++;
-                        jsonWriter.WriteEndElement();
-                    }
-                }
-                else
-                {
-                    if (objectStack.Count > 0)
-                    {
-                        currentValue.OnSaveEnded();
-                        jsonWriter.WriteEndElement();
-
-                        currentValue = objectStack.Pop();
-                        currentIndex = indexStack.Pop() + 1;
-                    }
-                }
-            }
-
-            OnSaveEnded();
-        }
-
-        /// <summary>
-        /// Returns an enumerator which iterates through the values in this object.
-        /// </summary>
-        /// <returns>An <see cref="System.Collections.IEnumerator"/> which iterates through the values in this object.</returns>
-        /// <remarks>This method is the virtual version of the IEnumerator.GetEnumerator method and is provided to allow derived classes to implement the 
-        /// appropriate version of the generic interface (enumerator of values or key/value pairs).</remarks>
-        [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate",
-            Justification = "This method is a virtual version of the IEnumerable.GetEnumerator method.")]
-        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures",
-            Justification = "This class is a collection that is properly represented by the nested generic type.")]
-        protected virtual IEnumerator<KeyValuePair<string, JsonValue>> GetKeyValuePairEnumerator()
-        {
-            yield break;
-        }
-
-        /// <summary>
-        /// Callback method called during Save operations to let the instance write the start element
-        /// and return the next element in the collection.
-        /// </summary>
-        /// <param name="jsonWriter">The JXML writer used to write JSON.</param>
-        /// <param name="index">The index within this collection.</param>
-        /// <returns>The next item in the collection, or null of there are no more items.</returns>
-        internal virtual JsonValue WriteStartElementAndGetNext(XmlDictionaryWriter jsonWriter, int index)
-        {
-            return null;
-        }
-
-        /// <summary>
-        /// Callback method called to let an instance write the proper JXML attribute when saving this
-        /// instance.
-        /// </summary>
-        /// <param name="jsonWriter">The JXML writer used to write JSON.</param>
-        internal virtual void WriteAttributeString(XmlDictionaryWriter jsonWriter)
-        {
-        }
-
-        /// <summary>
-        /// Callback method called when a Save operation is starting for this instance.
-        /// </summary>
-        protected virtual void OnSaveStarted()
-        {
-        }
-
-        /// <summary>
-        /// Callback method called when a Save operation is finished for this instance.
-        /// </summary>
-        protected virtual void OnSaveEnded()
-        {
-        }
-
-        /// <summary>
-        /// Called internally to raise the <see cref="Changing"/> event.
-        /// </summary>
-        /// <param name="sender">The object which caused the event to be raised.</param>
-        /// <param name="eventArgs">The arguments to the event.</param>
-        [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate",
-            Justification = "This is a helper function used to raise the event.")]
-        [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers",
-            Justification = "This is not externally visible, since the constructor for this class is internal (cannot be directly derived) and all its subclasses are sealed.")]
-        protected void RaiseChangingEvent(object sender, JsonValueChangeEventArgs eventArgs)
-        {
-            EventHandler<JsonValueChangeEventArgs> changing = OnChanging;
-            if (changing != null)
-            {
-                changing(sender, eventArgs);
-            }
-        }
-
-        /// <summary>
-        /// Called internally to raise the <see cref="Changed"/> event.
-        /// </summary>
-        /// <param name="sender">The object which caused the event to be raised.</param>
-        /// <param name="eventArgs">The arguments to the event.</param>
-        [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate",
-            Justification = "This is a helper function used to raise the event.")]
-        [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers",
-            Justification = "This is not externally visible, since the constructor for this class is internal (cannot be directly derived) and all its subclasses are sealed.")]
-        protected void RaiseChangedEvent(object sender, JsonValueChangeEventArgs eventArgs)
-        {
-            EventHandler<JsonValueChangeEventArgs> changed = OnChanged;
-            if (changed != null)
-            {
-                changed(sender, eventArgs);
-            }
-        }
-
-        private static bool IsJsonCollection(JsonValue value)
-        {
-            return value != null && (value.JsonType == JsonType.Array || value.JsonType == JsonType.Object);
-        }
-
-        /// <summary>
-        /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.String"/> object.
-        /// </summary>
-        /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.String"/> object.</param>
-        /// <returns>The <see cref="System.String"/> initialized with the <see cref="System.Json.JsonValue"/> value specified or null if value is null.</returns>
-        public static explicit operator string(JsonValue value)
-        {
-            return CastValue<string>(value);
-        }
-
-        /// <summary>
-        /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Double"/> object.
-        /// </summary>
-        /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Double"/> object.</param>
-        /// <returns>The <see cref="System.Double"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns>
-        public static explicit operator double(JsonValue value)
-        {
-            return CastValue<double>(value);
-        }
-
-        /// <summary>
-        /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Single"/> object.
-        /// </summary>
-        /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Single"/> object.</param>
-        /// <returns>The <see cref="System.Single"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns>
-        public static explicit operator float(JsonValue value)
-        {
-            return CastValue<float>(value);
-        }
-
-        /// <summary>
-        /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Decimal"/> object.
-        /// </summary>
-        /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Decimal"/> object.</param>
-        /// <returns>The <see cref="System.Decimal"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns>
-        public static explicit operator decimal(JsonValue value)
-        {
-            return CastValue<decimal>(value);
-        }
-
-        /// <summary>
-        /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Int64"/> object.
-        /// </summary>
-        /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Int64"/> object.</param>
-        /// <returns>The <see cref="System.Int64"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns>
-        public static explicit operator long(JsonValue value)
-        {
-            return CastValue<long>(value);
-        }
-
-        /// <summary>
-        /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.UInt64"/> object.
-        /// </summary>
-        /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.UInt64"/> object.</param>
-        /// <returns>The <see cref="System.UInt64"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns>
-        [CLSCompliant(false)]
-        public static explicit operator ulong(JsonValue value)
-        {
-            return CastValue<ulong>(value);
-        }
-
-        /// <summary>
-        /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Int32"/> object.
-        /// </summary>
-        /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Int32"/> object.</param>
-        /// <returns>The <see cref="System.Int32"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns>
-        public static explicit operator int(JsonValue value)
-        {
-            return CastValue<int>(value);
-        }
-
-        /// <summary>
-        /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.UInt32"/> object.
-        /// </summary>
-        /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.UInt32"/> object.</param>
-        /// <returns>The <see cref="System.UInt32"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns>
-        [CLSCompliant(false)]
-        public static explicit operator uint(JsonValue value)
-        {
-            return CastValue<uint>(value);
-        }
-
-        /// <summary>
-        /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Int16"/> object.
-        /// </summary>
-        /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Int16"/> object.</param>
-        /// <returns>The <see cref="System.Int16"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns>
-        public static explicit operator short(JsonValue value)
-        {
-            return CastValue<short>(value);
-        }
-
-        /// <summary>
-        /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.UInt16"/> object.
-        /// </summary>
-        /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.UInt16"/> object.</param>
-        /// <returns>The <see cref="System.UInt16"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns>
-        [CLSCompliant(false)]
-        public static explicit operator ushort(JsonValue value)
-        {
-            return CastValue<ushort>(value);
-        }
-
-        /// <summary>
-        /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.SByte"/> object.
-        /// </summary>
-        /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.SByte"/> object.</param>
-        /// <returns>The <see cref="System.SByte"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns>
-        [CLSCompliant(false)]
-        public static explicit operator sbyte(JsonValue value)
-        {
-            return CastValue<sbyte>(value);
-        }
-
-        /// <summary>
-        /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Byte"/> object.
-        /// </summary>
-        /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Byte"/> object.</param>
-        /// <returns>The <see cref="System.Byte"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns>
-        public static explicit operator byte(JsonValue value)
-        {
-            return CastValue<byte>(value);
-        }
-
-        /// <summary>
-        /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Uri"/> object.
-        /// </summary>
-        /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Uri"/> object.</param>
-        /// <returns>The <see cref="System.Uri"/> initialized with the <see cref="System.Json.JsonValue"/> value specified or null if value is null.</returns>
-        public static explicit operator Uri(JsonValue value)
-        {
-            return CastValue<Uri>(value);
-        }
-
-        /// <summary>
-        /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Guid"/> object.
-        /// </summary>
-        /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Guid"/> object.</param>
-        /// <returns>The <see cref="System.Guid"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns>
-        public static explicit operator Guid(JsonValue value)
-        {
-            return CastValue<Guid>(value);
-        }
-
-        /// <summary>
-        /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.DateTime"/> object.
-        /// </summary>
-        /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.DateTime"/> object.</param>
-        /// <returns>The <see cref="System.DateTime"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns>
-        public static explicit operator DateTime(JsonValue value)
-        {
-            return CastValue<DateTime>(value);
-        }
-
-        /// <summary>
-        /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Char"/> object.
-        /// </summary>
-        /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Char"/> object.</param>
-        /// <returns>The <see cref="System.Char"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns>
-        public static explicit operator char(JsonValue value)
-        {
-            return CastValue<char>(value);
-        }
-
-        /// <summary>
-        /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.Boolean"/> object.
-        /// </summary>
-        /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.Boolean"/> object.</param>
-        /// <returns>The <see cref="System.Boolean"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns>
-        public static explicit operator bool(JsonValue value)
-        {
-            return CastValue<bool>(value);
-        }
-
-        /// <summary>
-        /// Enables explicit casts from an instance of type <see cref="System.Json.JsonValue"/> to a <see cref="System.DateTimeOffset"/> object.
-        /// </summary>
-        /// <param name="value">The instance of <see cref="System.Json.JsonValue"/> used to initialize the <see cref="System.DateTimeOffset"/> object.</param>
-        /// <returns>The <see cref="System.DateTimeOffset"/> initialized with the <see cref="System.Json.JsonValue"/> value specified.</returns>
-        public static explicit operator DateTimeOffset(JsonValue value)
-        {
-            return CastValue<DateTimeOffset>(value);
-        }
-
-        /// <summary>
-        /// Enables implicit casts from type <see cref="System.Boolean"/> to a <see cref="System.Json.JsonPrimitive"/>.
-        /// </summary>
-        /// <param name="value">The <see cref="System.Boolean"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param>
-        /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Boolean"/> specified.</returns>
-        public static implicit operator JsonValue(bool value)
-        {
-            return new JsonPrimitive(value);
-        }
-
-        /// <summary>
-        /// Enables implicit casts from type <see cref="System.Byte"/> to a <see cref="System.Json.JsonPrimitive"/>.
-        /// </summary>
-        /// <param name="value">The <see cref="System.Byte"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param>
-        /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Byte"/> specified.</returns>
-        public static implicit operator JsonValue(byte value)
-        {
-            return new JsonPrimitive(value);
-        }
-
-        /// <summary>
-        /// Enables implicit casts from type <see cref="System.Decimal"/> to a <see cref="System.Json.JsonPrimitive"/>.
-        /// </summary>
-        /// <param name="value">The <see cref="System.Decimal"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param>
-        /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Decimal"/> specified.</returns>
-        public static implicit operator JsonValue(decimal value)
-        {
-            return new JsonPrimitive(value);
-        }
-
-        /// <summary>
-        /// Enables implicit casts from type <see cref="System.Double"/> to a <see cref="System.Json.JsonPrimitive"/>.
-        /// </summary>
-        /// <param name="value">The <see cref="System.Double"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param>
-        /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Double"/> specified.</returns>
-        public static implicit operator JsonValue(double value)
-        {
-            return new JsonPrimitive(value);
-        }
-
-        /// <summary>
-        /// Enables implicit casts from type <see cref="System.Int16"/> to a <see cref="System.Json.JsonPrimitive"/>.
-        /// </summary>
-        /// <param name="value">The <see cref="System.Int16"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param>
-        /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Int16"/> specified.</returns>
-        public static implicit operator JsonValue(short value)
-        {
-            return new JsonPrimitive(value);
-        }
-
-        /// <summary>
-        /// Enables implicit casts from type <see cref="System.Int32"/> to a <see cref="System.Json.JsonPrimitive"/>.
-        /// </summary>
-        /// <param name="value">The <see cref="System.Int32"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param>
-        /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Int32"/> specified.</returns>
-        public static implicit operator JsonValue(int value)
-        {
-            return new JsonPrimitive(value);
-        }
-
-        /// <summary>
-        /// Enables implicit casts from type <see cref="System.Int64"/> to a <see cref="System.Json.JsonPrimitive"/>.
-        /// </summary>
-        /// <param name="value">The <see cref="System.Int64"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param>
-        /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Int64"/> specified.</returns>
-        public static implicit operator JsonValue(long value)
-        {
-            return new JsonPrimitive(value);
-        }
-
-        /// <summary>
-        /// Enables implicit casts from type <see cref="System.Single"/> to a <see cref="System.Json.JsonPrimitive"/>.
-        /// </summary>
-        /// <param name="value">The <see cref="System.Single"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param>
-        /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Single"/> specified.</returns>
-        public static implicit operator JsonValue(float value)
-        {
-            return new JsonPrimitive(value);
-        }
-
-        /// <summary>
-        /// Enables implicit casts from type <see cref="System.String"/> to a <see cref="System.Json.JsonPrimitive"/>.
-        /// </summary>
-        /// <param name="value">The <see cref="System.String"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param>
-        /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.String"/> specified, or null if the value is null.</returns>
-        [SuppressMessage("Microsoft.Design", "CA1057:StringUriOverloadsCallSystemUriOverloads",
-            Justification = "This operator does not intend to represent a Uri overload.")]
-        public static implicit operator JsonValue(string value)
-        {
-            return value == null ? null : new JsonPrimitive(value);
-        }
-
-        /// <summary>
-        /// Enables implicit casts from type <see cref="System.Char"/> to a <see cref="System.Json.JsonPrimitive"/>.
-        /// </summary>
-        /// <param name="value">The <see cref="System.Char"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param>
-        /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Char"/> specified.</returns>
-        public static implicit operator JsonValue(char value)
-        {
-            return new JsonPrimitive(value);
-        }
-
-        /// <summary>
-        /// Enables implicit casts from type <see cref="System.DateTime"/> to a <see cref="System.Json.JsonPrimitive"/>.
-        /// </summary>
-        /// <param name="value">The <see cref="System.DateTime"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param>
-        /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.DateTime"/> specified.</returns>
-        public static implicit operator JsonValue(DateTime value)
-        {
-            return new JsonPrimitive(value);
-        }
-
-        /// <summary>
-        /// Enables implicit casts from type <see cref="System.Guid"/> to a <see cref="System.Json.JsonPrimitive"/>.
-        /// </summary>
-        /// <param name="value">The <see cref="System.Guid"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param>
-        /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Guid"/> specified.</returns>
-        public static implicit operator JsonValue(Guid value)
-        {
-            return new JsonPrimitive(value);
-        }
-
-        /// <summary>
-        /// Enables implicit casts from type <see cref="System.Uri"/> to a <see cref="System.Json.JsonPrimitive"/>.
-        /// </summary>
-        /// <param name="value">The <see cref="System.Uri"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param>
-        /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.Uri"/> specified, or null if the value is null.</returns>
-        public static implicit operator JsonValue(Uri value)
-        {
-            return value == null ? null : new JsonPrimitive(value);
-        }
-
-        /// <summary>
-        /// Enables implicit casts from type <see cref="System.SByte"/> to a <see cref="System.Json.JsonPrimitive"/>.
-        /// </summary>
-        /// <param name="value">The <see cref="System.SByte"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param>
-        /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.SByte"/> specified.</returns>
-        [CLSCompliant(false)]
-        public static implicit operator JsonValue(sbyte value)
-        {
-            return new JsonPrimitive(value);
-        }
-
-        /// <summary>
-        /// Enables implicit casts from type <see cref="System.UInt16"/> to a <see cref="System.Json.JsonPrimitive"/>.
-        /// </summary>
-        /// <param name="value">The <see cref="System.UInt16"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param>
-        /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.UInt16"/> specified.</returns>
-        [CLSCompliant(false)]
-        public static implicit operator JsonValue(ushort value)
-        {
-            return new JsonPrimitive(value);
-        }
-
-        /// <summary>
-        /// Enables implicit casts from type <see cref="System.UInt32"/> to a <see cref="System.Json.JsonPrimitive"/>.
-        /// </summary>
-        /// <param name="value">The <see cref="System.UInt32"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param>
-        /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.UInt32"/> specified.</returns>
-        [CLSCompliant(false)]
-        public static implicit operator JsonValue(uint value)
-        {
-            return new JsonPrimitive(value);
-        }
-
-        /// <summary>
-        /// Enables implicit casts from type <see cref="System.UInt64"/> to a <see cref="System.Json.JsonPrimitive"/>.
-        /// </summary>
-        /// <param name="value">The <see cref="System.UInt64"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param>
-        /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.UInt64"/> specified.</returns>
-        [CLSCompliant(false)]
-        public static implicit operator JsonValue(ulong value)
-        {
-            return new JsonPrimitive(value);
-        }
-
-        /// <summary>
-        /// Enables implicit casts from type <see cref="System.DateTimeOffset"/> to a <see cref="System.Json.JsonPrimitive"/>.
-        /// </summary>
-        /// <param name="value">The <see cref="System.DateTimeOffset"/> instance used to initialize the <see cref="System.Json.JsonPrimitive"/>.</param>
-        /// <returns>The <see cref="System.Json.JsonValue"/> initialized with the <see cref="System.DateTimeOffset"/> specified.</returns>
-        public static implicit operator JsonValue(DateTimeOffset value)
-        {
-            return new JsonPrimitive(value);
-        }
-    }
-}
diff --git a/mcs/class/System.Json-new/JsonValueChange.cs b/mcs/class/System.Json-new/JsonValueChange.cs
deleted file mode 100644 (file)
index 7bc9f90..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-namespace System.Json
-{
-    /// <summary>
-    /// Specifies the event type when an event is raised for a <see cref="System.Json.JsonValue"/>.
-    /// </summary>
-    public enum JsonValueChange
-    {
-        /// <summary>
-        /// An element has been or will be added to the collection.
-        /// </summary>
-        Add,
-
-        /// <summary>
-        /// An element has been or will be removed from the collection.
-        /// </summary>
-        Remove,
-
-        /// <summary>
-        /// An element has been or will be replaced in the collection. Used on indexers.
-        /// </summary>
-        Replace,
-
-        /// <summary>
-        /// All elements of the collection have been or will be removed.
-        /// </summary>
-        Clear,
-    }
-}
diff --git a/mcs/class/System.Json-new/JsonValueChangeEventArgs.cs b/mcs/class/System.Json-new/JsonValueChangeEventArgs.cs
deleted file mode 100644 (file)
index 9088df2..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-namespace System.Json
-{
-    /// <summary>
-    /// Provide data for the <see cref="System.Json.JsonValue.Changing"/> and <see cref="System.Json.JsonValue.Changed"/> events.
-    /// </summary>
-    public class JsonValueChangeEventArgs : EventArgs
-    {
-        private JsonValue child;
-        private JsonValueChange change;
-        private int index;
-        private string key;
-
-        /// <summary>
-        /// Initializes a new instance of the <see cref="System.Json.JsonValueChangeEventArgs"/> class for
-        /// changes in a <see cref="System.Json.JsonArray"/>.
-        /// </summary>
-        /// <param name="child">The <see cref="System.Json.JsonValue"/> instance which will be or has been modified.</param>
-        /// <param name="change">The type of change of the <see cref="System.Json.JsonValue"/> event.</param>
-        /// <param name="index">The index of the element being changed in a <see cref="System.Json.JsonArray"/>.</param>
-        public JsonValueChangeEventArgs(JsonValue child, JsonValueChange change, int index)
-        {
-            if (index < 0)
-            {
-                throw new ArgumentOutOfRangeException("index", RS.Format(Properties.Resources.ArgumentMustBeGreaterThanOrEqualTo, index, 0));
-            }
-
-            this.child = child;
-            this.change = change;
-            this.index = index;
-        }
-
-        /// <summary>
-        /// Initializes a new instance of the <see cref="System.Json.JsonValueChangeEventArgs"/> class for
-        /// changes in a <see cref="System.Json.JsonObject"/>.
-        /// </summary>
-        /// <param name="child">The <see cref="System.Json.JsonValue"/> instance which will be or has been modified.</param>
-        /// <param name="change">The type of change of the <see cref="System.Json.JsonValue"/> event.</param>
-        /// <param name="key">The key of the element being changed in a <see cref="System.Json.JsonObject"/>.</param>
-        public JsonValueChangeEventArgs(JsonValue child, JsonValueChange change, string key)
-        {
-            if (change != JsonValueChange.Clear)
-            {
-                if (key == null)
-                {
-                    throw new ArgumentNullException("key");
-                }
-            }
-
-            this.child = child;
-            this.change = change;
-            index = -1;
-            this.key = key;
-        }
-
-        /// <summary>
-        /// Gets the child which will be or has been modified.
-        /// </summary>
-        /// <remarks><p>This property is <code>null</code> for <see cref="System.Json.JsonValueChange.Clear"/> event types
-        /// raised by <see cref="System.Json.JsonValue"/> instances.</p>
-        /// <p>For <see cref="System.Json.JsonValueChange">Replace</see> events, this property contains the new value in
-        /// the <see cref="System.Json.JsonValue.Changing"/> event, and the old value (the one being replaced) in the
-        /// <see cref="System.Json.JsonValue.Changed"/> event.</p></remarks>
-        public JsonValue Child
-        {
-            get { return child; }
-        }
-
-        /// <summary>
-        /// Gets the type of change.
-        /// </summary>
-        public JsonValueChange Change
-        {
-            get { return change; }
-        }
-
-        /// <summary>
-        /// Gets the index in the <see cref="System.Json.JsonArray"/> where the change happened, or
-        /// <code>-1</code> if the change happened in a <see cref="System.Json.JsonValue"/> of a different type.
-        /// </summary>
-        public int Index
-        {
-            get { return index; }
-        }
-
-        /// <summary>
-        /// Gets the key in the <see cref="System.Json.JsonObject"/> where the change happened, or
-        /// <code>null</code> if the change happened in a <see cref="System.Json.JsonValue"/> of a different type.
-        /// </summary>
-        /// <remarks>This property can also be <code>null</code> if the event type is
-        /// <see cref="System.Json.JsonValueChange">Clear</see>.</remarks>
-        public string Key
-        {
-            get { return key; }
-        }
-    }
-}
diff --git a/mcs/class/System.Json-new/JsonValueDynamicMetaObject.cs b/mcs/class/System.Json-new/JsonValueDynamicMetaObject.cs
deleted file mode 100644 (file)
index e3fed12..0000000
+++ /dev/null
@@ -1,383 +0,0 @@
-#if NET_4_0
-using System.Collections.Generic;
-using System.Dynamic;
-using System.Linq.Expressions;
-using System.Reflection;
-using System.Runtime.Serialization.Json;
-
-namespace System.Json
-{
-    /// <summary>
-    /// This class provides dynamic behavior support for the JsonValue types.
-    /// </summary>
-    internal class JsonValueDynamicMetaObject : DynamicMetaObject
-    {
-        private static readonly MethodInfo _getValueByIndexMethodInfo = typeof(JsonValue).GetMethod("GetValue", new Type[] { typeof(int) });
-        private static readonly MethodInfo _getValueByKeyMethodInfo = typeof(JsonValue).GetMethod("GetValue", new Type[] { typeof(string) });
-        private static readonly MethodInfo _setValueByIndexMethodInfo = typeof(JsonValue).GetMethod("SetValue", new Type[] { typeof(int), typeof(object) });
-        private static readonly MethodInfo _setValueByKeyMethodInfo = typeof(JsonValue).GetMethod("SetValue", new Type[] { typeof(string), typeof(object) });
-        private static readonly MethodInfo _castValueMethodInfo = typeof(JsonValue).GetMethod("CastValue", new Type[] { typeof(JsonValue) });
-        private static readonly MethodInfo _changeTypeMethodInfo = typeof(Convert).GetMethod("ChangeType", new Type[] { typeof(object), typeof(Type) });
-
-        /// <summary>
-        /// Class constructor.
-        /// </summary>
-        /// <param name="parameter">The expression representing this <see cref="DynamicMetaObject"/> during the dynamic binding process.</param>
-        /// <param name="value">The runtime value represented by the <see cref="DynamicMetaObject"/>.</param>
-        internal JsonValueDynamicMetaObject(Expression parameter, JsonValue value)
-            : base(parameter, BindingRestrictions.Empty, value)
-        {
-        }
-
-        /// <summary>
-        /// Gets the default binding restrictions for this type.
-        /// </summary>
-        private BindingRestrictions DefaultRestrictions
-        {
-            get { return BindingRestrictions.GetTypeRestriction(Expression, LimitType); }
-        }
-
-        /// <summary>
-        /// Implements dynamic cast for JsonValue types.
-        /// </summary>
-        /// <param name="binder">An instance of the <see cref="ConvertBinder"/> that represents the details of the dynamic operation.</param>
-        /// <returns>The new <see cref="DynamicMetaObject"/> representing the result of the binding.</returns>
-        public override DynamicMetaObject BindConvert(ConvertBinder binder)
-        {
-            if (binder == null)
-            {
-                throw new ArgumentNullException("binder");
-            }
-
-            Expression expression = Expression;
-
-            bool implicitCastSupported =
-                binder.Type.IsAssignableFrom(LimitType) ||
-                binder.Type == typeof(IEnumerable<KeyValuePair<string, JsonValue>>) ||
-                binder.Type == typeof(IDynamicMetaObjectProvider) ||
-                binder.Type == typeof(object);
-
-            if (!implicitCastSupported)
-            {
-                if (JsonValue.IsSupportedExplicitCastType(binder.Type))
-                {
-                    Expression instance = Expression.Convert(Expression, LimitType);
-                    expression = Expression.Call(_castValueMethodInfo.MakeGenericMethod(binder.Type), new Expression[] { instance });
-                }
-                else
-                {
-                    string exceptionMessage = RS.Format(Properties.Resources.CannotCastJsonValue, LimitType.FullName, binder.Type.FullName);
-                    expression = Expression.Throw(Expression.Constant(new InvalidCastException(exceptionMessage)), typeof(object));
-                }
-            }
-
-            expression = Expression.Convert(expression, binder.Type);
-
-            return new DynamicMetaObject(expression, DefaultRestrictions);
-        }
-
-        /// <summary>
-        /// Implements setter for dynamic indexer by index (JsonArray)
-        /// </summary>
-        /// <param name="binder">An instance of the <see cref="GetIndexBinder"/> that represents the details of the dynamic operation.</param>
-        /// <param name="indexes">An array of <see cref="DynamicMetaObject"/> instances - indexes for the get index operation.</param>
-        /// <returns>The new <see cref="DynamicMetaObject"/> representing the result of the binding.</returns>
-        public override DynamicMetaObject BindGetIndex(GetIndexBinder binder, DynamicMetaObject[] indexes)
-        {
-            if (binder == null)
-            {
-                throw new ArgumentNullException("binder");
-            }
-
-            if (indexes == null)
-            {
-                throw new ArgumentNullException("indexes");
-            }
-
-            Expression indexExpression;
-            if (!JsonValueDynamicMetaObject.TryGetIndexExpression(indexes, out indexExpression))
-            {
-                return new DynamicMetaObject(indexExpression, DefaultRestrictions);
-            }
-
-            MethodInfo methodInfo = indexExpression.Type == typeof(string) ? _getValueByKeyMethodInfo : _getValueByIndexMethodInfo;
-            Expression[] args = new Expression[] { indexExpression };
-
-            return GetMethodMetaObject(methodInfo, args);
-        }
-
-        /// <summary>
-        /// Implements getter for dynamic indexer by index (JsonArray).
-        /// </summary>
-        /// <param name="binder">An instance of the <see cref="SetIndexBinder"/> that represents the details of the dynamic operation.</param>
-        /// <param name="indexes">An array of <see cref="DynamicMetaObject"/> instances - indexes for the set index operation.</param>
-        /// <param name="value">The <see cref="DynamicMetaObject"/> representing the value for the set index operation.</param>
-        /// <returns>The new <see cref="DynamicMetaObject"/> representing the result of the binding.</returns>
-        public override DynamicMetaObject BindSetIndex(SetIndexBinder binder, DynamicMetaObject[] indexes, DynamicMetaObject value)
-        {
-            if (binder == null)
-            {
-                throw new ArgumentNullException("binder");
-            }
-
-            if (indexes == null)
-            {
-                throw new ArgumentNullException("indexes");
-            }
-
-            if (value == null)
-            {
-                throw new ArgumentNullException("value");
-            }
-
-            Expression indexExpression;
-            if (!JsonValueDynamicMetaObject.TryGetIndexExpression(indexes, out indexExpression))
-            {
-                return new DynamicMetaObject(indexExpression, DefaultRestrictions);
-            }
-
-            MethodInfo methodInfo = indexExpression.Type == typeof(string) ? _setValueByKeyMethodInfo : _setValueByIndexMethodInfo;
-            Expression[] args = new Expression[] { indexExpression, Expression.Convert(value.Expression, typeof(object)) };
-
-            return GetMethodMetaObject(methodInfo, args);
-        }
-
-        /// <summary>
-        /// Implements getter for dynamic indexer by key (JsonObject).
-        /// </summary>
-        /// <param name="binder">An instance of the <see cref="GetMemberBinder"/> that represents the details of the dynamic operation.</param>
-        /// <returns>The new <see cref="DynamicMetaObject"/> representing the result of the binding.</returns>
-        public override DynamicMetaObject BindGetMember(GetMemberBinder binder)
-        {
-            if (binder == null)
-            {
-                throw new ArgumentNullException("binder");
-            }
-
-            PropertyInfo propInfo = LimitType.GetProperty(binder.Name, BindingFlags.Instance | BindingFlags.Public);
-
-            if (propInfo != null)
-            {
-                return base.BindGetMember(binder);
-            }
-
-            Expression[] args = new Expression[] { Expression.Constant(binder.Name) };
-
-            return GetMethodMetaObject(_getValueByKeyMethodInfo, args);
-        }
-
-        /// <summary>
-        /// Implements setter for dynamic indexer by key (JsonObject).
-        /// </summary>
-        /// <param name="binder">An instance of the <see cref="SetMemberBinder"/> that represents the details of the dynamic operation.</param>
-        /// <param name="value">The <see cref="DynamicMetaObject"/> representing the value for the set member operation.</param>
-        /// <returns>The new <see cref="DynamicMetaObject"/> representing the result of the binding.</returns>
-        public override DynamicMetaObject BindSetMember(SetMemberBinder binder, DynamicMetaObject value)
-        {
-            if (binder == null)
-            {
-                throw new ArgumentNullException("binder");
-            }
-
-            if (value == null)
-            {
-                throw new ArgumentNullException("value");
-            }
-
-            Expression[] args = new Expression[] { Expression.Constant(binder.Name), Expression.Convert(value.Expression, typeof(object)) };
-
-            return GetMethodMetaObject(_setValueByKeyMethodInfo, args);
-        }
-
-        /// <summary>
-        /// Performs the binding of the dynamic invoke member operation.
-        /// Implemented to support extension methods defined in <see cref="JsonValueExtensions"/> type.
-        /// </summary>
-        /// <param name="binder">An instance of the InvokeMemberBinder that represents the details of the dynamic operation.</param>
-        /// <param name="args">An array of DynamicMetaObject instances - arguments to the invoke member operation.</param>
-        /// <returns>The new DynamicMetaObject representing the result of the binding.</returns>
-        public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args)
-        {
-            if (binder == null)
-            {
-                throw new ArgumentNullException("binder");
-            }
-
-            if (args == null)
-            {
-                throw new ArgumentNullException("args");
-            }
-
-            List<Type> argTypeList = new List<Type>();
-
-            for (int idx = 0; idx < args.Length; idx++)
-            {
-                argTypeList.Add(args[idx].LimitType);
-            }
-
-            MethodInfo methodInfo = Value.GetType().GetMethod(binder.Name, argTypeList.ToArray());
-
-            if (methodInfo == null)
-            {
-                argTypeList.Insert(0, typeof(JsonValue));
-
-                Type[] argTypes = argTypeList.ToArray();
-
-                methodInfo = JsonValueDynamicMetaObject.GetExtensionMethod(typeof(JsonValueExtensions), binder.Name, argTypes);
-
-                if (methodInfo != null)
-                {
-                    Expression thisInstance = Expression.Convert(Expression, LimitType);
-                    Expression[] argsExpression = new Expression[argTypes.Length];
-
-                    argsExpression[0] = thisInstance;
-                    for (int i = 0; i < args.Length; i++)
-                    {
-                        argsExpression[i + 1] = args[i].Expression;
-                    }
-
-                    Expression callExpression = Expression.Call(methodInfo, argsExpression);
-
-                    if (methodInfo.ReturnType == typeof(void))
-                    {
-                        callExpression = Expression.Block(callExpression, Expression.Default(binder.ReturnType));
-                    }
-                    else
-                    {
-                        callExpression = Expression.Convert(Expression.Call(methodInfo, argsExpression), binder.ReturnType);
-                    }
-
-                    return new DynamicMetaObject(callExpression, DefaultRestrictions);
-                }
-            }
-
-            return base.BindInvokeMember(binder, args);
-        }
-
-        /// <summary>
-        /// Returns the enumeration of all dynamic member names.
-        /// </summary>
-        /// <returns>An <see cref="IEnumerable{T}"/> of string reprenseting the dynamic member names.</returns>
-        public override IEnumerable<string> GetDynamicMemberNames()
-        {
-            JsonValue jsonValue = Value as JsonValue;
-
-            if (jsonValue != null)
-            {
-                List<string> names = new List<string>();
-
-                foreach (KeyValuePair<string, JsonValue> pair in jsonValue)
-                {
-                    names.Add(pair.Key);
-                }
-
-                return names;
-            }
-
-            return base.GetDynamicMemberNames();
-        }
-
-        /// <summary>
-        /// Gets a <see cref="MethodInfo"/> instance for the specified method name in the specified type.
-        /// </summary>
-        /// <param name="extensionProviderType">The extension provider type.</param>
-        /// <param name="methodName">The name of the method to get the info for.</param>
-        /// <param name="argTypes">The types of the method arguments.</param>
-        /// <returns>A <see cref="MethodInfo"/>instance or null if the method cannot be resolved.</returns>
-        private static MethodInfo GetExtensionMethod(Type extensionProviderType, string methodName, Type[] argTypes)
-        {
-            MethodInfo methodInfo = null;
-            MethodInfo[] methods = extensionProviderType.GetMethods();
-
-            foreach (MethodInfo info in methods)
-            {
-                if (info.Name == methodName)
-                {
-                    methodInfo = info;
-
-                    if (!info.IsGenericMethodDefinition)
-                    {
-                        bool paramsMatch = true;
-                        ParameterInfo[] args = methodInfo.GetParameters();
-
-                        if (args.Length == argTypes.Length)
-                        {
-                            for (int idx = 0; idx < args.Length; idx++)
-                            {
-                                if (!args[idx].ParameterType.IsAssignableFrom(argTypes[idx]))
-                                {
-                                    paramsMatch = false;
-                                    break;
-                                }
-                            }
-
-                            if (paramsMatch)
-                            {
-                                break;
-                            }
-                        }
-                    }
-                }
-            }
-
-            return methodInfo;
-        }
-
-        /// <summary>
-        /// Attempts to get an expression for an index parameter.
-        /// </summary>
-        /// <param name="indexes">The operation indexes parameter.</param>
-        /// <param name="expression">A <see cref="Expression"/> to be initialized to the index expression if the operation is successful, otherwise an error expression.</param>
-        /// <returns>true the operation is successful, false otherwise.</returns>
-        private static bool TryGetIndexExpression(DynamicMetaObject[] indexes, out Expression expression)
-        {
-            if (indexes.Length == 1 && indexes[0] != null && indexes[0].Value != null)
-            {
-                DynamicMetaObject index = indexes[0];
-                Type indexType = indexes[0].Value.GetType();
-
-                switch (Type.GetTypeCode(indexType))
-                {
-                    case TypeCode.Char:
-                    case TypeCode.Int16:
-                    case TypeCode.UInt16:
-                    case TypeCode.Byte:
-                    case TypeCode.SByte:
-                        Expression argExp = Expression.Convert(index.Expression, typeof(object));
-                        Expression typeExp = Expression.Constant(typeof(int));
-                        expression = Expression.Convert(Expression.Call(_changeTypeMethodInfo, new Expression[] { argExp, typeExp }), typeof(int));
-                        return true;
-
-                    case TypeCode.Int32:
-                    case TypeCode.String:
-                        expression = index.Expression;
-                        return true;
-                }
-
-                expression = Expression.Throw(Expression.Constant(new ArgumentException(RS.Format(Properties.Resources.InvalidIndexType, indexType))), typeof(object));
-                return false;
-            }
-
-            expression = Expression.Throw(Expression.Constant(new ArgumentException(Properties.Resources.NonSingleNonNullIndexNotSupported)), typeof(object));
-            return false;
-        }
-
-        /// <summary>
-        /// Gets a <see cref="DynamicMetaObject"/> for a method call.
-        /// </summary>
-        /// <param name="methodInfo">Info for the method to be performed.</param>
-        /// <param name="args">expression array representing the method arguments</param>
-        /// <returns>A meta object for the method call.</returns>
-        private DynamicMetaObject GetMethodMetaObject(MethodInfo methodInfo, Expression[] args)
-        {
-            Expression instance = Expression.Convert(Expression, LimitType);
-            Expression methodCall = Expression.Call(instance, methodInfo, args);
-            BindingRestrictions restrictions = DefaultRestrictions;
-
-            DynamicMetaObject metaObj = new DynamicMetaObject(methodCall, restrictions);
-
-            return metaObj;
-        }
-    }
-}
-#endif
diff --git a/mcs/class/System.Json-new/JsonValueLinqExtensions.cs b/mcs/class/System.Json-new/JsonValueLinqExtensions.cs
deleted file mode 100644 (file)
index 5aa6ba7..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Diagnostics.CodeAnalysis;
-
-namespace System.Json
-{
-    /// <summary>
-    /// This class extends the funcionality of the <see cref="JsonValue"/> type for better Linq support . 
-    /// </summary>
-    [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Justification = "Linq is a technical name.")]
-    [EditorBrowsable(EditorBrowsableState.Never)]
-    public static class JsonValueLinqExtensions
-    {
-        /// <summary>
-        /// Extension method for creating a <see cref="JsonValue"/> from an <see cref="IEnumerable{T}"/> collection of <see cref="JsonValue"/> types.
-        /// </summary>
-        /// <param name="items">The enumerable instance.</param>
-        /// <returns>A <see cref="JsonArray"/> created from the specified items.</returns>
-        public static JsonArray ToJsonArray(this IEnumerable<JsonValue> items)
-        {
-            return new JsonArray(items);
-        }
-
-        /// <summary>
-        /// Extension method for creating a <see cref="JsonValue"/> from an <see cref="IEnumerable{T}"/> collection of <see cref="KeyValuePair{K,V}"/> of <see cref="String"/> and <see cref="JsonValue"/> types.
-        /// </summary>
-        /// <param name="items">The enumerable instance.</param>
-        /// <returns>A <see cref="JsonValue"/> created from the specified items.</returns>
-        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "JsonValue implements the nested type in param.")]
-        public static JsonObject ToJsonObject(this IEnumerable<KeyValuePair<string, JsonValue>> items)
-        {
-            return new JsonObject(items);
-        }
-    }
-}
diff --git a/mcs/class/System.Json-new/LICENSE b/mcs/class/System.Json-new/LICENSE
deleted file mode 100644 (file)
index 70a9036..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-This is a copied text from http://aspnetwebstack.codeplex.com/license
-
-=====================================================================
-
-Apache License
-Version 2.0, January 2004
-http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
-"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
-
-"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
-
-"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
-
-"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
-
-"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
-
-"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
-
-"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
-
-"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
-
-"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
-
-"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
-
-2. Grant of Copyright License.
-
-Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
-
-3. Grant of Patent License.
-
-Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
-
-4. Redistribution.
-
-You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
-
-1. You must give any other recipients of the Work or Derivative Works a copy of this License; and
-
-2. You must cause any modified files to carry prominent notices stating that You changed the files; and
-
-3. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
-
-4. If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
-
-You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
-
-5. Submission of Contributions.
-
-Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
-
-6. Trademarks.
-
-This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty.
-
-Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability.
-
-In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability.
-
-While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. 
-
diff --git a/mcs/class/System.Json-new/Makefile b/mcs/class/System.Json-new/Makefile
deleted file mode 100644 (file)
index 8bd99a8..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-thisdir = class/System.Json
-SUBDIRS = 
-include ../../build/rules.make
-
-RESX_RESOURCES = Properties/Resources.resx
-RESOURCES = Properties/Resources.resources
-
-LIBRARY = System.Json.dll
-LIB_MCS_FLAGS = \
-               /resource:Properties/Resources.resources,System.Json.Properties.Resources.resources \
-               /r:System.dll \
-               /r:System.Xml.dll \
-               /r:System.Core.dll \
-               /r:System.Runtime.Serialization.dll \
-               /r:System.ServiceModel.Web.dll
-
-ifeq (4, $(FRAMEWORK_VERSION_MAJOR))
-LIB_MCS_FLAGS += /r:Microsoft.CSharp.dll
-endif
-
-TEST_MCS_FLAGS = $(LIB_MCS_FLAGS)
-
-EXTRA_DISTFILES = $(RESX_RESOURCES)
-
-VALID_PROFILE := $(filter 2 4, $(FRAMEWORK_VERSION_MAJOR))
-
-ifndef VALID_PROFILE
-LIBRARY_NAME = dummy-System.Json.dll
-NO_INSTALL = yes
-NO_SIGN_ASSEMBLY = yes
-NO_TEST = yes
-endif
-
-include ../../build/library.make
-
-$(the_lib): $(RESOURCES)
-
-$(RESOURCES):  %.resources: %.resx
-       $(RESGEN) $< || cp $@.prebuilt $@
-
diff --git a/mcs/class/System.Json-new/NGenWrapper.cs b/mcs/class/System.Json-new/NGenWrapper.cs
deleted file mode 100644 (file)
index 4de0b93..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-namespace System.Json
-{
-    /// <summary>
-    /// Struct that wraps values which cause JIT compilation at runtime.
-    /// This Struct is added to solve the FxCop warning CA908 in JsonObject.cs.
-    /// </summary>
-    /// <typeparam name="T">Wrapped type.</typeparam>
-    internal struct NGenWrapper<T>
-    {
-        /// <summary>
-        /// Value of type T which represents the actual data which is currently in hold.
-        /// </summary>
-        public T Value;
-
-        /// <summary>
-        /// Creates an instance of the <see cref="System.Json.NGenWrapper{T}"/> class
-        /// </summary>
-        /// <param name="value">The wrapped object of T</param>
-        public NGenWrapper(T value)
-        {
-            Value = value;
-        }
-
-        /// <summary>
-        /// Cast operator from <see cref="System.Json.NGenWrapper{T}"/> to <typeparamref name="T"/>
-        /// </summary>
-        /// <param name="value">Object in type <see cref="System.Json.NGenWrapper{T}"/></param>
-        /// <returns>Object in type <typeparamref name="T">The wrapped element type</typeparamref></returns>
-        /// <typeparamref name="T">The wrapped element type</typeparamref>
-        public static implicit operator T(NGenWrapper<T> value)
-        {
-            return value.Value;
-        }
-
-        /// <summary>
-        /// Cast operator from <typeparamref name="T"/> to <see cref="System.Json.NGenWrapper{T}"/>
-        /// </summary>
-        /// <param name="value">Object in type <typeparamref name="T"/></param>
-        /// <returns>Object in type <see cref="System.Json.NGenWrapper{T}"/></returns>
-        /// <typeparamref name="T">The wrapped element type</typeparamref>
-        public static implicit operator NGenWrapper<T>(T value)
-        {
-            return new NGenWrapper<T>(value);
-        }
-    }
-}
diff --git a/mcs/class/System.Json-new/Properties/AssemblyInfo.cs b/mcs/class/System.Json-new/Properties/AssemblyInfo.cs
deleted file mode 100644 (file)
index cf08e4e..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-using System.Reflection;
-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("System.Json")]
-[assembly: AssemblyDescription("")]
-[assembly: Guid("6fd72360-ebfc-4097-96fa-2ee418c04f7b")]
diff --git a/mcs/class/System.Json-new/Properties/Resources.Designer.cs b/mcs/class/System.Json-new/Properties/Resources.Designer.cs
deleted file mode 100644 (file)
index 5a0e120..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated by a tool.
-//     Runtime Version:4.0.30319.239
-//
-//     Changes to this file may cause incorrect behavior and will be lost if
-//     the code is regenerated.
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-namespace System.Json.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("System.Json.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;
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to The argument &apos;{0}&apos; must be greater than or equal to {1}..
-        /// </summary>
-        internal static string ArgumentMustBeGreaterThanOrEqualTo {
-            get {
-                return ResourceManager.GetString("ArgumentMustBeGreaterThanOrEqualTo", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Unable to cast object of type &apos;{0}&apos; to type &apos;{1}&apos;..
-        /// </summary>
-        internal static string CannotCastJsonValue {
-            get {
-                return ResourceManager.GetString("CannotCastJsonValue", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to CannotReadAsType=Cannot read &apos;{0}&apos; as &apos;{1}&apos; type..
-        /// </summary>
-        internal static string CannotReadAsType {
-            get {
-                return ResourceManager.GetString("CannotReadAsType", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Cannot read JsonPrimitive value &apos;{0}&apos; as &apos;{1}&apos;..
-        /// </summary>
-        internal static string CannotReadPrimitiveAsType {
-            get {
-                return ResourceManager.GetString("CannotReadPrimitiveAsType", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to &apos;{0}&apos; does not contain a definition for property &apos;{1}&apos;..
-        /// </summary>
-        internal static string DynamicPropertyNotDefined {
-            get {
-                return ResourceManager.GetString("DynamicPropertyNotDefined", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to The input source is not correctly formatted..
-        /// </summary>
-        internal static string IncorrectJsonFormat {
-            get {
-                return ResourceManager.GetString("IncorrectJsonFormat", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to &apos;{0}&apos; type indexer is not supported on JsonValue of &apos;JsonType.{1}&apos; type..
-        /// </summary>
-        internal static string IndexerNotSupportedOnJsonType {
-            get {
-                return ResourceManager.GetString("IndexerNotSupportedOnJsonType", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Cannot convert null to &apos;{0}&apos; because it is a non-nullable value type..
-        /// </summary>
-        internal static string InvalidCastNonNullable {
-            get {
-                return ResourceManager.GetString("InvalidCastNonNullable", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Cannot cast JsonPrimitive value &apos;{0}&apos; as &apos;{1}&apos;. It is not in a valid date format..
-        /// </summary>
-        internal static string InvalidDateFormat {
-            get {
-                return ResourceManager.GetString("InvalidDateFormat", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Invalid &apos;{0}&apos; index type; only &apos;System.String&apos; and non-negative &apos;System.Int32&apos; types are supported..
-        /// </summary>
-        internal static string InvalidIndexType {
-            get {
-                return ResourceManager.GetString("InvalidIndexType", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Invalid JSON primitive: {0}..
-        /// </summary>
-        internal static string InvalidJsonPrimitive {
-            get {
-                return ResourceManager.GetString("InvalidJsonPrimitive", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Cannot cast &apos;{0}&apos; value &apos;{1}.{2}&apos; as a type of &apos;{3}&apos;. The provided string is not a valid relative or absolute &apos;{3}&apos;..
-        /// </summary>
-        internal static string InvalidUriFormat {
-            get {
-                return ResourceManager.GetString("InvalidUriFormat", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to An empty string cannot be parsed as JSON..
-        /// </summary>
-        internal static string JsonStringCannotBeEmpty {
-            get {
-                return ResourceManager.GetString("JsonStringCannotBeEmpty", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Null index or multidimensional indexing is not supported by this indexer; use &apos;System.Int32&apos; or &apos;System.String&apos; for array and object indexing respectively..
-        /// </summary>
-        internal static string NonSingleNonNullIndexNotSupported {
-            get {
-                return ResourceManager.GetString("NonSingleNonNullIndexNotSupported", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Cannot cast JsonPrimitive value &apos;{0}&apos; as &apos;{1}&apos;. The value is either too large or too small for the specified CLR type..
-        /// </summary>
-        internal static string OverflowReadAs {
-            get {
-                return ResourceManager.GetString("OverflowReadAs", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Object type not supported..
-        /// </summary>
-        internal static string TypeNotSupported {
-            get {
-                return ResourceManager.GetString("TypeNotSupported", resourceCulture);
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized string similar to Operation not supported on JsonValue instances of &apos;JsonType.Default&apos; type..
-        /// </summary>
-        internal static string UseOfDefaultNotAllowed {
-            get {
-                return ResourceManager.GetString("UseOfDefaultNotAllowed", resourceCulture);
-            }
-        }
-    }
-}
diff --git a/mcs/class/System.Json-new/Properties/Resources.resources b/mcs/class/System.Json-new/Properties/Resources.resources
deleted file mode 100644 (file)
index 21fb36c..0000000
Binary files a/mcs/class/System.Json-new/Properties/Resources.resources and /dev/null differ
diff --git a/mcs/class/System.Json-new/Properties/Resources.resx b/mcs/class/System.Json-new/Properties/Resources.resx
deleted file mode 100644 (file)
index 02fd621..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-<?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>
-  <data name="ArgumentMustBeGreaterThanOrEqualTo" xml:space="preserve">
-    <value>The argument '{0}' must be greater than or equal to {1}.</value>
-  </data>
-  <data name="CannotCastJsonValue" xml:space="preserve">
-    <value>Unable to cast object of type '{0}' to type '{1}'.</value>
-  </data>
-  <data name="CannotReadAsType" xml:space="preserve">
-    <value>CannotReadAsType=Cannot read '{0}' as '{1}' type.</value>
-  </data>
-  <data name="CannotReadPrimitiveAsType" xml:space="preserve">
-    <value>Cannot read JsonPrimitive value '{0}' as '{1}'.</value>
-  </data>
-  <data name="DynamicPropertyNotDefined" xml:space="preserve">
-    <value>'{0}' does not contain a definition for property '{1}'.</value>
-  </data>
-  <data name="IncorrectJsonFormat" xml:space="preserve">
-    <value>The input source is not correctly formatted.</value>
-  </data>
-  <data name="IndexerNotSupportedOnJsonType" xml:space="preserve">
-    <value>'{0}' type indexer is not supported on JsonValue of 'JsonType.{1}' type.</value>
-  </data>
-  <data name="InvalidCastNonNullable" xml:space="preserve">
-    <value>Cannot convert null to '{0}' because it is a non-nullable value type.</value>
-  </data>
-  <data name="InvalidDateFormat" xml:space="preserve">
-    <value>Cannot cast JsonPrimitive value '{0}' as '{1}'. It is not in a valid date format.</value>
-  </data>
-  <data name="InvalidIndexType" xml:space="preserve">
-    <value>Invalid '{0}' index type; only 'System.String' and non-negative 'System.Int32' types are supported.</value>
-  </data>
-  <data name="InvalidJsonPrimitive" xml:space="preserve">
-    <value>Invalid JSON primitive: {0}.</value>
-  </data>
-  <data name="InvalidUriFormat" xml:space="preserve">
-    <value>Cannot cast '{0}' value '{1}.{2}' as a type of '{3}'. The provided string is not a valid relative or absolute '{3}'.</value>
-  </data>
-  <data name="JsonStringCannotBeEmpty" xml:space="preserve">
-    <value>An empty string cannot be parsed as JSON.</value>
-  </data>
-  <data name="NonSingleNonNullIndexNotSupported" xml:space="preserve">
-    <value>Null index or multidimensional indexing is not supported by this indexer; use 'System.Int32' or 'System.String' for array and object indexing respectively.</value>
-  </data>
-  <data name="OverflowReadAs" xml:space="preserve">
-    <value>Cannot cast JsonPrimitive value '{0}' as '{1}'. The value is either too large or too small for the specified CLR type.</value>
-  </data>
-  <data name="TypeNotSupported" xml:space="preserve">
-    <value>Object type not supported.</value>
-  </data>
-  <data name="UseOfDefaultNotAllowed" xml:space="preserve">
-    <value>Operation not supported on JsonValue instances of 'JsonType.Default' type.</value>
-  </data>
-</root>
\ No newline at end of file
diff --git a/mcs/class/System.Json-new/README.porting b/mcs/class/System.Json-new/README.porting
deleted file mode 100644 (file)
index 7690e7c..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-This assembly is now a port from Microsoft's ASP.NET web stack.
-http://aspnetwebstack.codeplex.com
-
-The sources are mostly copied from src/System.Json and flavored with
-#if - #endif directives. RS.cs is copied from src. Assembly.cs is ignored.
-
diff --git a/mcs/class/System.Json-new/RS.cs b/mcs/class/System.Json-new/RS.cs
deleted file mode 100644 (file)
index de83ff7..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-using System;
-using System.Globalization;
-
-internal static class RS
-{
-    public static string Format(string format, params object[] args)
-    {
-        return String.Format(CultureInfo.CurrentCulture, format, args);
-    }
-}
diff --git a/mcs/class/System.Json-new/Settings.StyleCop b/mcs/class/System.Json-new/Settings.StyleCop
deleted file mode 100644 (file)
index 83ad56e..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-<StyleCopSettings Version="4.3">
-
-  <!-- Files in this SourceFileList are excluded from DocumentationRules only -->
-  <SourceFileList>
-    <Settings>
-      <GlobalSettings>
-        <StringProperty Name="MergeSettingsFiles">Merge</StringProperty>
-      </GlobalSettings>
-
-      <Analyzers>
-        <Analyzer AnalyzerId="Microsoft.StyleCop.CSharp.DocumentationRules">
-          <Rules>
-            <Rule Name="ElementsMustBeDocumented">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="PartialElementsMustBeDocumented">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="EnumerationItemsMustBeDocumented">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="DocumentationMustContainValidXml">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="ElementDocumentationMustHaveSummary">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="PartialElementDocumentationMustHaveSummary">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="ElementDocumentationMustHaveSummaryText">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="PartialElementDocumentationMustHaveSummaryText">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="ElementDocumentationMustNotHaveDefaultSummary">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="ElementParametersMustBeDocumented">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="ElementParameterDocumentationMustMatchElementParameters">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="ElementParameterDocumentationMustDeclareParameterName">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="ElementParameterDocumentationMustHaveText">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="ElementReturnValueMustBeDocumented">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="ElementReturnValueDocumentationMustHaveText">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="VoidReturnValueMustNotBeDocumented">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="GenericTypeParametersMustBeDocumented">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="GenericTypeParametersMustBeDocumentedPartialClass">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="GenericTypeParameterDocumentationMustMatchTypeParameters">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="GenericTypeParameterDocumentationMustDeclareParameterName">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="GenericTypeParameterDocumentationMustHaveText">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="PropertySummaryDocumentationMustMatchAccessors">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="PropertySummaryDocumentationMustOmitSetAccessorWithRestrictedAccess">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="ElementDocumentationMustNotBeCopiedAndPasted">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="SingleLineCommentsMustNotUseDocumentationStyleSlashes">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="DocumentationTextMustNotBeEmpty">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="DocumentationTextMustContainWhitespace">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="DocumentationMustMeetCharacterPercentage">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="DocumentationTextMustMeetMinimumCharacterLength">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="IncludedDocumentationXPathDoesNotExist">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="IncludeNodeDoesNotContainValidFileAndPath">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="FileMustHaveHeader">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="FileHeaderMustShowCopyright">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-            <Rule Name="FileHeaderMustHaveCopyrightText">
-              <RuleSettings>
-                <BooleanProperty Name="Enabled">False</BooleanProperty>
-              </RuleSettings>
-            </Rule>
-          </Rules>
-          <AnalyzerSettings />
-        </Analyzer>
-      </Analyzers>
-
-    </Settings>
-
-    <SourceFile>JXmlToJsonValueConverter.cs</SourceFile>
-    <SourceFile>JsonPrimitive.cs</SourceFile>
-    <SourceFile>JsonObject.cs</SourceFile>
-    <SourceFile>JsonValue.cs</SourceFile>
-    <SourceFile>JsonValueExtensions.cs</SourceFile>
-
-  </SourceFileList>
-
-</StyleCopSettings>
diff --git a/mcs/class/System.Json-new/System.Json.csproj b/mcs/class/System.Json-new/System.Json.csproj
deleted file mode 100644 (file)
index b29fe47..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory),Runtime.sln))\tools\WebStack.settings.targets" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <CodeAnalysis Condition=" '$(CodeAnalysis)' == '' ">false</CodeAnalysis>
-    <ProductVersion>9.0.30729</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{F0441BE9-BDC0-4629-BE5A-8765FFAA2481}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>System.Json</RootNamespace>
-    <AssemblyName>System.Json</AssemblyName>
-    <TargetFrameworkProfile Condition="'$(TargetFrameworkVersion)' != 'v4.5'">Client</TargetFrameworkProfile>
-    <FileAlignment>512</FileAlignment>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>..\..\bin\Debug\</OutputPath>
-    <DefineConstants>TRACE;DEBUG;ASPNETMVC</DefineConstants>
-    <CodeAnalysisRuleSet>..\Strict.ruleset</CodeAnalysisRuleSet>
-    <DocumentationFile>$(OutputPath)\$(AssemblyName).xml</DocumentationFile>
-    <NoWarn>1591</NoWarn>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>..\..\bin\Release\</OutputPath>
-    <DefineConstants>TRACE;ASPNETMVC</DefineConstants>
-    <CodeAnalysisRuleSet>..\Strict.ruleset</CodeAnalysisRuleSet>
-    <RunCodeAnalysis>$(CodeAnalysis)</RunCodeAnalysis>
-    <DocumentationFile>$(OutputPath)\$(AssemblyName).xml</DocumentationFile>
-    <NoWarn>1591</NoWarn>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'CodeCoverage|AnyCPU'">
-    <DebugSymbols>true</DebugSymbols>
-    <OutputPath>..\..\bin\CodeCoverage\</OutputPath>
-    <DefineConstants>TRACE;DEBUG;CODE_COVERAGE;ASPNETMVC</DefineConstants>
-    <DebugType>full</DebugType>
-    <CodeAnalysisRuleSet>..\Strict.ruleset</CodeAnalysisRuleSet>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Runtime.Serialization" />
-    <Reference Include="System.Xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="..\CommonAssemblyInfo.cs">
-      <Link>Properties\CommonAssemblyInfo.cs</Link>
-    </Compile>
-    <Compile Include="..\RS.cs">
-      <Link>RS.cs</Link>
-    </Compile>
-    <Compile Include="..\TransparentCommonAssemblyInfo.cs">
-      <Link>Properties\TransparentCommonAssemblyInfo.cs</Link>
-    </Compile>
-    <Compile Include="GlobalSuppressions.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="Properties\Resources.Designer.cs">
-      <AutoGen>True</AutoGen>
-      <DesignTime>True</DesignTime>
-      <DependentUpon>Resources.resx</DependentUpon>
-    </Compile>
-    <Compile Include="JsonArray.cs" />
-    <Compile Include="JsonObject.cs" />
-    <Compile Include="JsonPrimitive.cs" />
-    <Compile Include="JsonType.cs" />
-    <Compile Include="JsonValue.cs" />
-    <Compile Include="JsonValueChange.cs" />
-    <Compile Include="JsonValueChangeEventArgs.cs" />
-    <Compile Include="JsonValueDynamicMetaObject.cs" />
-    <Compile Include="JsonValueLinqExtensions.cs" />
-    <Compile Include="JXmlToJsonValueConverter.cs" />
-    <Compile Include="NGenWrapper.cs" />
-    <Compile Include="Extensions\JsonValueExtensions.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <EmbeddedResource Include="Properties\Resources.resx">
-      <Generator>ResXFileCodeGenerator</Generator>
-      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
-      <SubType>Designer</SubType>
-    </EmbeddedResource>
-  </ItemGroup>
-  <ItemGroup>
-    <CodeAnalysisDictionary Include="..\CodeAnalysisDictionary.xml">
-      <Link>CodeAnalysisDictionary.xml</Link>
-    </CodeAnalysisDictionary>
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-</Project>
\ No newline at end of file
diff --git a/mcs/class/System.Json-new/System.Json.dll.sources b/mcs/class/System.Json-new/System.Json.dll.sources
deleted file mode 100644 (file)
index eab5e43..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-../../build/common/Consts.cs
-../../build/common/Locale.cs
-../../build/common/MonoTODOAttribute.cs
-Assembly/AssemblyInfo.cs
-Extensions/JsonValueExtensions.cs
-GlobalSuppressions.cs
-JXmlToJsonValueConverter.cs
-JsonArray.cs
-JsonObject.cs
-JsonPrimitive.cs
-JsonType.cs
-JsonValue.cs
-JsonValueChange.cs
-JsonValueChangeEventArgs.cs
-JsonValueDynamicMetaObject.cs
-JsonValueLinqExtensions.cs
-NGenWrapper.cs
-Properties/Resources.Designer.cs
-RS.cs
diff --git a/mcs/class/System.Json-new/System.Json_test.dll.sources b/mcs/class/System.Json-new/System.Json_test.dll.sources
deleted file mode 100644 (file)
index 8d6ae22..0000000
+++ /dev/null
@@ -1 +0,0 @@
-System.Json/JsonValueTest.cs
\ No newline at end of file
index b8c49cd952bd53eac4e7967132dddbb9b7d678c5..a550ea9caa15684f460fbd452d9e502c8f3ab66e 100755 (executable)
@@ -37,22 +37,6 @@ using System.Runtime.InteropServices;
 
 // General Information about the System.Json assembly
 
-[assembly: AssemblyTitle ("System.Json.dll")]
-[assembly: AssemblyDescription ("System.Json.dll")]
 [assembly: AssemblyDefaultAlias ("System.Json.dll")]
 
-[assembly: AssemblyCompany (Consts.MonoCompany)]
-[assembly: AssemblyProduct (Consts.MonoProduct)]
-[assembly: AssemblyCopyright (Consts.MonoCopyright)]
-[assembly: AssemblyVersion (Consts.FxVersion)]
-[assembly: SatelliteContractVersion (Consts.FxVersion)]
 [assembly: AssemblyInformationalVersion (Consts.FxFileVersion)]
-[assembly: AssemblyFileVersion (Consts.FxFileVersion)]
-
-[assembly: NeutralResourcesLanguage ("en-US")]
-[assembly: AssemblyDelaySign (true)]
-[assembly: AssemblyKeyFile ("../winfx.pub")]
-
-[assembly: ComVisible (false)]
-
-[assembly: SecurityCritical]
index 906b0bf48f178ac8324ae1a357d887ee160d6007..20398a5fe6f99d89848469fcb9921a17225c9df0 100644 (file)
@@ -2,24 +2,40 @@ thisdir = class/System.Json
 SUBDIRS = 
 include ../../build/rules.make
 
+UPSTREAM_DIR = ../../../external/aspnetwebstack/src
+RESX_RESOURCES = $(UPSTREAM_DIR)/System.Json/Properties/Resources.resx
+RESOURCES = $(subst $(UPSTREAM_DIR),$(build_libdir),$(RESX_RESOURCES:.resx=.resources))
+
 LIBRARY = System.Json.dll
 LIB_MCS_FLAGS = \
+               /d:ASPNETMVC -keyfile:../winfx.pub -delaysign \
                /r:System.dll \
                /r:System.Xml.dll \
                /r:System.Core.dll \
-               /r:System.ServiceModel.Web.dll
+               /r:System.Runtime.Serialization.dll \
+               /r:System.ServiceModel.Web.dll \
+               $(RESOURCES:%=/resource:%)
+
+ifeq (4, $(FRAMEWORK_VERSION_MAJOR))
+LIB_MCS_FLAGS += /r:Microsoft.CSharp.dll
+endif
 
 TEST_MCS_FLAGS = $(LIB_MCS_FLAGS)
 
-EXTRA_DISTFILES =
+EXTRA_DISTFILES = $(RESX_RESOURCES)
 
-VALID_PROFILE := $(filter 2 4, $(FRAMEWORK_VERSION_MAJOR))
+include ../../build/library.make
 
-ifndef VALID_PROFILE
-LIBRARY_NAME = dummy-System.Json.dll
-NO_INSTALL = yes
-NO_SIGN_ASSEMBLY = yes
-NO_TEST = yes
-endif
+$(the_lib): $(RESOURCES)
 
-include ../../build/library.make
+# Canned recipe which would be useful, but make doesn't run it for some reason...
+#define run-resgen = 
+#      mkdir -p $(dir $@)
+#      $(RESGEN) $< $@
+#endef
+
+$(build_libdir)/System.Json/Properties/Resources.resources: $(UPSTREAM_DIR)/System.Json/Properties/Resources.resx
+#      Doesn't work for some reason
+#      $(run-resgen)
+       mkdir -p $(dir $@)
+       $(RESGEN) $< $@
index 47a9ceed63acc60eeff70671bb6a16c17d727b69..7e0d4bdeb139743e9651a8e70de0fb7183d81054 100644 (file)
@@ -1,8 +1,25 @@
 ../../build/common/Consts.cs
+../../build/common/Locale.cs
+../../build/common/MonoTODOAttribute.cs
 Assembly/AssemblyInfo.cs
-System.Json/JsonArray.cs
-System.Json/JsonObject.cs
-System.Json/JsonPrimitive.cs
-System.Json/JsonType.cs
-System.Json/JsonValue.cs
-../System.ServiceModel.Web/System.Runtime.Serialization.Json/JavaScriptReader.cs
\ No newline at end of file
+
+../../../external/aspnetwebstack/src/RS.cs
+../../../external/aspnetwebstack/src/CommonAssemblyInfo.cs
+../../../external/aspnetwebstack/src/TransparentCommonAssemblyInfo.cs
+
+../../../external/aspnetwebstack/src/System.Json/Properties/AssemblyInfo.cs
+../../../external/aspnetwebstack/src/System.Json/Extensions/JsonValueExtensions.cs
+../../../external/aspnetwebstack/src/System.Json/GlobalSuppressions.cs
+../../../external/aspnetwebstack/src/System.Json/JXmlToJsonValueConverter.cs
+../../../external/aspnetwebstack/src/System.Json/JsonArray.cs
+../../../external/aspnetwebstack/src/System.Json/JsonObject.cs
+../../../external/aspnetwebstack/src/System.Json/JsonPrimitive.cs
+../../../external/aspnetwebstack/src/System.Json/JsonType.cs
+../../../external/aspnetwebstack/src/System.Json/JsonValue.cs
+../../../external/aspnetwebstack/src/System.Json/JsonValueChange.cs
+../../../external/aspnetwebstack/src/System.Json/JsonValueChangeEventArgs.cs
+../../../external/aspnetwebstack/src/System.Json/JsonValueDynamicMetaObject.cs
+../../../external/aspnetwebstack/src/System.Json/JsonValueLinqExtensions.cs
+../../../external/aspnetwebstack/src/System.Json/NGenWrapper.cs
+../../../external/aspnetwebstack/src/System.Json/Properties/Resources.Designer.cs
+
diff --git a/mcs/class/System.Json/System.Json/ChangeLog b/mcs/class/System.Json/System.Json/ChangeLog
deleted file mode 100644 (file)
index 2c56ec1..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-2010-03-10  Atsushi Enomoto  <atsushi@ximian.com>
-
-       * JsonReader.cs : moved to Sys.SM.Web/Sys.R.S.Json.
-
-2010-03-10  Atsushi Enomoto  <atsushi@ximian.com>
-
-       * JsonValue.cs : use Sys.SM.Web.dll's JavaScriptObjectDeserializer
-         for silverlight sdk / moonlight compatibility.
-       * JsonReader.cs : renamed to JavaScriptReader (for disambiguation in
-         Sys.SM.Web.dll). Now it is native-type based and used by the above
-         deserializer.
-
-2010-02-18  Atsushi Enomoto  <atsushi@ximian.com>
-
-       * JsonValue.cs : fix string escaping, it was giving wrong output
-         after \" and \\.
-
-2010-02-18  Atsushi Enomoto  <atsushi@ximian.com>
-
-       * JsonReader.cs : line endings after a value should not result in
-         a parse error.
-       * JsonObject.cs : duplicate object key "SHOULD" not be used, but
-         they are not rejected. So, make it a bit sloppy.
-
-2010-01-27  Atsushi Enomoto  <atsushi@ximian.com>
-
-       * JsonReader.cs : oops, added previous change to wrong position.
-
-2010-01-27  Atsushi Enomoto  <atsushi@ximian.com>
-
-       * JsonReader.cs : It seems it can either return int, long or decimal
-         depending on the value. Users cannot really predict what type of
-         the primitive value can be returned and casts to specific types
-         very likely fail. doh.
-
-2010-01-27  Atsushi Enomoto  <atsushi@ximian.com>
-
-       * JsonReader.cs : use decimal instead of int to parse decimal part
-         of numeric value. It can parse bigger value than int now (like
-         tweet id).
-
-2009-10-05  Atsushi Enomoto  <atsushi@ximian.com>
-
-       * JsonReader.cs : \uXXXX parser was totally wrong, giving wrong #.
-
-2009-09-22  Atsushi Enomoto  <atsushi@ximian.com>
-
-       * JsonValue.cs, JsonReader.cs, JsonPrimitive.cs :
-         Handle "null" values, as string, so far (haven't tried what .NET
-         actually does).
-         Fix array ToString() that missed commas (while Save() worked fine -
-         it has different serialization logic).
-
-2009-01-15  Atsushi Enomoto  <atsushi@ximian.com>
-
-       * JsonReader.cs : consume ',' between items in an array.
-
-2008-09-15  Atsushi Enomoto  <atsushi@ximian.com>
-
-       * JsonObject.cs, JsonValue.cs : SL2b2 updates.
-
-2008-08-28  Atsushi Enomoto  <atsushi@ximian.com>
-
-       * JsonReader.cs : a ReadChar() is missing in number parsing.
-
-2008-06-10  Atsushi Enomoto  <atsushi@ximian.com>
-
-       * JsonArray.cs, JsonObject.cs, JsonPrimitive.cs, JsonReader.cs,
-         JsonType.cs, JsonValue.cs, MergedEnumerator.cs : initial checkin.
-
diff --git a/mcs/class/System.Json/System.Json/JsonArray.cs b/mcs/class/System.Json/System.Json/JsonArray.cs
deleted file mode 100644 (file)
index c630044..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Text;
-
-namespace System.Json
-{
-       public class JsonArray : JsonValue, IList<JsonValue>
-       {
-               List<JsonValue> list;
-
-               public JsonArray (params JsonValue [] items)
-               {
-                       list = new List<JsonValue> ();
-                       AddRange (items);
-               }
-
-               public JsonArray (IEnumerable<JsonValue> items)
-               {
-                       if (items == null)
-                               throw new ArgumentNullException ("items");
-
-                       list = new List<JsonValue> (items);
-               }
-
-               public override int Count {
-                       get { return list.Count; }
-               }
-
-               public bool IsReadOnly {
-                       get { return false; }
-               }
-
-               public override sealed JsonValue this [int index] {
-                       get { return list [index]; }
-                       set { list [index] = value; }
-               }
-
-               public override JsonType JsonType {
-                       get { return JsonType.Array; }
-               }
-
-               public void Add (JsonValue item)
-               {
-                       if (item == null)
-                               throw new ArgumentNullException ("item");
-
-                       list.Add (item);
-               }
-
-               public void AddRange (IEnumerable<JsonValue> items)
-               {
-                       if (items == null)
-                               throw new ArgumentNullException ("items");
-
-                       list.AddRange (items);
-               }
-
-               public void AddRange (params JsonValue [] items)
-               {
-                       if (items == null)
-                               return;
-
-                       list.AddRange (items);
-               }
-
-               public void Clear ()
-               {
-                       list.Clear ();
-               }
-
-               public bool Contains (JsonValue item)
-               {
-                       return list.Contains (item);
-               }
-
-               public void CopyTo (JsonValue [] array, int arrayIndex)
-               {
-                       list.CopyTo (array, arrayIndex);
-               }
-
-               public int IndexOf (JsonValue item)
-               {
-                       return list.IndexOf (item);
-               }
-
-               public void Insert (int index, JsonValue item)
-               {
-                       list.Insert (index, item);
-               }
-
-               public bool Remove (JsonValue item)
-               {
-                       return list.Remove (item);
-               }
-
-               public void RemoveAt (int index)
-               {
-                       list.RemoveAt (index);
-               }
-
-               public override void Save (Stream stream)
-               {
-                       if (stream == null)
-                               throw new ArgumentNullException ("stream");
-                       stream.WriteByte ((byte) '[');
-                       for (int i = 0; i < list.Count; i++) {
-                               JsonValue v = list [i];
-                               if (v != null)
-                                       v.Save (stream);
-                               else {
-                                       stream.WriteByte ((byte) 'n');
-                                       stream.WriteByte ((byte) 'u');
-                                       stream.WriteByte ((byte) 'l');
-                                       stream.WriteByte ((byte) 'l');
-                               }
-
-                               if (i < Count - 1) {
-                                       stream.WriteByte ((byte) ',');
-                                       stream.WriteByte ((byte) ' ');
-                               }
-                       }
-                       stream.WriteByte ((byte) ']');
-               }
-
-               IEnumerator<JsonValue> IEnumerable<JsonValue>.GetEnumerator ()
-               {
-                       return list.GetEnumerator ();
-               }
-
-               IEnumerator IEnumerable.GetEnumerator ()
-               {
-                       return list.GetEnumerator ();
-               }
-       }
-}
diff --git a/mcs/class/System.Json/System.Json/JsonObject.cs b/mcs/class/System.Json/System.Json/JsonObject.cs
deleted file mode 100644 (file)
index 33177b1..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Text;
-
-using JsonPair = System.Collections.Generic.KeyValuePair<string, System.Json.JsonValue>;
-using JsonPairEnumerable = System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, System.Json.JsonValue>>;
-
-namespace System.Json
-{
-       public class JsonObject : JsonValue, IDictionary<string, JsonValue>, ICollection<JsonPair>
-       {
-               Dictionary<string, JsonValue> map;
-
-               public JsonObject (params JsonPair [] items)
-               {
-                       map = new Dictionary<string, JsonValue> ();
-
-                       if (items != null)
-                               AddRange (items);
-               }
-
-               public JsonObject (JsonPairEnumerable items)
-               {
-                       if (items == null)
-                               throw new ArgumentNullException ("items");
-
-                       map = new Dictionary<string, JsonValue> ();
-                       AddRange (items);
-               }
-
-               public override int Count {
-                       get { return map.Count; }
-               }
-
-               public IEnumerator<JsonPair> GetEnumerator ()
-               {
-                       return map.GetEnumerator ();
-               }
-
-               IEnumerator IEnumerable.GetEnumerator ()
-               {
-                       return map.GetEnumerator ();
-               }
-
-               public override sealed JsonValue this [string key] {
-                       get { return map [key]; }
-                       set { map [key] = value; }
-               }
-
-               public override JsonType JsonType {
-                       get { return JsonType.Object; }
-               }
-
-               public ICollection<string> Keys {
-                       get { return map.Keys; }
-               }
-
-               public ICollection<JsonValue> Values {
-                       get { return map.Values; }
-               }
-
-               public void Add (string key, JsonValue value)
-               {
-                       if (key == null)
-                               throw new ArgumentNullException ("key");
-
-                       map.Add (key, value);
-               }
-
-               public void Add (JsonPair pair)
-               {
-                       Add (pair.Key, pair.Value);
-               }
-
-               public void AddRange (JsonPairEnumerable items)
-               {
-                       if (items == null)
-                               throw new ArgumentNullException ("items");
-
-                       foreach (var pair in items)
-                               map.Add (pair.Key, pair.Value);
-               }
-
-               public void AddRange (params JsonPair [] items)
-               {
-                       AddRange ((JsonPairEnumerable) items);
-               }
-
-               public void Clear ()
-               {
-                       map.Clear ();
-               }
-
-               bool ICollection<JsonPair>.Contains (JsonPair item)
-               {
-                       return (map as ICollection<JsonPair>).Contains (item);
-               }
-
-               bool ICollection<JsonPair>.Remove (JsonPair item)
-               {
-                       return (map as ICollection<JsonPair>).Remove (item);
-               }
-
-               public override bool ContainsKey (string key)
-               {
-                       if (key == null)
-                               throw new ArgumentNullException ("key");
-
-                       return map.ContainsKey (key);
-               }
-
-               public void CopyTo (JsonPair [] array, int arrayIndex)
-               {
-                       (map as ICollection<JsonPair>).CopyTo (array, arrayIndex);
-               }
-
-               public bool Remove (string key)
-               {
-                       if (key == null)
-                               throw new ArgumentNullException ("key");
-
-                       return map.Remove (key);
-               }
-
-               bool ICollection<JsonPair>.IsReadOnly {
-                       get { return false; }
-               }
-
-               public override void Save (Stream stream)
-               {
-                       if (stream == null)
-                               throw new ArgumentNullException ("stream");
-                       stream.WriteByte ((byte) '{');
-                       foreach (JsonPair pair in map) {
-                               stream.WriteByte ((byte) '"');
-                               byte [] bytes = Encoding.UTF8.GetBytes (EscapeString (pair.Key));
-                               stream.Write (bytes, 0, bytes.Length);
-                               stream.WriteByte ((byte) '"');
-                               stream.WriteByte ((byte) ',');
-                               stream.WriteByte ((byte) ' ');
-                               if (pair.Value == null) {
-                                       stream.WriteByte ((byte) 'n');
-                                       stream.WriteByte ((byte) 'u');
-                                       stream.WriteByte ((byte) 'l');
-                                       stream.WriteByte ((byte) 'l');
-                               } else
-                                       pair.Value.Save (stream);
-                       }
-                       stream.WriteByte ((byte) '}');
-               }
-
-               public bool TryGetValue (string key, out JsonValue value)
-               {
-                       return map.TryGetValue (key, out value);
-               }
-       }
-}
diff --git a/mcs/class/System.Json/System.Json/JsonPrimitive.cs b/mcs/class/System.Json/System.Json/JsonPrimitive.cs
deleted file mode 100644 (file)
index 6451878..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Text;
-
-namespace System.Json
-{
-       public class JsonPrimitive : JsonValue
-       {
-               object value;
-
-               public JsonPrimitive (bool value)
-               {
-                       this.value = value;
-               }
-
-               public JsonPrimitive (byte value)
-               {
-                       this.value = value;
-               }
-
-               public JsonPrimitive (char value)
-               {
-                       this.value = value;
-               }
-
-               public JsonPrimitive (decimal value)
-               {
-                       this.value = value;
-               }
-
-               public JsonPrimitive (double value)
-               {
-                       this.value = value;
-               }
-
-               public JsonPrimitive (float value)
-               {
-                       this.value = value;
-               }
-
-               public JsonPrimitive (int value)
-               {
-                       this.value = value;
-               }
-
-               public JsonPrimitive (long value)
-               {
-                       this.value = value;
-               }
-
-               public JsonPrimitive (sbyte value)
-               {
-                       this.value = value;
-               }
-
-               public JsonPrimitive (short value)
-               {
-                       this.value = value;
-               }
-
-               public JsonPrimitive (string value)
-               {
-                       this.value = value;
-               }
-
-               public JsonPrimitive (DateTime value)
-               {
-                       this.value = value;
-               }
-
-               public JsonPrimitive (uint value)
-               {
-                       this.value = value;
-               }
-
-               public JsonPrimitive (ulong value)
-               {
-                       this.value = value;
-               }
-
-               public JsonPrimitive (ushort value)
-               {
-                       this.value = value;
-               }
-
-               public JsonPrimitive (DateTimeOffset value)
-               {
-                       this.value = value;
-               }
-
-               public JsonPrimitive (Guid value)
-               {
-                       this.value = value;
-               }
-
-               public JsonPrimitive (TimeSpan value)
-               {
-                       this.value = value;
-               }
-
-               public JsonPrimitive (Uri value)
-               {
-                       this.value = value;
-               }
-
-               internal object Value {
-                       get { return value; }
-               }
-
-               public override JsonType JsonType {
-                       get {
-                               // FIXME: what should we do for null? Handle it as null so far.
-                               if (value == null)
-                                       return JsonType.String;
-
-                               switch (Type.GetTypeCode (value.GetType ())) {
-                               case TypeCode.Boolean:
-                                       return JsonType.Boolean;
-                               case TypeCode.Char:
-                               case TypeCode.String:
-                               case TypeCode.DateTime:
-                               case TypeCode.Object: // DateTimeOffset || Guid || TimeSpan || Uri
-                                       return JsonType.String;
-                               default:
-                                       return JsonType.Number;
-                               }
-                       }
-               }
-
-               static readonly byte [] true_bytes = Encoding.UTF8.GetBytes ("true");
-               static readonly byte [] false_bytes = Encoding.UTF8.GetBytes ("false");
-
-               public override void Save (Stream stream)
-               {
-                       switch (JsonType) {
-                       case JsonType.Boolean:
-                               if ((bool) value)
-                                       stream.Write (true_bytes, 0, 4);
-                               else
-                                       stream.Write (false_bytes, 0, 5);
-                               break;
-                       case JsonType.String:
-                               stream.WriteByte ((byte) '\"');
-                               byte [] bytes = Encoding.UTF8.GetBytes (EscapeString (value.ToString ()));
-                               stream.Write (bytes, 0, bytes.Length);
-                               stream.WriteByte ((byte) '\"');
-                               break;
-                       default:
-                               bytes = Encoding.UTF8.GetBytes (GetFormattedString ());
-                               stream.Write (bytes, 0, bytes.Length);
-                               break;
-                       }
-               }
-
-               internal string GetFormattedString ()
-               {
-                       switch (JsonType) {
-                       case JsonType.String:
-                               if (value is string || value == null)
-                                       return (string) value;
-                               throw new NotImplementedException ("GetFormattedString from value type " + value.GetType ());
-                       case JsonType.Number:
-                               return ((IFormattable) value).ToString ("G", NumberFormatInfo.InvariantInfo);
-                       default:
-                               throw new InvalidOperationException ();
-                       }
-               }
-       }
-}
diff --git a/mcs/class/System.Json/System.Json/JsonType.cs b/mcs/class/System.Json/System.Json/JsonType.cs
deleted file mode 100644 (file)
index c04f574..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-namespace System.Json
-{
-       public enum JsonType
-       {
-               String,
-               Number,
-               Object,
-               Array,
-               Boolean,
-       }
-}
diff --git a/mcs/class/System.Json/System.Json/JsonValue.cs b/mcs/class/System.Json/System.Json/JsonValue.cs
deleted file mode 100644 (file)
index 1d16b88..0000000
+++ /dev/null
@@ -1,460 +0,0 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Runtime.Serialization.Json;
-using System.Text;
-
-using JsonPair = System.Collections.Generic.KeyValuePair<string, System.Json.JsonValue>;
-
-
-namespace System.Json
-{
-       public abstract class JsonValue : IEnumerable
-       {
-               public static JsonValue Load (Stream stream)
-               {
-                       if (stream == null)
-                               throw new ArgumentNullException ("stream");
-                       return Load (new StreamReader (stream, true));
-               }
-
-               public static JsonValue Load (TextReader textReader)
-               {
-                       if (textReader == null)
-                               throw new ArgumentNullException ("textReader");
-
-                       var ret = new JavaScriptReader (textReader, true).Read ();
-
-                       return ToJsonValue (ret);
-               }
-
-               static IEnumerable<KeyValuePair<string,JsonValue>> ToJsonPairEnumerable (IEnumerable<KeyValuePair<string,object>> kvpc)
-               {
-                       foreach (var kvp in kvpc)
-                               yield return new KeyValuePair<string,JsonValue> (kvp.Key, ToJsonValue (kvp.Value));
-               }
-
-               static IEnumerable<JsonValue> ToJsonValueEnumerable (IEnumerable<object> arr)
-               {
-                       foreach (var obj in arr)
-                               yield return ToJsonValue (obj);
-               }
-
-               static JsonValue ToJsonValue (object ret)
-               {
-                       if (ret == null)
-                               return null;
-                       var kvpc = ret as IEnumerable<KeyValuePair<string,object>>;
-                       if (kvpc != null)
-                               return new JsonObject (ToJsonPairEnumerable (kvpc));
-                       var arr = ret as IEnumerable<object>;
-                       if (arr != null)
-                               return new JsonArray (ToJsonValueEnumerable (arr));
-
-                       if (ret is bool)
-                               return new JsonPrimitive ((bool) ret);
-                       if (ret is byte)
-                               return new JsonPrimitive ((byte) ret);
-                       if (ret is char)
-                               return new JsonPrimitive ((char) ret);
-                       if (ret is decimal)
-                               return new JsonPrimitive ((decimal) ret);
-                       if (ret is double)
-                               return new JsonPrimitive ((double) ret);
-                       if (ret is float)
-                               return new JsonPrimitive ((float) ret);
-                       if (ret is int)
-                               return new JsonPrimitive ((int) ret);
-                       if (ret is long)
-                               return new JsonPrimitive ((long) ret);
-                       if (ret is sbyte)
-                               return new JsonPrimitive ((sbyte) ret);
-                       if (ret is short)
-                               return new JsonPrimitive ((short) ret);
-                       if (ret is string)
-                               return new JsonPrimitive ((string) ret);
-                       if (ret is uint)
-                               return new JsonPrimitive ((uint) ret);
-                       if (ret is ulong)
-                               return new JsonPrimitive ((ulong) ret);
-                       if (ret is ushort)
-                               return new JsonPrimitive ((ushort) ret);
-                       if (ret is DateTime)
-                               return new JsonPrimitive ((DateTime) ret);
-                       if (ret is DateTimeOffset)
-                               return new JsonPrimitive ((DateTimeOffset) ret);
-                       if (ret is Guid)
-                               return new JsonPrimitive ((Guid) ret);
-                       if (ret is TimeSpan)
-                               return new JsonPrimitive ((TimeSpan) ret);
-                       if (ret is Uri)
-                               return new JsonPrimitive ((Uri) ret);
-                       throw new NotSupportedException (String.Format ("Unexpected parser return type: {0}", ret.GetType ()));
-               }
-
-               public static JsonValue Parse (string jsonString)
-               {
-                       if (jsonString == null)
-                               throw new ArgumentNullException ("jsonString");
-                       return Load (new StringReader (jsonString));
-               }
-
-               public virtual int Count {
-                       get { throw new InvalidOperationException (); }
-               }
-
-               public abstract JsonType JsonType { get; }
-
-               public virtual JsonValue this [int index] {
-                       get { throw new InvalidOperationException (); }
-                       set { throw new InvalidOperationException (); }
-               }
-
-               public virtual JsonValue this [string key] {
-                       get { throw new InvalidOperationException (); }
-                       set { throw new InvalidOperationException (); }
-               }
-
-               public virtual bool ContainsKey (string key)
-               {
-                       throw new InvalidOperationException ();
-               }
-
-               public virtual void Save (Stream stream)
-               {
-                       if (stream == null)
-                               throw new ArgumentNullException ("stream");
-                       Save (new StreamWriter (stream));
-               }
-
-               public virtual void Save (TextWriter textWriter)
-               {
-                       if (textWriter == null)
-                               throw new ArgumentNullException ("textWriter");
-                       SaveInternal (textWriter);
-               }
-               
-               void SaveInternal (TextWriter w)
-               {
-                       switch (JsonType) {
-                       case JsonType.Object:
-                               w.Write ('{');
-                               bool following = false;
-                               foreach (JsonPair pair in ((JsonObject) this)) {
-                                       if (following)
-                                               w.Write (", ");
-                                       w.Write ('\"');
-                                       w.Write (EscapeString (pair.Key));
-                                       w.Write ("\": ");
-                                       if (pair.Value == null)
-                                               w.Write ("null");
-                                       else
-                                               pair.Value.SaveInternal (w);
-                                       following = true;
-                               }
-                               w.Write ('}');
-                               break;
-                       case JsonType.Array:
-                               w.Write ('[');
-                               following = false;
-                               foreach (JsonValue v in ((JsonArray) this)) {
-                                       if (following)
-                                               w.Write (", ");
-                                       if (v != null) 
-                                               v.SaveInternal (w);
-                                       else
-                                               w.Write ("null");
-                                       following = true;
-                               }
-                               w.Write (']');
-                               break;
-                       case JsonType.Boolean:
-                               w.Write ((bool) this ? "true" : "false");
-                               break;
-                       case JsonType.String:
-                               w.Write ('"');
-                               w.Write (EscapeString (((JsonPrimitive) this).GetFormattedString ()));
-                               w.Write ('"');
-                               break;
-                       default:
-                               w.Write (((JsonPrimitive) this).GetFormattedString ());
-                               break;
-                       }
-               }
-
-               public override string ToString ()
-               {
-                       StringWriter sw = new StringWriter ();
-                       Save (sw);
-                       return sw.ToString ();
-               }
-
-               IEnumerator IEnumerable.GetEnumerator ()
-               {
-                       throw new InvalidOperationException ();
-               }
-
-               internal string EscapeString (string src)
-               {
-                       if (src == null)
-                               return null;
-
-                       for (int i = 0; i < src.Length; i++)
-                               if (src [i] == '"' || src [i] == '\\') {
-                                       var sb = new StringBuilder ();
-                                       if (i > 0)
-                                               sb.Append (src, 0, i);
-                                       return DoEscapeString (sb, src, i);
-                               }
-                       return src;
-               }
-
-               string DoEscapeString (StringBuilder sb, string src, int cur)
-               {
-                       int start = cur;
-                       for (int i = cur; i < src.Length; i++)
-                               if (src [i] == '"' || src [i] == '\\') {
-                                       sb.Append (src, start, i - start);
-                                       sb.Append ('\\');
-                                       sb.Append (src [i++]);
-                                       start = i;
-                               }
-                       sb.Append (src, start, src.Length - start);
-                       return sb.ToString ();
-               }
-
-               // CLI -> JsonValue
-
-               public static implicit operator JsonValue (bool value)
-               {
-                       return new JsonPrimitive (value);
-               }
-
-               public static implicit operator JsonValue (byte value)
-               {
-                       return new JsonPrimitive (value);
-               }
-
-               public static implicit operator JsonValue (char value)
-               {
-                       return new JsonPrimitive (value);
-               }
-
-               public static implicit operator JsonValue (decimal value)
-               {
-                       return new JsonPrimitive (value);
-               }
-
-               public static implicit operator JsonValue (double value)
-               {
-                       return new JsonPrimitive (value);
-               }
-
-               public static implicit operator JsonValue (float value)
-               {
-                       return new JsonPrimitive (value);
-               }
-
-               public static implicit operator JsonValue (int value)
-               {
-                       return new JsonPrimitive (value);
-               }
-
-               public static implicit operator JsonValue (long value)
-               {
-                       return new JsonPrimitive (value);
-               }
-
-               public static implicit operator JsonValue (sbyte value)
-               {
-                       return new JsonPrimitive (value);
-               }
-
-               public static implicit operator JsonValue (short value)
-               {
-                       return new JsonPrimitive (value);
-               }
-
-               public static implicit operator JsonValue (string value)
-               {
-                       return new JsonPrimitive (value);
-               }
-
-               public static implicit operator JsonValue (uint value)
-               {
-                       return new JsonPrimitive (value);
-               }
-
-               public static implicit operator JsonValue (ulong value)
-               {
-                       return new JsonPrimitive (value);
-               }
-
-               public static implicit operator JsonValue (ushort value)
-               {
-                       return new JsonPrimitive (value);
-               }
-
-               public static implicit operator JsonValue (DateTime value)
-               {
-                       return new JsonPrimitive (value);
-               }
-
-               public static implicit operator JsonValue (DateTimeOffset value)
-               {
-                       return new JsonPrimitive (value);
-               }
-
-               public static implicit operator JsonValue (Guid value)
-               {
-                       return new JsonPrimitive (value);
-               }
-
-               public static implicit operator JsonValue (TimeSpan value)
-               {
-                       return new JsonPrimitive (value);
-               }
-
-               public static implicit operator JsonValue (Uri value)
-               {
-                       return new JsonPrimitive (value);
-               }
-
-               // JsonValue -> CLI
-
-               public static implicit operator bool (JsonValue value)
-               {
-                       if (value == null)
-                               throw new ArgumentNullException ("value");
-                       return Convert.ToBoolean (((JsonPrimitive) value).Value);
-               }
-
-               public static implicit operator byte (JsonValue value)
-               {
-                       if (value == null)
-                               throw new ArgumentNullException ("value");
-                       return Convert.ToByte (((JsonPrimitive) value).Value);
-               }
-
-               public static implicit operator char (JsonValue value)
-               {
-                       if (value == null)
-                               throw new ArgumentNullException ("value");
-                       return Convert.ToChar (((JsonPrimitive) value).Value);
-               }
-
-               public static implicit operator decimal (JsonValue value)
-               {
-                       if (value == null)
-                               throw new ArgumentNullException ("value");
-                       return Convert.ToDecimal (((JsonPrimitive) value).Value);
-               }
-
-               public static implicit operator double (JsonValue value)
-               {
-                       if (value == null)
-                               throw new ArgumentNullException ("value");
-                       return Convert.ToDouble (((JsonPrimitive) value).Value);
-               }
-
-               public static implicit operator float (JsonValue value)
-               {
-                       if (value == null)
-                               throw new ArgumentNullException ("value");
-                       return Convert.ToSingle (((JsonPrimitive) value).Value);
-               }
-
-               public static implicit operator int (JsonValue value)
-               {
-                       if (value == null)
-                               throw new ArgumentNullException ("value");
-                       return Convert.ToInt32 (((JsonPrimitive) value).Value);
-               }
-
-               public static implicit operator long (JsonValue value)
-               {
-                       if (value == null)
-                               throw new ArgumentNullException ("value");
-                       return Convert.ToInt64 (((JsonPrimitive) value).Value);
-               }
-
-               public static implicit operator sbyte (JsonValue value)
-               {
-                       if (value == null)
-                               throw new ArgumentNullException ("value");
-                       return Convert.ToSByte (((JsonPrimitive) value).Value);
-               }
-
-               public static implicit operator short (JsonValue value)
-               {
-                       if (value == null)
-                               throw new ArgumentNullException ("value");
-                       return Convert.ToInt16 (((JsonPrimitive) value).Value);
-               }
-
-               public static implicit operator string (JsonValue value)
-               {
-                       if (value == null)
-                               return null;
-                       return (string) ((JsonPrimitive) value).Value;
-               }
-
-               public static implicit operator uint (JsonValue value)
-               {
-                       if (value == null)
-                               throw new ArgumentNullException ("value");
-                       return Convert.ToUInt16 (((JsonPrimitive) value).Value);
-               }
-
-               public static implicit operator ulong (JsonValue value)
-               {
-                       if (value == null)
-                               throw new ArgumentNullException ("value");
-                       return Convert.ToUInt64(((JsonPrimitive) value).Value);
-               }
-
-               public static implicit operator ushort (JsonValue value)
-               {
-                       if (value == null)
-                               throw new ArgumentNullException ("value");
-                       return Convert.ToUInt16 (((JsonPrimitive) value).Value);
-               }
-
-               public static implicit operator DateTime (JsonValue value)
-               {
-                       if (value == null)
-                               throw new ArgumentNullException ("value");
-                       return (DateTime) ((JsonPrimitive) value).Value;
-               }
-
-               public static implicit operator DateTimeOffset (JsonValue value)
-               {
-                       if (value == null)
-                               throw new ArgumentNullException ("value");
-                       return (DateTimeOffset) ((JsonPrimitive) value).Value;
-               }
-
-               public static implicit operator TimeSpan (JsonValue value)
-               {
-                       if (value == null)
-                               throw new ArgumentNullException ("value");
-                       return (TimeSpan) ((JsonPrimitive) value).Value;
-               }
-
-               public static implicit operator Guid (JsonValue value)
-               {
-                       if (value == null)
-                               throw new ArgumentNullException ("value");
-                       return (Guid) ((JsonPrimitive) value).Value;
-               }
-
-               public static implicit operator Uri (JsonValue value)
-               {
-                       if (value == null)
-                               throw new ArgumentNullException ("value");
-                       return (Uri) ((JsonPrimitive) value).Value;
-               }
-       }
-}
diff --git a/mcs/class/System.Net.Http.Formatting/Extensions.cs b/mcs/class/System.Net.Http.Formatting/Extensions.cs
new file mode 100644 (file)
index 0000000..0f92f97
--- /dev/null
@@ -0,0 +1,47 @@
+//
+// Extension.cs
+//
+// Authors:
+//     Marek Safar  <marek.safar@gmail.com>
+//
+// Copyright (C) 2012 Xamarin Inc (http://www.xamarin.com)
+//
+// 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.
+//
+
+using System.Collections.Generic;
+using System.Net.Http.Headers;
+
+//
+// Workaround for not up-to-date aspnetwebstack, once it support .net 4.5 this could be deleted
+//
+static class Extensions
+{
+       public static void TryAddWithoutValidation (this HttpHeaders headers, string key, string value)
+       {
+               headers.AddWithoutValidation (key, value);
+       }
+       
+       public static bool TryAddWithoutValidation (this HttpHeaders headers, string key, IEnumerable<string> values)
+       {
+               headers.AddWithoutValidation (key, values);
+               return true;
+       }
+}
\ No newline at end of file
diff --git a/mcs/class/System.Net.Http.Formatting/Makefile b/mcs/class/System.Net.Http.Formatting/Makefile
new file mode 100644 (file)
index 0000000..d3e1834
--- /dev/null
@@ -0,0 +1,21 @@
+thisdir = class/System.Net.Http.Formatting
+SUBDIRS = 
+include ../../build/rules.make
+
+LIBRARY = System.Net.Http.Formatting.dll
+
+
+System.Net.Http.Properties.CommonWebApiResources.resources: ../../../external/aspnetwebstack/src/Common/CommonWebApiResources.resx
+       $(RESGEN) "$<" "$@"
+       
+System.Net.Http.Properties.Resources.resources: ../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Properties/Resources.resx
+       $(RESGEN) "$<" "$@"
+
+LIB_MCS_FLAGS = -r:System.Core.dll -r:System.dll -r:System.Net.Http.dll -r:System.Xml.dll -r:System.Runtime.Serialization.dll -r:Newtonsoft.Json.dll \
+               -d:ASPNETMVC -keyfile:../winfx.pub -delaysign \
+               -resource:System.Net.Http.Properties.CommonWebApiResources.resources
+
+include ../../build/library.make
+
+$(the_lib): System.Net.Http.Properties.CommonWebApiResources.resources \
+       System.Net.Http.Properties.Resources.resources
\ No newline at end of file
diff --git a/mcs/class/System.Net.Http.Formatting/System.Net.Http.Formatting.dll.sources b/mcs/class/System.Net.Http.Formatting/System.Net.Http.Formatting.dll.sources
new file mode 100644 (file)
index 0000000..ed7b33c
--- /dev/null
@@ -0,0 +1,82 @@
+../../../external/aspnetwebstack/src/CommonAssemblyInfo.cs
+../../../external/aspnetwebstack/src/RS.cs
+../../../external/aspnetwebstack/src/TransparentCommonAssemblyInfo.cs
+
+../../../external/aspnetwebstack/src/Common/CommonWebApiResources.Designer.cs
+../../../external/aspnetwebstack/src/Common/DictionaryExtensions.cs
+../../../external/aspnetwebstack/src/Common/Error.cs
+../../../external/aspnetwebstack/src/Common/TaskHelpers.cs
+../../../external/aspnetwebstack/src/Common/TaskHelpersExtensions.cs
+
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/BufferedMediaTypeFormatter.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/ContentNegotiationResult.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/DefaultContentNegotiator.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/DelegatingEnumerable.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/FormDataCollection.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/FormUrlEncodedJson.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/FormUrlEncodedMediaTypeFormatter.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/IContentNegotiator.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/IFormatterLogger.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/IRequiredMemberSelector.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/JsonContractResolver.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/JsonMediaTypeFormatter.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/JsonReaderQuotaException.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/MediaRangeMapping.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/MediaTypeConstants.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/MediaTypeFormatterCollection.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/MediaTypeFormatter.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/MediaTypeFormatterExtensions.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/MediaTypeHeaderValueEqualityComparer.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/MediaTypeHeaderValueExtensions.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/MediaTypeMapping.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/MediaTypeMatch.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/MediaTypeWithQualityHeaderValueComparer.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/ParsedMediaTypeHeaderValue.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/QueryStringMapping.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/RequestHeaderMapping.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/ResponseFormatterSelectionResult.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/ResponseMediaTypeMatch.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/SecureJsonTextReader.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/StringComparisonHelper.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/StringWithQualityHeaderValueComparer.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/UriPathExtensionMapping.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/XHRRequestHeaderMapping.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/XmlMediaTypeFormatter.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/Parsers/FormUrlEncodedParser.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/Parsers/HttpRequestHeaderParser.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/Parsers/HttpRequestLineParser.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/Parsers/HttpResponseHeaderParser.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/Parsers/HttpStatusLineParser.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/Parsers/InternetMessageFormatHeaderParser.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/Parsers/MimeMultipartBodyPartParser.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/Parsers/MimeMultipartParser.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Formatting/Parsers/ParserState.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Internal/AsyncResultWithExtraData.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Internal/DelegatingStream.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Internal/NonClosingDelegatingStream.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Internal/UriQueryUtility.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Properties/AssemblyInfo.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Properties/Resources.Designer.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/CloneableExtensions.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/FormattingUtilities.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/GlobalSuppressions.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/HttpClientExtensions.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/HttpContentCollectionExtensions.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/HttpContentExtensions.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/HttpContentMessageExtensions.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/HttpContentMultipartExtensions.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/HttpHeaderExtensions.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/HttpMessageContent.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/HttpRequestMessageExtensions.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/HttpUnsortedHeaders.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/HttpUnsortedRequest.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/HttpUnsortedResponse.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/IMultipartStreamProvider.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/MimeBodyPart.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/MultipartFileStreamProvider.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/MultipartFormDataStreamProvider.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/MultipartMemoryStreamProvider.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/ObjectContent.cs
+../../../external/aspnetwebstack/src/System.Net.Http.Formatting/UriExtensions.cs
+
+Extensions.cs
\ No newline at end of file
diff --git a/mcs/class/System.Net.Http/System.Net.Http.Headers/ContentDispositionHeaderValue.cs b/mcs/class/System.Net.Http/System.Net.Http.Headers/ContentDispositionHeaderValue.cs
new file mode 100644 (file)
index 0000000..47f2938
--- /dev/null
@@ -0,0 +1,50 @@
+//
+// ContentDispositionHeaderValue.cs
+//
+// Authors:
+//     Marek Safar  <marek.safar@gmail.com>
+//
+// Copyright (C) 2012 Xamarin Inc (http://www.xamarin.com)
+//
+// 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.
+//
+
+using System.Collections.Generic;
+using System.Text;
+using System.Globalization;
+
+namespace System.Net.Http.Headers
+{
+       public class ContentDispositionHeaderValue : ICloneable
+       {
+               private ContentDispositionHeaderValue ()
+               {
+               }
+               
+               public string DispositionType { get; set; }
+               public string FileName { get; set; }
+               public string Name { get; set; }
+
+               object ICloneable.Clone ()
+               {
+                       return MemberwiseClone ();
+               }
+       }
+}
index 49efa5076099a86c374e613839332a696211a49c..0b66f3444c483fd623aab4005747cb32d4947d8a 100644 (file)
@@ -51,6 +51,15 @@ namespace System.Net.Http.Headers
                                return GetValues<string> ("Content-Encoding");
                        }
                }
+               
+               public ContentDispositionHeaderValue ContentDisposition {
+                       get {
+                               return GetValue<ContentDispositionHeaderValue> ("Content-Disposition");
+                       }
+                       set {
+                               AddOrRemove ("Content-Disposition", value);
+                       }
+               }
 
                public ICollection<string> ContentLanguage {
                        get {
index f88d6760d53e8e9205e34c73bd63b6c5436cc5be..daee130501b38b3f08d1ce2c1b3ed8a49de8de4e 100644 (file)
@@ -2,6 +2,7 @@
 Assembly/AssemblyInfo.cs
 System.Net.Http/ByteArrayContent.cs
 System.Net.Http/ClientCertificateOption.cs
+System.Net.Http/DelegatingHandler.cs
 System.Net.Http/HttpClient.cs
 System.Net.Http/HttpClientHandler.cs
 System.Net.Http/HttpCompletionOption.cs
@@ -16,6 +17,7 @@ System.Net.Http/StringContent.cs
 System.Net.Http.Headers/AuthenticationHeaderValue.cs
 System.Net.Http.Headers/CacheControlHeaderValue.cs
 System.Net.Http.Headers/CollectionExtensions.cs
+System.Net.Http.Headers/ContentDispositionHeaderValue.cs
 System.Net.Http.Headers/ContentRangeHeaderValue.cs
 System.Net.Http.Headers/EntityTagHeaderValue.cs
 System.Net.Http.Headers/HashCodeCalculator.cs
diff --git a/mcs/class/System.Net.Http/System.Net.Http/DelegatingHandler.cs b/mcs/class/System.Net.Http/System.Net.Http/DelegatingHandler.cs
new file mode 100644 (file)
index 0000000..5bc1aa8
--- /dev/null
@@ -0,0 +1,67 @@
+//
+// DelegatingHandler.cs
+//
+// Authors:
+//     Marek Safar  <marek.safar@gmail.com>
+//
+// Copyright (C) 2011 Xamarin Inc (http://www.xamarin.com)
+//
+// 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.
+//
+
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace System.Net.Http
+{
+       public abstract class DelegatingHandler : HttpMessageHandler
+       {
+               bool disposed;
+               
+               protected DelegatingHandler ()
+               {
+               }
+               
+               protected DelegatingHandler(HttpMessageHandler innerHandler)
+               {
+                       if (innerHandler == null)
+                               throw new ArgumentNullException ("innerHandler");
+                       
+                       InnerHandler = innerHandler;
+               }
+               
+               public HttpMessageHandler InnerHandler { get; set; }
+               
+               protected override void Dispose (bool disposing)
+               {
+                       if (disposing && !disposed) {
+                               disposed = true;
+                               InnerHandler.Dispose ();
+                       }
+                       
+                       base.Dispose (disposing);
+               }
+
+               protected internal override Task<HttpResponseMessage> SendAsync (HttpRequestMessage request, CancellationToken cancellationToken)
+               {
+                       throw new NotImplementedException ();
+               }
+       }
+}
index 89979a544b6c4aabdeae81aaed0150019f2e4b32..8a66f60421f88acd49d5794f1fb610f8b64f7de0 100644 (file)
@@ -90,6 +90,12 @@ namespace System.Net.Http
                        await SerializeToStreamAsync (buffer, null).ConfigureAwait (false);
                        buffer.Seek (0, SeekOrigin.Begin);
                }
+               
+               public Task<Stream> ReadAsStreamAsync ()
+               {
+                       // TODO:
+                       throw new NotImplementedException ();
+               }
 
                public async Task<byte[]> ReadAsByteArrayAsync ()
                {
index 746487c231c7410c026d6ec8d5c80979246b8cc8..85f8666ad662c6b7bbc8c578ccaf06c163b4abe2 100755 (executable)
@@ -47,6 +47,7 @@ TEST_EXTRA_FILES = \
        Test/Resources/* \
        Test/XmlFiles/* \
        Test/System.ServiceModel.Channels/soap-fault*.xml \
+       Test/System.ServiceModel.Channels/binary-message.raw \
        Test/System.ServiceModel.Description/dump.xml
 
 EXTRA_DISTFILES = $(RESOURCE_FILES) $(TEST_EXTRA_FILES)
diff --git a/mcs/class/System.Web.Http/Makefile b/mcs/class/System.Web.Http/Makefile
new file mode 100644 (file)
index 0000000..488e020
--- /dev/null
@@ -0,0 +1,21 @@
+thisdir = class/System.Web.Http
+SUBDIRS = 
+include ../../build/rules.make
+
+LIBRARY = System.Web.Http.dll
+
+System.Web.Http.Properties.CommonWebApiResources.resources: ../../../external/aspnetwebstack/src/Common/CommonWebApiResources.resx
+       $(RESGEN) "$<" "$@"
+       
+System.Web.Http.Properties.SRResources.resources: ../../../external/aspnetwebstack/src/System.Web.Http/Properties/SRResources.resx
+       $(RESGEN) "$<" "$@"
+
+
+LIB_MCS_FLAGS = -r:System.Core.dll -r:System.dll -r:System.Xml.dll -r:System.Net.Http.dll -r:System.ComponentModel.DataAnnotations.dll \
+               -r:System.Net.Http.Formatting.dll -r:System.Runtime.Caching.dll -r:System.Runtime.Serialization.dll -r:System.Data.Linq.dll \
+               -d:ASPNETMVC -keyfile:../winfx.pub -delaysign
+
+include ../../build/library.make
+
+$(the_lib): System.Web.Http.Properties.CommonWebApiResources.resources \
+       System.Web.Http.Properties.SRResources.resources
\ No newline at end of file
diff --git a/mcs/class/System.Web.Http/System.Web.Http.dll.sources b/mcs/class/System.Web.Http/System.Web.Http.dll.sources
new file mode 100644 (file)
index 0000000..9e70f9c
--- /dev/null
@@ -0,0 +1,265 @@
+../../../external/aspnetwebstack/src/CommonAssemblyInfo.cs
+../../../external/aspnetwebstack/src/RS.cs
+../../../external/aspnetwebstack/src/AptcaCommonAssemblyInfo.cs
+
+../../../external/aspnetwebstack/src/Common/CommonWebApiResources.Designer.cs
+../../../external/aspnetwebstack/src/Common/DictionaryExtensions.cs
+../../../external/aspnetwebstack/src/Common/Error.cs
+../../../external/aspnetwebstack/src/Common/HttpMethodHelper.cs
+../../../external/aspnetwebstack/src/Common/PrefixContainer.cs
+../../../external/aspnetwebstack/src/Common/TaskHelpers.cs
+../../../external/aspnetwebstack/src/Common/TaskHelpersExtensions.cs
+
+../../../external/aspnetwebstack/src/System.Web.Http/Controllers/ApiControllerActionInvoker.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Controllers/ApiControllerActionSelector.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Controllers/HttpActionBinding.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Controllers/HttpActionContext.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Controllers/HttpActionContextExtensions.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Controllers/HttpActionDescriptor.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Controllers/HttpControllerConfigurationAttribute.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Controllers/HttpControllerContext.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Controllers/HttpControllerDescriptor.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Controllers/HttpParameterBinding.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Controllers/HttpParameterDescriptor.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Controllers/IActionHttpMethodProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Controllers/IActionMethodSelector.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Controllers/IActionResultConverter.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Controllers/IActionValueBinder.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Controllers/IHttpActionInvoker.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Controllers/IHttpActionSelector.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Controllers/IHttpController.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Controllers/ReflectedHttpActionDescriptor.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Controllers/ReflectedHttpParameterDescriptor.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Controllers/ResponseMessageResultConverter.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Controllers/ValueResultConverter.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Controllers/VoidResultConverter.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Description/ApiDescription.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Description/ApiExplorer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Description/ApiExplorerSettingsAttribute.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Description/ApiParameterDescription.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Description/ApiParameterSource.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Description/IApiExplorer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Description/IDocumentationProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Dispatcher/DefaultBuildManager.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Dispatcher/DefaultHttpControllerActivator.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Dispatcher/DefaultHttpControllerFactory.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Dispatcher/ExceptionSurrogate.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Dispatcher/HttpControllerDispatcher.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Dispatcher/HttpControllerTypeCache.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Dispatcher/HttpControllerTypeCacheSerializer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Dispatcher/HttpControllerTypeCacheUtil.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Dispatcher/IBuildManager.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Dispatcher/IHttpControllerActivator.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Dispatcher/IHttpControllerFactory.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Filters/ActionDescriptorFilterProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Filters/ActionFilterAttribute.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Filters/AuthorizationFilterAttribute.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Filters/ConfigurationFilterProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Filters/ExceptionFilterAttribute.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Filters/FilterAttribute.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Filters/FilterInfoComparer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Filters/FilterInfo.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Filters/FilterScope.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Filters/HttpActionExecutedContext.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Filters/HttpFilterCollection.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Filters/IActionFilter.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Filters/IAuthorizationFilter.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Filters/IExceptionFilter.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Filters/IFilter.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Filters/IFilterProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Hosting/HttpPipelineFactory.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Hosting/HttpPropertyKeys.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Internal/CollectionModelBinderUtil.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Internal/DataTypeUtil.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Internal/HttpActionContextExtensions.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Internal/HttpParameterBindingExtensions.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Internal/MemberInfoExtensions.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Internal/ParameterInfoExtensions.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Internal/TypeActivator.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Internal/TypeDescriptorHelper.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Internal/TypeHelper.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Internal/UriQueryUtility.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Metadata/IMetadataAware.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Metadata/ModelMetadata.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Metadata/ModelMetadataProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Metadata/Providers/AssociatedMetadataProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Metadata/Providers/CachedAssociatedMetadataProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Metadata/Providers/CachedDataAnnotationsMetadataAttributes.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Metadata/Providers/CachedDataAnnotationsModelMetadata.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Metadata/Providers/CachedDataAnnotationsModelMetadataProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Metadata/Providers/CachedModelMetadata.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Metadata/Providers/EmptyMetadataProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/CancellationTokenParameterBinding.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/CustomModelBinderAttribute.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/DefaultActionValueBinder.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/ErrorParameterBinding.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/FormatterParameterBinding.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/FormDataCollectionExtensions.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/HttpBindingBehaviorAttribute.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/HttpBindingBehavior.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/HttpRequestParameterBinding.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/IModelBinder.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/JQueryMVCFormUrlEncodedFormatter.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/ModelBinderAttribute.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/ModelBinderConfig.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/ModelBinderErrorMessageProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/ModelBinderParameterBinding.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/ModelBinderProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/ModelBindingContext.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/ModelBindingHelper.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/ModelErrorCollection.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/ModelError.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/ModelState.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/ModelStateDictionary.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/Binders/ArrayModelBinder.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/Binders/ArrayModelBinderProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/Binders/BinaryDataModelBinderProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/Binders/CollectionModelBinder.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/Binders/CollectionModelBinderProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/Binders/ComplexModelDto.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/Binders/ComplexModelDtoModelBinder.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/Binders/ComplexModelDtoModelBinderProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/Binders/ComplexModelDtoResult.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/Binders/CompositeModelBinder.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/Binders/CompositeModelBinderProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/Binders/DictionaryModelBinder.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/Binders/DictionaryModelBinderProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/Binders/GenericModelBinderProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/Binders/KeyValuePairModelBinder.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/Binders/KeyValuePairModelBinderProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/Binders/MutableObjectModelBinder.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/Binders/MutableObjectModelBinderProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/Binders/SimpleModelBinderProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/Binders/TypeConverterModelBinder.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/Binders/TypeConverterModelBinderProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/Binders/TypeMatchModelBinder.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ModelBinding/Binders/TypeMatchModelBinderProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Properties/AssemblyInfo.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Properties/SRResources.Designer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Query/DynamicQueryable.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Query/ODataQueryDeserializer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Query/ParseException.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Query/QueryComposer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Query/QueryResolver.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Query/QueryValidator.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Query/ServiceQuery.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Query/ServiceQueryPart.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Routing/BoundRouteTemplate.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Routing/HttpMethodConstraint.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Routing/HttpParsedRoute.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Routing/HttpRoute.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Routing/HttpRouteData.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Routing/HttpRouteDirection.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Routing/HttpRouteParser.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Routing/HttpRouteValueDictionary.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Routing/HttpVirtualPathData.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Routing/IHttpRouteConstraint.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Routing/IHttpRoute.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Routing/IHttpRouteData.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Routing/IHttpVirtualPathData.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Routing/PathContentSegment.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Routing/PathLiteralSubsegment.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Routing/PathParameterSubsegment.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Routing/PathSegment.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Routing/PathSeparatorSegment.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Routing/PathSubsegment.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Routing/UrlHelper.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Services/DefaultServiceResolver.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Services/DependencyResolver.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Services/IDependencyResolver.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/FormattingUtilities.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/HttpRequestMessageExtensions.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/IFormatterTracer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/ITraceManager.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/ITraceWriter.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/ITraceWriterExtensions.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/TraceCategories.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/TraceKind.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/TraceLevel.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/TraceManager.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/TraceRecord.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/Tracers/ActionFilterAttributeTracer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/Tracers/ActionFilterTracer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/Tracers/ActionValueBinderTracer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/Tracers/AuthorizationFilterAttributeTracer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/Tracers/AuthorizationFilterTracer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/Tracers/BufferedMediaTypeFormatterTracer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/Tracers/ContentNegotiatorTracer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/Tracers/ExceptionFilterAttributeTracer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/Tracers/ExceptionFilterTracer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/Tracers/FilterTracer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/Tracers/FormatterParameterBindingTracer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/Tracers/FormUrlEncodedMediaTypeFormatterTracer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/Tracers/HttpActionBindingTracer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/Tracers/HttpActionDescriptorTracer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/Tracers/HttpActionInvokerTracer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/Tracers/HttpActionSelectorTracer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/Tracers/HttpControllerActivatorTracer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/Tracers/HttpControllerFactoryTracer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/Tracers/HttpControllerTracer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/Tracers/HttpParameterBindingTracer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/Tracers/JsonMediaTypeFormatterTracer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/Tracers/MediaTypeFormatterTracer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/Tracers/MessageHandlerTracer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/Tracers/RequestMessageHandlerTracer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Tracing/Tracers/XmlMediaTypeFormatterTracer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Validation/DefaultBodyModelValidator.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Validation/IBodyModelValidator.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Validation/ModelStateFormatterLogger.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Validation/ModelValidatedEventArgs.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Validation/ModelValidatingEventArgs.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Validation/ModelValidationNode.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Validation/ModelValidationRequiredMemberSelector.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Validation/ModelValidationResult.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Validation/ModelValidator.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Validation/ModelValidatorProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Validation/Providers/AssociatedValidatorProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Validation/Providers/DataAnnotationsModelValidatorProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Validation/Providers/DataMemberModelValidatorProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Validation/Providers/RequiredMemberModelValidatorProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Validation/Validators/DataAnnotationsModelValidator.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Validation/Validators/RequiredMemberModelValidator.cs
+../../../external/aspnetwebstack/src/System.Web.Http/Validation/Validators/ValidatableObjectAdapter.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ValueProviders/IEnumerableValueProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ValueProviders/IUriValueProviderFactory.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ValueProviders/IValueProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ValueProviders/ValueProviderAttribute.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ValueProviders/ValueProviderFactory.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ValueProviders/ValueProviderResult.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ValueProviders/Providers/CompositeValueProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ValueProviders/Providers/CompositeValueProviderFactory.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ValueProviders/Providers/ElementalValueProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ValueProviders/Providers/NameValueCollectionValueProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ValueProviders/Providers/QueryStringValueProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ValueProviders/Providers/QueryStringValueProviderFactory.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ValueProviders/Providers/RouteDataValueProvider.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ValueProviders/Providers/RouteDataValueProviderFactory.cs
+../../../external/aspnetwebstack/src/System.Web.Http/AcceptVerbsAttribute.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ActionNameAttribute.cs
+../../../external/aspnetwebstack/src/System.Web.Http/AllowAnonymousAttribute.cs
+../../../external/aspnetwebstack/src/System.Web.Http/ApiController.cs
+../../../external/aspnetwebstack/src/System.Web.Http/AuthorizeAttribute.cs
+../../../external/aspnetwebstack/src/System.Web.Http/DependencyResolverExtensions.cs
+../../../external/aspnetwebstack/src/System.Web.Http/FromBodyAttribute.cs
+../../../external/aspnetwebstack/src/System.Web.Http/FromUriAttribute.cs
+../../../external/aspnetwebstack/src/System.Web.Http/GlobalSuppressions.cs
+../../../external/aspnetwebstack/src/System.Web.Http/HttpBindNeverAttribute.cs
+../../../external/aspnetwebstack/src/System.Web.Http/HttpBindRequiredAttribute.cs
+../../../external/aspnetwebstack/src/System.Web.Http/HttpConfiguration.cs
+../../../external/aspnetwebstack/src/System.Web.Http/HttpDeleteAttribute.cs
+../../../external/aspnetwebstack/src/System.Web.Http/HttpGetAttribute.cs
+../../../external/aspnetwebstack/src/System.Web.Http/HttpHeadAttribute.cs
+../../../external/aspnetwebstack/src/System.Web.Http/HttpOptionsAttribute.cs
+../../../external/aspnetwebstack/src/System.Web.Http/HttpPatchAttribute.cs
+../../../external/aspnetwebstack/src/System.Web.Http/HttpPostAttribute.cs
+../../../external/aspnetwebstack/src/System.Web.Http/HttpPutAttribute.cs
+../../../external/aspnetwebstack/src/System.Web.Http/HttpRequestMessageExtensions.cs
+../../../external/aspnetwebstack/src/System.Web.Http/HttpResponseException.cs
+../../../external/aspnetwebstack/src/System.Web.Http/HttpResponseMessageExtensions.cs
+../../../external/aspnetwebstack/src/System.Web.Http/HttpRouteCollection.cs
+../../../external/aspnetwebstack/src/System.Web.Http/HttpRouteCollectionExtensions.cs
+../../../external/aspnetwebstack/src/System.Web.Http/HttpServer.cs
+../../../external/aspnetwebstack/src/System.Web.Http/IncludeErrorDetailPolicy.cs
+../../../external/aspnetwebstack/src/System.Web.Http/NonActionAttribute.cs
+../../../external/aspnetwebstack/src/System.Web.Http/QueryableAttribute.cs
+../../../external/aspnetwebstack/src/System.Web.Http/RouteParameter.cs
diff --git a/mcs/class/System.Web.Mvc3/GlobalSuppressions.cs b/mcs/class/System.Web.Mvc3/GlobalSuppressions.cs
new file mode 100644 (file)
index 0000000..f3998e9
--- /dev/null
@@ -0,0 +1,18 @@
+// This file is used by Code Analysis to maintain SuppressMessage 
+// attributes that are applied to this project. 
+// Project-level suppressions either have no target or are given 
+// a specific target and scoped to a namespace, type, member, etc. 
+//
+// To add a suppression to this file, right-click the message in the 
+// Error List, point to "Suppress Message(s)", and click 
+// "In Project Suppression File". 
+// You do not need to add suppressions to this file manually. 
+
+using System.Diagnostics.CodeAnalysis;
+
+[assembly: SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames", Justification = "Assembly is delay-signed.")]
+[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "System.Web.Mvc.Ajax", Justification = "Helpers reside within a separate namespace to support alternate helper classes.")]
+[assembly: SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "System.Web.Mvc.TempDataDictionary.#System.Collections.Generic.ICollection`1<System.Collections.Generic.KeyValuePair`2<System.String,System.Object>>.Contains(System.Collections.Generic.KeyValuePair`2<System.String,System.Object>)", Justification = "There are no defined scenarios for wanting to derive from this class, but we don't want to prevent it either.")]
+[assembly: SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "System.Web.Mvc.TempDataDictionary.#System.Collections.Generic.ICollection`1<System.Collections.Generic.KeyValuePair`2<System.String,System.Object>>.CopyTo(System.Collections.Generic.KeyValuePair`2<System.String,System.Object>[],System.Int32)", Justification = "There are no defined scenarios for wanting to derive from this class, but we don't want to prevent it either.")]
+[assembly: SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "System.Web.Mvc.TempDataDictionary.#System.Collections.Generic.ICollection`1<System.Collections.Generic.KeyValuePair`2<System.String,System.Object>>.IsReadOnly", Justification = "There are no defined scenarios for wanting to derive from this class, but we don't want to prevent it either.")]
+[assembly: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "Param", Scope = "resource", Target = "System.Web.Mvc.Resources.MvcResources.resources", Justification = "This is the name that matches ASP.NET")]
diff --git a/mcs/class/System.Web.Mvc3/Makefile b/mcs/class/System.Web.Mvc3/Makefile
new file mode 100644 (file)
index 0000000..881547f
--- /dev/null
@@ -0,0 +1,42 @@
+thisdir = class/System.Web.Mvc3
+SUBDIRS = 
+include ../../build/rules.make
+
+LIBRARY = System.Web.Mvc3.dll
+LIBRARY_NAME = System.Web.Mvc.dll
+LIBRARY_USE_INTERMEDIATE_FILE = yes
+
+RESX_DIST =  Mvc/Resources/MvcResources.resx
+
+LIB_MCS_FLAGS = \
+               /warn:1 \
+               /noconfig \
+               /keyfile:../winfx.pub \
+               /d:MONO \
+               /delaysign \
+               /r:Microsoft.Web.Infrastructure.dll \
+               /r:System.dll \
+               /r:System.Core.dll \
+               /r:System.Configuration.dll \
+               /r:System.Data.dll \
+               /r:System.Xml.dll \
+               /r:System.Web.dll \
+               /r:System.Web.Abstractions.dll \
+               /r:System.Web.Routing.dll \
+               /r:System.Web.Extensions.dll \
+               /r:System.ComponentModel.DataAnnotations.dll \
+               /r:System.Data.Linq.dll \
+               /r:System.Runtime.Caching.dll \
+               /r:System.Web.Razor.dll \
+               /r:System.Web.WebPages.Razor.dll \
+               /r:System.Web.WebPages.dll \
+               $(foreach r, $(RESOURCES), /resource:$(r),System.Web.Mvc.Resources.$(notdir $(r)))
+
+EXTRA_DISTFILES = $(RESX_DIST)
+RESOURCES = $(RESX_DIST:.resx=.resources)
+include ../../build/library.make
+
+$(build_lib): $(RESOURCES)
+
+$(RESOURCES): %.resources: %.resx
+       $(RESGEN) `echo $< | $(PLATFORM_CHANGE_SEPARATOR_CMD)`
diff --git a/mcs/class/System.Web.Mvc3/Mvc/AcceptVerbsAttribute.cs b/mcs/class/System.Web.Mvc3/Mvc/AcceptVerbsAttribute.cs
new file mode 100644 (file)
index 0000000..c6516f4
--- /dev/null
@@ -0,0 +1,58 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Collections.ObjectModel;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq;
+    using System.Reflection;
+    using System.Web.Mvc.Resources;
+
+    [SuppressMessage("Microsoft.Design", "CA1019:DefineAccessorsForAttributeArguments", Justification = "The accessor is exposed as an ICollection<string>.")]
+    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
+    public sealed class AcceptVerbsAttribute : ActionMethodSelectorAttribute {
+        public AcceptVerbsAttribute(HttpVerbs verbs)
+            : this(EnumToArray(verbs)) {
+        }
+
+        public AcceptVerbsAttribute(params string[] verbs) {
+            if (verbs == null || verbs.Length == 0) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "verbs");
+            }
+
+            Verbs = new ReadOnlyCollection<string>(verbs);
+        }
+
+        public ICollection<string> Verbs {
+            get;
+            private set;
+        }
+
+        private static void AddEntryToList(HttpVerbs verbs, HttpVerbs match, List<string> verbList, string entryText) {
+            if ((verbs & match) != 0) {
+                verbList.Add(entryText);
+            }
+        }
+
+        internal static string[] EnumToArray(HttpVerbs verbs) {
+            List<string> verbList = new List<string>();
+
+            AddEntryToList(verbs, HttpVerbs.Get, verbList, "GET");
+            AddEntryToList(verbs, HttpVerbs.Post, verbList, "POST");
+            AddEntryToList(verbs, HttpVerbs.Put, verbList, "PUT");
+            AddEntryToList(verbs, HttpVerbs.Delete, verbList, "DELETE");
+            AddEntryToList(verbs, HttpVerbs.Head, verbList, "HEAD");
+
+            return verbList.ToArray();
+        }
+
+        public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+
+            string incomingVerb = controllerContext.HttpContext.Request.GetHttpMethodOverride();
+
+            return Verbs.Contains(incomingVerb, StringComparer.OrdinalIgnoreCase);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ActionDescriptor.cs b/mcs/class/System.Web.Mvc3/Mvc/ActionDescriptor.cs
new file mode 100644 (file)
index 0000000..9c4155a
--- /dev/null
@@ -0,0 +1,175 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.ComponentModel;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Linq;
+    using System.Reflection;
+    using System.Web.Mvc.Resources;
+
+    public abstract class ActionDescriptor : ICustomAttributeProvider, IUniquelyIdentifiable {
+
+        private readonly static ActionMethodDispatcherCache _staticDispatcherCache = new ActionMethodDispatcherCache();
+        private ActionMethodDispatcherCache _instanceDispatcherCache;
+        private readonly Lazy<string> _uniqueId;
+
+        private static readonly ActionSelector[] _emptySelectors = new ActionSelector[0];
+
+        protected ActionDescriptor() {
+            _uniqueId = new Lazy<string>(CreateUniqueId);
+        }
+
+        public abstract string ActionName {
+            get;
+        }
+
+        public abstract ControllerDescriptor ControllerDescriptor {
+            get;
+        }
+
+        internal ActionMethodDispatcherCache DispatcherCache {
+            get {
+                if (_instanceDispatcherCache == null) {
+                    _instanceDispatcherCache = _staticDispatcherCache;
+                }
+                return _instanceDispatcherCache;
+            }
+            set {
+                _instanceDispatcherCache = value;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Security", "CA2119:SealMethodsThatSatisfyPrivateInterfaces", Justification = "This is overridden elsewhere in System.Web.Mvc")]
+        public virtual string UniqueId {
+            get {
+                return _uniqueId.Value;
+            }
+        }
+
+        private string CreateUniqueId() {
+            return DescriptorUtil.CreateUniqueId(GetType(), ControllerDescriptor, ActionName);
+        }
+
+        public abstract object Execute(ControllerContext controllerContext, IDictionary<string, object> parameters);
+
+        internal static object ExtractParameterFromDictionary(ParameterInfo parameterInfo, IDictionary<string, object> parameters, MethodInfo methodInfo) {
+            object value;
+
+            if (!parameters.TryGetValue(parameterInfo.Name, out value)) {
+                // the key should always be present, even if the parameter value is null
+                string message = String.Format(CultureInfo.CurrentCulture, MvcResources.ReflectedActionDescriptor_ParameterNotInDictionary,
+                    parameterInfo.Name, parameterInfo.ParameterType, methodInfo, methodInfo.DeclaringType);
+                throw new ArgumentException(message, "parameters");
+            }
+
+            if (value == null && !TypeHelpers.TypeAllowsNullValue(parameterInfo.ParameterType)) {
+                // tried to pass a null value for a non-nullable parameter type
+                string message = String.Format(CultureInfo.CurrentCulture, MvcResources.ReflectedActionDescriptor_ParameterCannotBeNull,
+                    parameterInfo.Name, parameterInfo.ParameterType, methodInfo, methodInfo.DeclaringType);
+                throw new ArgumentException(message, "parameters");
+            }
+
+            if (value != null && !parameterInfo.ParameterType.IsInstanceOfType(value)) {
+                // value was supplied but is not of the proper type
+                string message = String.Format(CultureInfo.CurrentCulture, MvcResources.ReflectedActionDescriptor_ParameterValueHasWrongType,
+                    parameterInfo.Name, methodInfo, methodInfo.DeclaringType, value.GetType(), parameterInfo.ParameterType);
+                throw new ArgumentException(message, "parameters");
+            }
+
+            return value;
+        }
+
+        internal static object ExtractParameterOrDefaultFromDictionary(ParameterInfo parameterInfo, IDictionary<string, object> parameters) {
+            Type parameterType = parameterInfo.ParameterType;
+
+            object value;
+            parameters.TryGetValue(parameterInfo.Name, out value);
+
+            // if wrong type, replace with default instance
+            if (parameterType.IsInstanceOfType(value)) {
+                return value;
+            }
+            else {
+                object defaultValue;
+                if (ParameterInfoUtil.TryGetDefaultValue(parameterInfo, out defaultValue)) {
+                    return defaultValue;
+                }
+                else {
+                    return TypeHelpers.GetDefaultValue(parameterType);
+                }
+            }
+        }
+
+        public virtual object[] GetCustomAttributes(bool inherit) {
+            return GetCustomAttributes(typeof(object), inherit);
+        }
+
+        public virtual object[] GetCustomAttributes(Type attributeType, bool inherit) {
+            if (attributeType == null) {
+                throw new ArgumentNullException("attributeType");
+            }
+
+            return (object[])Array.CreateInstance(attributeType, 0);
+        }
+
+        internal virtual IEnumerable<FilterAttribute> GetFilterAttributes(bool useCache) {
+            return GetCustomAttributes(typeof(FilterAttribute), inherit: true).Cast<FilterAttribute>();
+        }
+
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        [Obsolete("Please call System.Web.Mvc.FilterProviders.Providers.GetFilters() now.", true)]
+        public virtual FilterInfo GetFilters() {
+            return new FilterInfo();
+        }
+
+        public abstract ParameterDescriptor[] GetParameters();
+
+        [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "This method may perform non-trivial work.")]
+        public virtual ICollection<ActionSelector> GetSelectors() {
+            return _emptySelectors;
+        }
+
+        public virtual bool IsDefined(Type attributeType, bool inherit) {
+            if (attributeType == null) {
+                throw new ArgumentNullException("attributeType");
+            }
+
+            return false;
+        }
+
+        internal static string VerifyActionMethodIsCallable(MethodInfo methodInfo) {
+            // we can't call static methods
+            if (methodInfo.IsStatic) {
+                return String.Format(CultureInfo.CurrentCulture,
+                                     MvcResources.ReflectedActionDescriptor_CannotCallStaticMethod,
+                                     methodInfo,
+                                     methodInfo.ReflectedType.FullName);
+            }
+
+            // we can't call instance methods where the 'this' parameter is a type other than ControllerBase
+            if (!typeof(ControllerBase).IsAssignableFrom(methodInfo.ReflectedType)) {
+                return String.Format(CultureInfo.CurrentCulture, MvcResources.ReflectedActionDescriptor_CannotCallInstanceMethodOnNonControllerType,
+                    methodInfo, methodInfo.ReflectedType.FullName);
+            }
+
+            // we can't call methods with open generic type parameters
+            if (methodInfo.ContainsGenericParameters) {
+                return String.Format(CultureInfo.CurrentCulture, MvcResources.ReflectedActionDescriptor_CannotCallOpenGenericMethods,
+                    methodInfo, methodInfo.ReflectedType.FullName);
+            }
+
+            // we can't call methods with ref/out parameters
+            ParameterInfo[] parameterInfos = methodInfo.GetParameters();
+            foreach (ParameterInfo parameterInfo in parameterInfos) {
+                if (parameterInfo.IsOut || parameterInfo.ParameterType.IsByRef) {
+                    return String.Format(CultureInfo.CurrentCulture, MvcResources.ReflectedActionDescriptor_CannotCallMethodsWithOutOrRefParameters,
+                        methodInfo, methodInfo.ReflectedType.FullName, parameterInfo);
+                }
+            }
+
+            // we can call this method
+            return null;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ActionExecutedContext.cs b/mcs/class/System.Web.Mvc3/Mvc/ActionExecutedContext.cs
new file mode 100644 (file)
index 0000000..e8c7d20
--- /dev/null
@@ -0,0 +1,55 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+
+    public class ActionExecutedContext : ControllerContext {
+
+        private ActionResult _result;
+
+        // parameterless constructor used for mocking
+        public ActionExecutedContext() {
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", Justification = "The virtual property setters are only to support mocking frameworks, in which case this constructor shouldn't be called anyway.")]
+        public ActionExecutedContext(ControllerContext controllerContext, ActionDescriptor actionDescriptor, bool canceled, Exception exception)
+            : base(controllerContext) {
+            if (actionDescriptor == null) {
+                throw new ArgumentNullException("actionDescriptor");
+            }
+
+            ActionDescriptor = actionDescriptor;
+            Canceled = canceled;
+            Exception = exception;
+        }
+
+        public virtual ActionDescriptor ActionDescriptor {
+            get;
+            set;
+        }
+
+        public virtual bool Canceled {
+            get;
+            set;
+        }
+
+        public virtual Exception Exception {
+            get;
+            set;
+        }
+
+        public bool ExceptionHandled {
+            get;
+            set;
+        }
+
+        public ActionResult Result {
+            get {
+                return _result ?? EmptyResult.Instance;
+            }
+            set {
+                _result = value;
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ActionExecutingContext.cs b/mcs/class/System.Web.Mvc3/Mvc/ActionExecutingContext.cs
new file mode 100644 (file)
index 0000000..7b507b6
--- /dev/null
@@ -0,0 +1,43 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+
+    public class ActionExecutingContext : ControllerContext {
+
+        // parameterless constructor used for mocking
+        public ActionExecutingContext() {
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", Justification = "The virtual property setters are only to support mocking frameworks, in which case this constructor shouldn't be called anyway.")]
+        public ActionExecutingContext(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary<string, object> actionParameters)
+            : base(controllerContext) {
+            if (actionDescriptor == null) {
+                throw new ArgumentNullException("actionDescriptor");
+            }
+            if (actionParameters == null) {
+                throw new ArgumentNullException("actionParameters");
+            }
+
+            ActionDescriptor = actionDescriptor;
+            ActionParameters = actionParameters;
+        }
+
+        public virtual ActionDescriptor ActionDescriptor {
+            get;
+            set;
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "The property setter is only here to support mocking this type and should not be called at runtime.")]
+        public virtual IDictionary<string, object> ActionParameters {
+            get;
+            set;
+        }
+
+        public ActionResult Result {
+            get;
+            set;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ActionFilterAttribute.cs b/mcs/class/System.Web.Mvc3/Mvc/ActionFilterAttribute.cs
new file mode 100644 (file)
index 0000000..4b708f9
--- /dev/null
@@ -0,0 +1,22 @@
+namespace System.Web.Mvc {
+    using System;
+
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
+    public abstract class ActionFilterAttribute : FilterAttribute, IActionFilter, IResultFilter {
+
+        // The OnXxx() methods are virtual rather than abstract so that a developer need override
+        // only the ones that interest him.
+
+        public virtual void OnActionExecuting(ActionExecutingContext filterContext) {
+        }
+
+        public virtual void OnActionExecuted(ActionExecutedContext filterContext) {
+        }
+
+        public virtual void OnResultExecuting(ResultExecutingContext filterContext) {
+        }
+
+        public virtual void OnResultExecuted(ResultExecutedContext filterContext) {
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ActionMethodDispatcher.cs b/mcs/class/System.Web.Mvc3/Mvc/ActionMethodDispatcher.cs
new file mode 100644 (file)
index 0000000..b54bb8a
--- /dev/null
@@ -0,0 +1,74 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Linq.Expressions;
+    using System.Reflection;
+
+    // The methods in this class don't perform error checking; that is the responsibility of the
+    // caller.
+    internal sealed class ActionMethodDispatcher {
+
+        private delegate object ActionExecutor(ControllerBase controller, object[] parameters);
+        private delegate void VoidActionExecutor(ControllerBase controller, object[] parameters);
+
+        private ActionExecutor _executor;
+
+        public ActionMethodDispatcher(MethodInfo methodInfo) {
+            _executor = GetExecutor(methodInfo);
+            MethodInfo = methodInfo;
+        }
+
+        public MethodInfo MethodInfo {
+            get;
+            private set;
+        }
+
+        public object Execute(ControllerBase controller, object[] parameters) {
+            return _executor(controller, parameters);
+        }
+
+        private static ActionExecutor GetExecutor(MethodInfo methodInfo) {
+            // Parameters to executor
+            ParameterExpression controllerParameter = Expression.Parameter(typeof(ControllerBase), "controller");
+            ParameterExpression parametersParameter = Expression.Parameter(typeof(object[]), "parameters");
+
+            // Build parameter list
+            List<Expression> parameters = new List<Expression>();
+            ParameterInfo[] paramInfos = methodInfo.GetParameters();
+            for (int i = 0; i < paramInfos.Length; i++) {
+                ParameterInfo paramInfo = paramInfos[i];
+                BinaryExpression valueObj = Expression.ArrayIndex(parametersParameter, Expression.Constant(i));
+                UnaryExpression valueCast = Expression.Convert(valueObj, paramInfo.ParameterType);
+
+                // valueCast is "(Ti) parameters[i]"
+                parameters.Add(valueCast);
+            }
+
+            // Call method
+            UnaryExpression instanceCast = (!methodInfo.IsStatic) ? Expression.Convert(controllerParameter, methodInfo.ReflectedType) : null;
+            MethodCallExpression methodCall = methodCall = Expression.Call(instanceCast, methodInfo, parameters);
+
+            // methodCall is "((TController) controller) method((T0) parameters[0], (T1) parameters[1], ...)"
+            // Create function
+            if (methodCall.Type == typeof(void)) {
+                Expression<VoidActionExecutor> lambda = Expression.Lambda<VoidActionExecutor>(methodCall, controllerParameter, parametersParameter);
+                VoidActionExecutor voidExecutor = lambda.Compile();
+                return WrapVoidAction(voidExecutor);
+            }
+            else {
+                // must coerce methodCall to match ActionExecutor signature
+                UnaryExpression castMethodCall = Expression.Convert(methodCall, typeof(object));
+                Expression<ActionExecutor> lambda = Expression.Lambda<ActionExecutor>(castMethodCall, controllerParameter, parametersParameter);
+                return lambda.Compile();
+            }
+        }
+
+        private static ActionExecutor WrapVoidAction(VoidActionExecutor executor) {
+            return delegate(ControllerBase controller, object[] parameters) {
+                executor(controller, parameters);
+                return null;
+            };
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ActionMethodDispatcherCache.cs b/mcs/class/System.Web.Mvc3/Mvc/ActionMethodDispatcherCache.cs
new file mode 100644 (file)
index 0000000..1846484
--- /dev/null
@@ -0,0 +1,15 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Reflection;
+
+    internal sealed class ActionMethodDispatcherCache : ReaderWriterCache<MethodInfo,ActionMethodDispatcher> {
+
+        public ActionMethodDispatcherCache() {
+        }
+
+        public ActionMethodDispatcher GetDispatcher(MethodInfo methodInfo) {
+            return FetchOrCreateItem(methodInfo, () => new ActionMethodDispatcher(methodInfo));
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ActionMethodSelector.cs b/mcs/class/System.Web.Mvc3/Mvc/ActionMethodSelector.cs
new file mode 100644 (file)
index 0000000..498327f
--- /dev/null
@@ -0,0 +1,113 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Globalization;
+    using System.Linq;
+    using System.Reflection;
+    using System.Text;
+    using System.Web.Mvc.Resources;
+
+    internal sealed class ActionMethodSelector {
+
+        public ActionMethodSelector(Type controllerType) {
+            ControllerType = controllerType;
+            PopulateLookupTables();
+        }
+
+        public Type ControllerType {
+            get;
+            private set;
+        }
+
+        public MethodInfo[] AliasedMethods {
+            get;
+            private set;
+        }
+
+        public ILookup<string, MethodInfo> NonAliasedMethods {
+            get;
+            private set;
+        }
+
+        private AmbiguousMatchException CreateAmbiguousMatchException(List<MethodInfo> ambiguousMethods, string actionName) {
+            StringBuilder exceptionMessageBuilder = new StringBuilder();
+            foreach (MethodInfo methodInfo in ambiguousMethods) {
+                string controllerAction = Convert.ToString(methodInfo, CultureInfo.CurrentCulture);
+                string controllerType = methodInfo.DeclaringType.FullName;
+                exceptionMessageBuilder.AppendLine();
+                exceptionMessageBuilder.AppendFormat(CultureInfo.CurrentCulture, MvcResources.ActionMethodSelector_AmbiguousMatchType, controllerAction, controllerType);
+            }
+            string message = String.Format(CultureInfo.CurrentCulture, MvcResources.ActionMethodSelector_AmbiguousMatch,
+                actionName, ControllerType.Name, exceptionMessageBuilder);
+            return new AmbiguousMatchException(message);
+        }
+
+        public MethodInfo FindActionMethod(ControllerContext controllerContext, string actionName) {
+            List<MethodInfo> methodsMatchingName = GetMatchingAliasedMethods(controllerContext, actionName);
+            methodsMatchingName.AddRange(NonAliasedMethods[actionName]);
+            List<MethodInfo> finalMethods = RunSelectionFilters(controllerContext, methodsMatchingName);
+
+            switch (finalMethods.Count) {
+                case 0:
+                    return null;
+
+                case 1:
+                    return finalMethods[0];
+
+                default:
+                    throw CreateAmbiguousMatchException(finalMethods, actionName);
+            }
+        }
+
+        internal List<MethodInfo> GetMatchingAliasedMethods(ControllerContext controllerContext, string actionName) {
+            // find all aliased methods which are opting in to this request
+            // to opt in, all attributes defined on the method must return true
+
+            var methods = from methodInfo in AliasedMethods
+                          let attrs = ReflectedAttributeCache.GetActionNameSelectorAttributes(methodInfo)
+                          where attrs.All(attr => attr.IsValidName(controllerContext, actionName, methodInfo))
+                          select methodInfo;
+            return methods.ToList();
+        }
+
+        private static bool IsMethodDecoratedWithAliasingAttribute(MethodInfo methodInfo) {
+            return methodInfo.IsDefined(typeof(ActionNameSelectorAttribute), true /* inherit */);
+        }
+
+        private static bool IsValidActionMethod(MethodInfo methodInfo) {
+            return !(methodInfo.IsSpecialName ||
+                     methodInfo.GetBaseDefinition().DeclaringType.IsAssignableFrom(typeof(Controller)));
+        }
+
+        private void PopulateLookupTables() {
+            MethodInfo[] allMethods = ControllerType.GetMethods(BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public);
+            MethodInfo[] actionMethods = Array.FindAll(allMethods, IsValidActionMethod);
+
+            AliasedMethods = Array.FindAll(actionMethods, IsMethodDecoratedWithAliasingAttribute);
+            NonAliasedMethods = actionMethods.Except(AliasedMethods).ToLookup(method => method.Name, StringComparer.OrdinalIgnoreCase);
+        }
+
+        private static List<MethodInfo> RunSelectionFilters(ControllerContext controllerContext, List<MethodInfo> methodInfos) {
+            // remove all methods which are opting out of this request
+            // to opt out, at least one attribute defined on the method must return false
+
+            List<MethodInfo> matchesWithSelectionAttributes = new List<MethodInfo>();
+            List<MethodInfo> matchesWithoutSelectionAttributes = new List<MethodInfo>();
+
+            foreach (MethodInfo methodInfo in methodInfos) {
+                ICollection<ActionMethodSelectorAttribute> attrs = ReflectedAttributeCache.GetActionMethodSelectorAttributes(methodInfo);
+                if (attrs.Count == 0) {
+                    matchesWithoutSelectionAttributes.Add(methodInfo);
+                }
+                else if (attrs.All(attr => attr.IsValidForRequest(controllerContext, methodInfo))) {
+                    matchesWithSelectionAttributes.Add(methodInfo);
+                }
+            }
+
+            // if a matching action method had a selection attribute, consider it more specific than a matching action method
+            // without a selection attribute
+            return (matchesWithSelectionAttributes.Count > 0) ? matchesWithSelectionAttributes : matchesWithoutSelectionAttributes;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ActionMethodSelectorAttribute.cs b/mcs/class/System.Web.Mvc3/Mvc/ActionMethodSelectorAttribute.cs
new file mode 100644 (file)
index 0000000..2f171f2
--- /dev/null
@@ -0,0 +1,9 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Reflection;
+
+    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
+    public abstract class ActionMethodSelectorAttribute : Attribute {
+        public abstract bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ActionNameAttribute.cs b/mcs/class/System.Web.Mvc3/Mvc/ActionNameAttribute.cs
new file mode 100644 (file)
index 0000000..06b982d
--- /dev/null
@@ -0,0 +1,27 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Reflection;
+    using System.Web.Mvc.Resources;
+
+    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
+    public sealed class ActionNameAttribute : ActionNameSelectorAttribute {
+
+        public ActionNameAttribute(string name) {
+            if (String.IsNullOrEmpty(name)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "name");
+            }
+
+            Name = name;
+        }
+
+        public string Name {
+            get;
+            private set;
+        }
+
+        public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo) {
+            return String.Equals(actionName, Name, StringComparison.OrdinalIgnoreCase);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ActionNameSelectorAttribute.cs b/mcs/class/System.Web.Mvc3/Mvc/ActionNameSelectorAttribute.cs
new file mode 100644 (file)
index 0000000..949134e
--- /dev/null
@@ -0,0 +1,9 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Reflection;
+
+    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
+    public abstract class ActionNameSelectorAttribute : Attribute {
+        public abstract bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ActionResult.cs b/mcs/class/System.Web.Mvc3/Mvc/ActionResult.cs
new file mode 100644 (file)
index 0000000..e648246
--- /dev/null
@@ -0,0 +1,9 @@
+namespace System.Web.Mvc {
+
+    public abstract class ActionResult {
+
+        public abstract void ExecuteResult(ControllerContext context);
+
+    }
+
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ActionSelector.cs b/mcs/class/System.Web.Mvc3/Mvc/ActionSelector.cs
new file mode 100644 (file)
index 0000000..1708097
--- /dev/null
@@ -0,0 +1,5 @@
+namespace System.Web.Mvc {
+
+    public delegate bool ActionSelector(ControllerContext controllerContext);
+
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/AdditionalMetaDataAttribute.cs b/mcs/class/System.Web.Mvc3/Mvc/AdditionalMetaDataAttribute.cs
new file mode 100644 (file)
index 0000000..9b25a76
--- /dev/null
@@ -0,0 +1,41 @@
+namespace System.Web.Mvc {
+    using System;
+
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Property, AllowMultiple = true)]
+    public sealed class AdditionalMetadataAttribute : Attribute, IMetadataAware {
+        private object _typeId = new object();
+
+        public AdditionalMetadataAttribute(string name, object value) {
+            if (name == null) {
+                throw new ArgumentNullException("name");
+            }
+
+            Name = name;
+            Value = value;
+        }
+
+        public override object TypeId {
+            get {
+                return _typeId;
+            }
+        }
+
+        public string Name {
+            get;
+            private set;
+        }
+
+        public object Value {
+            get;
+            private set;
+        }
+
+        public void OnMetadataCreated(ModelMetadata metadata) {
+            if (metadata == null) {
+                throw new ArgumentNullException("metadata");
+            }
+
+            metadata.AdditionalValues[Name] = Value;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Ajax/AjaxExtensions.cs b/mcs/class/System.Web.Mvc3/Mvc/Ajax/AjaxExtensions.cs
new file mode 100644 (file)
index 0000000..f11e751
--- /dev/null
@@ -0,0 +1,300 @@
+namespace System.Web.Mvc.Ajax {
+    using System;
+    using System.Collections.Generic;
+    using System.ComponentModel;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Web;
+    using System.Web.Mvc;
+    using System.Web.Mvc.Html;
+    using System.Web.Mvc.Resources;
+    using System.Web.Routing;
+
+    public static class AjaxExtensions {
+        private const string LinkOnClickFormat = "Sys.Mvc.AsyncHyperlink.handleClick(this, new Sys.UI.DomEvent(event), {0});";
+        private const string FormOnClickValue = "Sys.Mvc.AsyncForm.handleClick(this, new Sys.UI.DomEvent(event));";
+        private const string FormOnSubmitFormat = "Sys.Mvc.AsyncForm.handleSubmit(this, new Sys.UI.DomEvent(event), {0});";
+        private const string _globalizationScript = @"<script type=""text/javascript"" src=""{0}""></script>";
+
+        public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, AjaxOptions ajaxOptions) {
+            return ActionLink(ajaxHelper, linkText, actionName, (string)null /* controllerName */, ajaxOptions);
+        }
+
+        public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, object routeValues, AjaxOptions ajaxOptions) {
+            return ActionLink(ajaxHelper, linkText, actionName, (string)null /* controllerName */, routeValues, ajaxOptions);
+        }
+
+        public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) {
+            return ActionLink(ajaxHelper, linkText, actionName, (string)null /* controllerName */, routeValues, ajaxOptions, htmlAttributes);
+        }
+
+        public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions) {
+            return ActionLink(ajaxHelper, linkText, actionName, (string)null /* controllerName */, routeValues, ajaxOptions);
+        }
+
+        public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
+            return ActionLink(ajaxHelper, linkText, actionName, (string)null /* controllerName */, routeValues, ajaxOptions, htmlAttributes);
+        }
+
+        public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, AjaxOptions ajaxOptions) {
+            return ActionLink(ajaxHelper, linkText, actionName, controllerName, null /* values */, ajaxOptions, null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, object routeValues, AjaxOptions ajaxOptions) {
+            return ActionLink(ajaxHelper, linkText, actionName, controllerName, routeValues, ajaxOptions, null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) {
+            RouteValueDictionary newValues = new RouteValueDictionary(routeValues);
+            RouteValueDictionary newAttributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
+            return ActionLink(ajaxHelper, linkText, actionName, controllerName, newValues, ajaxOptions, newAttributes);
+        }
+
+        public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions) {
+            return ActionLink(ajaxHelper, linkText, actionName, controllerName, routeValues, ajaxOptions, null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
+            if (String.IsNullOrEmpty(linkText)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText");
+            }
+
+            string targetUrl = UrlHelper.GenerateUrl(null, actionName, controllerName, routeValues, ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, true /* includeImplicitMvcValues */);
+
+            return MvcHtmlString.Create(GenerateLink(ajaxHelper, linkText, targetUrl, GetAjaxOptions(ajaxOptions), htmlAttributes));
+        }
+
+        public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, string protocol, string hostName, string fragment, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) {
+            RouteValueDictionary newValues = new RouteValueDictionary(routeValues);
+            RouteValueDictionary newAttributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
+            return ActionLink(ajaxHelper, linkText, actionName, controllerName, protocol, hostName, fragment, newValues, ajaxOptions, newAttributes);
+        }
+
+        public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, string protocol, string hostName, string fragment, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
+            if (String.IsNullOrEmpty(linkText)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText");
+            }
+
+            string targetUrl = UrlHelper.GenerateUrl(null /* routeName */, actionName, controllerName, protocol, hostName, fragment, routeValues, ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, true /* includeImplicitMvcValues */);
+
+            return MvcHtmlString.Create(GenerateLink(ajaxHelper, linkText, targetUrl, ajaxOptions, htmlAttributes));
+        }
+
+        public static MvcForm BeginForm(this AjaxHelper ajaxHelper, AjaxOptions ajaxOptions) {
+            string formAction = ajaxHelper.ViewContext.HttpContext.Request.RawUrl;
+            return FormHelper(ajaxHelper, formAction, ajaxOptions, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, AjaxOptions ajaxOptions) {
+            return BeginForm(ajaxHelper, actionName, (string)null /* controllerName */, ajaxOptions);
+        }
+
+        public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, object routeValues, AjaxOptions ajaxOptions) {
+            return BeginForm(ajaxHelper, actionName, (string)null /* controllerName */, routeValues, ajaxOptions);
+        }
+
+        public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) {
+            return BeginForm(ajaxHelper, actionName, (string)null /* controllerName */, routeValues, ajaxOptions, htmlAttributes);
+        }
+
+        public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions) {
+            return BeginForm(ajaxHelper, actionName, (string)null /* controllerName */, routeValues, ajaxOptions);
+        }
+
+        public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
+            return BeginForm(ajaxHelper, actionName, (string)null /* controllerName */, routeValues, ajaxOptions, htmlAttributes);
+        }
+
+        public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, string controllerName, AjaxOptions ajaxOptions) {
+            return BeginForm(ajaxHelper, actionName, controllerName, null /* values */, ajaxOptions, null /* htmlAttributes */);
+        }
+
+        public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, string controllerName, object routeValues, AjaxOptions ajaxOptions) {
+            return BeginForm(ajaxHelper, actionName, controllerName, routeValues, ajaxOptions, null /* htmlAttributes */);
+        }
+
+        public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, string controllerName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) {
+            RouteValueDictionary newValues = new RouteValueDictionary(routeValues);
+            RouteValueDictionary newAttributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
+            return BeginForm(ajaxHelper, actionName, controllerName, newValues, ajaxOptions, newAttributes);
+        }
+
+        public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, string controllerName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions) {
+            return BeginForm(ajaxHelper, actionName, controllerName, routeValues, ajaxOptions, null /* htmlAttributes */);
+        }
+
+        public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, string controllerName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
+            // get target URL
+            string formAction = UrlHelper.GenerateUrl(null, actionName, controllerName, routeValues ?? new RouteValueDictionary(), ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, true /* includeImplicitMvcValues */);
+            return FormHelper(ajaxHelper, formAction, ajaxOptions, htmlAttributes);
+        }
+
+        public static MvcForm BeginRouteForm(this AjaxHelper ajaxHelper, string routeName, AjaxOptions ajaxOptions) {
+            return BeginRouteForm(ajaxHelper, routeName, null /* routeValues */, ajaxOptions, null /* htmlAttributes */);
+        }
+
+        public static MvcForm BeginRouteForm(this AjaxHelper ajaxHelper, string routeName, object routeValues, AjaxOptions ajaxOptions) {
+            return BeginRouteForm(ajaxHelper, routeName, (object)routeValues, ajaxOptions, null /* htmlAttributes */);
+        }
+
+        public static MvcForm BeginRouteForm(this AjaxHelper ajaxHelper, string routeName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) {
+            RouteValueDictionary newAttributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
+            return BeginRouteForm(ajaxHelper, routeName, new RouteValueDictionary(routeValues), ajaxOptions, newAttributes);
+        }
+
+        public static MvcForm BeginRouteForm(this AjaxHelper ajaxHelper, string routeName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions) {
+            return BeginRouteForm(ajaxHelper, routeName, routeValues, ajaxOptions, null /* htmlAttributes */);
+        }
+
+        public static MvcForm BeginRouteForm(this AjaxHelper ajaxHelper, string routeName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
+            string formAction = UrlHelper.GenerateUrl(routeName, null /* actionName */, null /* controllerName */, routeValues ?? new RouteValueDictionary(), ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, false /* includeImplicitMvcValues */);
+            return FormHelper(ajaxHelper, formAction, ajaxOptions, htmlAttributes);
+        }
+
+        [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "You don't want to dispose of this object unless you intend to write to the response")]
+        private static MvcForm FormHelper(this AjaxHelper ajaxHelper, string formAction, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
+            TagBuilder builder = new TagBuilder("form");
+            builder.MergeAttributes(htmlAttributes);
+            builder.MergeAttribute("action", formAction);
+            builder.MergeAttribute("method", "post");
+
+            ajaxOptions = GetAjaxOptions(ajaxOptions);
+
+            if (ajaxHelper.ViewContext.UnobtrusiveJavaScriptEnabled) {
+                builder.MergeAttributes(ajaxOptions.ToUnobtrusiveHtmlAttributes());
+            }
+            else {
+                builder.MergeAttribute("onclick", FormOnClickValue);
+                builder.MergeAttribute("onsubmit", GenerateAjaxScript(ajaxOptions, FormOnSubmitFormat));
+            }
+
+            if (ajaxHelper.ViewContext.ClientValidationEnabled) {
+                // forms must have an ID for client validation
+                builder.GenerateId(ajaxHelper.ViewContext.FormIdGenerator());
+            }
+
+            ajaxHelper.ViewContext.Writer.Write(builder.ToString(TagRenderMode.StartTag));
+            MvcForm theForm = new MvcForm(ajaxHelper.ViewContext);
+
+            if (ajaxHelper.ViewContext.ClientValidationEnabled) {
+                ajaxHelper.ViewContext.FormContext.FormId = builder.Attributes["id"];
+            }
+
+            return theForm;
+        }
+
+        public static MvcHtmlString GlobalizationScript(this AjaxHelper ajaxHelper) {
+            return GlobalizationScript(ajaxHelper, CultureInfo.CurrentCulture);
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "ajaxHelper", Justification = "This is an extension method")]
+        public static MvcHtmlString GlobalizationScript(this AjaxHelper ajaxHelper, CultureInfo cultureInfo) {
+            return GlobalizationScriptHelper(AjaxHelper.GlobalizationScriptPath, cultureInfo);
+        }
+
+        private static MvcHtmlString GlobalizationScriptHelper(string scriptPath, CultureInfo cultureInfo) {
+            if (cultureInfo == null) {
+                throw new ArgumentNullException("cultureInfo");
+            }
+
+            string src = VirtualPathUtility.AppendTrailingSlash(scriptPath) + cultureInfo.Name + ".js";
+            string scriptWithCorrectNewLines = _globalizationScript.Replace("\r\n", Environment.NewLine);
+            string formatted = String.Format(CultureInfo.InvariantCulture, scriptWithCorrectNewLines, src);
+
+            return MvcHtmlString.Create(formatted);
+        }
+
+        public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, object routeValues, AjaxOptions ajaxOptions) {
+            return RouteLink(ajaxHelper, linkText, null /* routeName */, new RouteValueDictionary(routeValues), ajaxOptions,
+                             new Dictionary<string, object>());
+        }
+
+        public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) {
+            return RouteLink(ajaxHelper, linkText, null /* routeName */, new RouteValueDictionary(routeValues), ajaxOptions,
+                             HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, RouteValueDictionary routeValues, AjaxOptions ajaxOptions) {
+            return RouteLink(ajaxHelper, linkText, null /* routeName */, routeValues, ajaxOptions,
+                             new Dictionary<string, object>());
+        }
+
+        public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
+            return RouteLink(ajaxHelper, linkText, null /* routeName */, routeValues, ajaxOptions, htmlAttributes);
+        }
+
+        public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, AjaxOptions ajaxOptions) {
+            return RouteLink(ajaxHelper, linkText, routeName, new RouteValueDictionary(), ajaxOptions,
+                             new Dictionary<string, object>());
+        }
+
+        public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, AjaxOptions ajaxOptions, object htmlAttributes) {
+            return RouteLink(ajaxHelper, linkText, routeName, new RouteValueDictionary(), ajaxOptions, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
+            return RouteLink(ajaxHelper, linkText, routeName, new RouteValueDictionary(), ajaxOptions, htmlAttributes);
+        }
+
+        public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, object routeValues, AjaxOptions ajaxOptions) {
+            return RouteLink(ajaxHelper, linkText, routeName, new RouteValueDictionary(routeValues), ajaxOptions,
+                             new Dictionary<string, object>());
+        }
+
+        public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) {
+            return RouteLink(ajaxHelper, linkText, routeName, new RouteValueDictionary(routeValues), ajaxOptions,
+                             HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions) {
+            return RouteLink(ajaxHelper, linkText, routeName, routeValues, ajaxOptions, new Dictionary<string, object>());
+        }
+
+        public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
+            if (String.IsNullOrEmpty(linkText)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText");
+            }
+
+            string targetUrl = UrlHelper.GenerateUrl(routeName, null /* actionName */, null /* controllerName */, routeValues ?? new RouteValueDictionary(), ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, false /* includeImplicitMvcValues */);
+
+            return MvcHtmlString.Create(GenerateLink(ajaxHelper, linkText, targetUrl, GetAjaxOptions(ajaxOptions), htmlAttributes));
+        }
+
+        public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, string protocol, string hostName, string fragment, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
+            if (String.IsNullOrEmpty(linkText)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText");
+            }
+
+            string targetUrl = UrlHelper.GenerateUrl(routeName, null /* actionName */, null /* controllerName */, protocol, hostName, fragment, routeValues ?? new RouteValueDictionary(), ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, false /* includeImplicitMvcValues */);
+
+            return MvcHtmlString.Create(GenerateLink(ajaxHelper, linkText, targetUrl, GetAjaxOptions(ajaxOptions), htmlAttributes));
+        }
+
+        private static string GenerateLink(AjaxHelper ajaxHelper, string linkText, string targetUrl, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
+            TagBuilder tag = new TagBuilder("a") {
+                InnerHtml = HttpUtility.HtmlEncode(linkText)
+            };
+
+            tag.MergeAttributes(htmlAttributes);
+            tag.MergeAttribute("href", targetUrl);
+
+            if (ajaxHelper.ViewContext.UnobtrusiveJavaScriptEnabled) {
+                tag.MergeAttributes(ajaxOptions.ToUnobtrusiveHtmlAttributes());
+            }
+            else {
+                tag.MergeAttribute("onclick", GenerateAjaxScript(ajaxOptions, LinkOnClickFormat));
+            }
+
+            return tag.ToString(TagRenderMode.Normal);
+        }
+
+        private static string GenerateAjaxScript(AjaxOptions ajaxOptions, string scriptFormat) {
+            string optionsString = ajaxOptions.ToJavascriptString();
+            return String.Format(CultureInfo.InvariantCulture, scriptFormat, optionsString);
+        }
+
+        private static AjaxOptions GetAjaxOptions(AjaxOptions ajaxOptions) {
+            return (ajaxOptions != null) ? ajaxOptions : new AjaxOptions();
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Ajax/AjaxOptions.cs b/mcs/class/System.Web.Mvc3/Mvc/Ajax/AjaxOptions.cs
new file mode 100644 (file)
index 0000000..69a817e
--- /dev/null
@@ -0,0 +1,226 @@
+namespace System.Web.Mvc.Ajax {
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Text;
+
+    public class AjaxOptions {
+        private string _confirm;
+        private string _httpMethod;
+        private InsertionMode _insertionMode = InsertionMode.Replace;
+        private string _loadingElementId;
+        private string _onBegin;
+        private string _onComplete;
+        private string _onFailure;
+        private string _onSuccess;
+        private string _updateTargetId;
+        private string _url;
+
+        public string Confirm {
+            get {
+                return _confirm ?? String.Empty;
+            }
+            set {
+                _confirm = value;
+            }
+        }
+
+        public string HttpMethod {
+            get {
+                return _httpMethod ?? String.Empty;
+            }
+            set {
+                _httpMethod = value;
+            }
+        }
+
+        public InsertionMode InsertionMode {
+            get {
+                return _insertionMode;
+            }
+            set {
+                switch (value) {
+                    case InsertionMode.Replace:
+                    case InsertionMode.InsertAfter:
+                    case InsertionMode.InsertBefore:
+                        _insertionMode = value;
+                        return;
+
+                    default:
+                        throw new ArgumentOutOfRangeException("value");
+                }
+            }
+        }
+
+        internal string InsertionModeString {
+            get {
+                switch (InsertionMode) {
+                    case InsertionMode.Replace:
+                        return "Sys.Mvc.InsertionMode.replace";
+                    case InsertionMode.InsertBefore:
+                        return "Sys.Mvc.InsertionMode.insertBefore";
+                    case InsertionMode.InsertAfter:
+                        return "Sys.Mvc.InsertionMode.insertAfter";
+                    default:
+                        return ((int)InsertionMode).ToString(CultureInfo.InvariantCulture);
+                }
+            }
+        }
+
+        internal string InsertionModeUnobtrusive {
+            get {
+                switch (InsertionMode) {
+                    case InsertionMode.Replace:
+                        return "replace";
+                    case InsertionMode.InsertBefore:
+                        return "before";
+                    case InsertionMode.InsertAfter:
+                        return "after";
+                    default:
+                        return ((int)InsertionMode).ToString(CultureInfo.InvariantCulture);
+                }
+            }
+        }
+
+        public int LoadingElementDuration {
+            get;
+            set;
+        }
+
+        public string LoadingElementId {
+            get {
+                return _loadingElementId ?? String.Empty;
+            }
+            set {
+                _loadingElementId = value;
+            }
+        }
+
+        public string OnBegin {
+            get {
+                return _onBegin ?? String.Empty;
+            }
+            set {
+                _onBegin = value;
+            }
+        }
+
+        public string OnComplete {
+            get {
+                return _onComplete ?? String.Empty;
+            }
+            set {
+                _onComplete = value;
+            }
+        }
+
+        public string OnFailure {
+            get {
+                return _onFailure ?? String.Empty;
+            }
+            set {
+                _onFailure = value;
+            }
+        }
+
+        public string OnSuccess {
+            get {
+                return _onSuccess ?? String.Empty;
+            }
+            set {
+                _onSuccess = value;
+            }
+        }
+
+        public string UpdateTargetId {
+            get {
+                return _updateTargetId ?? String.Empty;
+            }
+            set {
+                _updateTargetId = value;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "This property is used by the optionsBuilder which always accepts a string.")]
+        public string Url {
+            get {
+                return _url ?? String.Empty;
+            }
+            set {
+                _url = value;
+            }
+        }
+
+        internal string ToJavascriptString() {
+            // creates a string of the form { key1: value1, key2 : value2, ... }
+            StringBuilder optionsBuilder = new StringBuilder("{");
+            optionsBuilder.Append(String.Format(CultureInfo.InvariantCulture, " insertionMode: {0},", InsertionModeString));
+            optionsBuilder.Append(PropertyStringIfSpecified("confirm", Confirm));
+            optionsBuilder.Append(PropertyStringIfSpecified("httpMethod", HttpMethod));
+            optionsBuilder.Append(PropertyStringIfSpecified("loadingElementId", LoadingElementId));
+            optionsBuilder.Append(PropertyStringIfSpecified("updateTargetId", UpdateTargetId));
+            optionsBuilder.Append(PropertyStringIfSpecified("url", Url));
+            optionsBuilder.Append(EventStringIfSpecified("onBegin", OnBegin));
+            optionsBuilder.Append(EventStringIfSpecified("onComplete", OnComplete));
+            optionsBuilder.Append(EventStringIfSpecified("onFailure", OnFailure));
+            optionsBuilder.Append(EventStringIfSpecified("onSuccess", OnSuccess));
+            optionsBuilder.Length--;
+            optionsBuilder.Append(" }");
+            return optionsBuilder.ToString();
+        }
+
+        public IDictionary<string, object> ToUnobtrusiveHtmlAttributes() {
+            var result = new Dictionary<string, object> {
+                { "data-ajax", "true" },
+            };
+
+            AddToDictionaryIfSpecified(result, "data-ajax-url", Url);
+            AddToDictionaryIfSpecified(result, "data-ajax-method", HttpMethod);
+            AddToDictionaryIfSpecified(result, "data-ajax-confirm", Confirm);
+
+            AddToDictionaryIfSpecified(result, "data-ajax-begin", OnBegin);
+            AddToDictionaryIfSpecified(result, "data-ajax-complete", OnComplete);
+            AddToDictionaryIfSpecified(result, "data-ajax-failure", OnFailure);
+            AddToDictionaryIfSpecified(result, "data-ajax-success", OnSuccess);
+
+            if (!String.IsNullOrWhiteSpace(LoadingElementId)) {
+                result.Add("data-ajax-loading", "#" + LoadingElementId);
+
+                if (LoadingElementDuration > 0) {
+                    result.Add("data-ajax-loading-duration", LoadingElementDuration);
+                }
+            }
+
+            if (!String.IsNullOrWhiteSpace(UpdateTargetId)) {
+                result.Add("data-ajax-update", "#" + UpdateTargetId);
+                result.Add("data-ajax-mode", InsertionModeUnobtrusive);
+            }
+
+            return result;
+        }
+
+        // Helpers
+
+        private static void AddToDictionaryIfSpecified(IDictionary<string, object> dictionary, string name, string value) {
+            if (!String.IsNullOrWhiteSpace(value)) {
+                dictionary.Add(name, value);
+            }
+        }
+
+        private static string EventStringIfSpecified(string propertyName, string handler) {
+            if (!String.IsNullOrEmpty(handler)) {
+                return String.Format(CultureInfo.InvariantCulture, " {0}: Function.createDelegate(this, {1}),", propertyName, handler.ToString());
+            }
+            return String.Empty;
+        }
+
+        private static string PropertyStringIfSpecified(string propertyName, string propertyValue) {
+            if (!String.IsNullOrEmpty(propertyValue)) {
+                string escapedPropertyValue = propertyValue.Replace("'", @"\'");
+                return String.Format(CultureInfo.InvariantCulture, " {0}: '{1}',", propertyName, escapedPropertyValue);
+            }
+            return String.Empty;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Ajax/InsertionMode.cs b/mcs/class/System.Web.Mvc3/Mvc/Ajax/InsertionMode.cs
new file mode 100644 (file)
index 0000000..4335975
--- /dev/null
@@ -0,0 +1,7 @@
+namespace System.Web.Mvc.Ajax {
+    public enum InsertionMode {
+        Replace = 0,
+        InsertBefore = 1,
+        InsertAfter = 2
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/AjaxHelper.cs b/mcs/class/System.Web.Mvc3/Mvc/AjaxHelper.cs
new file mode 100644 (file)
index 0000000..0908bd3
--- /dev/null
@@ -0,0 +1,76 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Text;
+    using System.Web.Routing;
+    using System.Web.Script.Serialization;
+
+    public class AjaxHelper {
+
+        private static string _globalizationScriptPath;
+
+        public AjaxHelper(ViewContext viewContext, IViewDataContainer viewDataContainer)
+            : this(viewContext, viewDataContainer, RouteTable.Routes) {
+        }
+
+        public AjaxHelper(ViewContext viewContext, IViewDataContainer viewDataContainer, RouteCollection routeCollection) {
+            if (viewContext == null) {
+                throw new ArgumentNullException("viewContext");
+            }
+            if (viewDataContainer == null) {
+                throw new ArgumentNullException("viewDataContainer");
+            }
+            if (routeCollection == null) {
+                throw new ArgumentNullException("routeCollection");
+            }
+            ViewContext = viewContext;
+            ViewDataContainer = viewDataContainer;
+            RouteCollection = routeCollection;
+        }
+
+        public static string GlobalizationScriptPath {
+            get {
+                if (String.IsNullOrEmpty(_globalizationScriptPath)) {
+                    _globalizationScriptPath = "~/Scripts/Globalization";
+                }
+                return _globalizationScriptPath;
+            }
+            set {
+                _globalizationScriptPath = value;
+            }
+        }
+
+        public RouteCollection RouteCollection {
+            get;
+            private set;
+        }
+
+        public ViewContext ViewContext {
+            get;
+            private set;
+        }
+
+        public ViewDataDictionary ViewData {
+            get {
+                return ViewDataContainer.ViewData;
+            }
+        }
+
+        public IViewDataContainer ViewDataContainer {
+            get;
+            private set;
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Instance method for consistency with other helpers.")]
+        public string JavaScriptStringEncode(string message) {
+            if (String.IsNullOrEmpty(message)) {
+                return message;
+            }
+
+            StringBuilder builder = new StringBuilder();
+            JavaScriptSerializer serializer = new JavaScriptSerializer();
+            serializer.Serialize(message, builder);
+            return builder.ToString(1, builder.Length - 2); // remove first + last quote
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/AjaxHelper`1.cs b/mcs/class/System.Web.Mvc3/Mvc/AjaxHelper`1.cs
new file mode 100644 (file)
index 0000000..edba2df
--- /dev/null
@@ -0,0 +1,23 @@
+namespace System.Web.Mvc {
+    using System.Web.Routing;
+
+    public class AjaxHelper<TModel> : AjaxHelper {
+        private ViewDataDictionary<TModel> _viewData;
+
+        public AjaxHelper(ViewContext viewContext, IViewDataContainer viewDataContainer)
+            : this(viewContext, viewDataContainer, RouteTable.Routes) {
+        }
+
+        public AjaxHelper(ViewContext viewContext, IViewDataContainer viewDataContainer, RouteCollection routeCollection)
+            : base(viewContext, viewDataContainer, routeCollection) {
+
+            _viewData = new ViewDataDictionary<TModel>(viewDataContainer.ViewData);
+        }
+
+        public new ViewDataDictionary<TModel> ViewData {
+            get {
+                return _viewData;
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/AjaxRequestExtensions.cs b/mcs/class/System.Web.Mvc3/Mvc/AjaxRequestExtensions.cs
new file mode 100644 (file)
index 0000000..8f635c2
--- /dev/null
@@ -0,0 +1,14 @@
+namespace System.Web.Mvc {
+    using System;
+
+    public static class AjaxRequestExtensions {
+
+        public static bool IsAjaxRequest(this HttpRequestBase request) {
+            if (request == null) {
+                throw new ArgumentNullException("request");
+            }
+            
+            return (request["X-Requested-With"] == "XMLHttpRequest") || ((request.Headers != null) && (request.Headers["X-Requested-With"] == "XMLHttpRequest"));
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/AllowHtmlAttribute.cs b/mcs/class/System.Web.Mvc3/Mvc/AllowHtmlAttribute.cs
new file mode 100644 (file)
index 0000000..3d45e64
--- /dev/null
@@ -0,0 +1,19 @@
+namespace System.Web.Mvc {
+    using System;
+
+    // This attribute can be applied to a model property to specify that the particular property to
+    // which it is applied should not go through request validation.
+
+    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
+    public sealed class AllowHtmlAttribute : Attribute, IMetadataAware {
+
+        public void OnMetadataCreated(ModelMetadata metadata) {
+            if (metadata == null) {
+                throw new ArgumentNullException("metadata");
+            }
+
+            metadata.RequestValidationEnabled = false;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/AreaHelpers.cs b/mcs/class/System.Web.Mvc3/Mvc/AreaHelpers.cs
new file mode 100644 (file)
index 0000000..32a20d9
--- /dev/null
@@ -0,0 +1,31 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Web.Routing;
+
+    internal static class AreaHelpers {
+
+        public static string GetAreaName(RouteBase route) {
+            IRouteWithArea routeWithArea = route as IRouteWithArea;
+            if (routeWithArea != null) {
+                return routeWithArea.Area;
+            }
+
+            Route castRoute = route as Route;
+            if (castRoute != null && castRoute.DataTokens != null) {
+                return castRoute.DataTokens["area"] as string;
+            }
+
+            return null;
+        }
+
+        public static string GetAreaName(RouteData routeData) {
+            object area;
+            if (routeData.DataTokens.TryGetValue("area", out area)) {
+                return area as string;
+            }
+
+            return GetAreaName(routeData.Route);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/AreaRegistration.cs b/mcs/class/System.Web.Mvc3/Mvc/AreaRegistration.cs
new file mode 100644 (file)
index 0000000..28a8084
--- /dev/null
@@ -0,0 +1,50 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Web.Routing;
+
+    public abstract class AreaRegistration {
+
+        private const string _typeCacheName = "MVC-AreaRegistrationTypeCache.xml";
+
+        public abstract string AreaName {
+            get;
+        }
+
+        internal void CreateContextAndRegister(RouteCollection routes, object state) {
+            AreaRegistrationContext context = new AreaRegistrationContext(AreaName, routes, state);
+
+            string thisNamespace = GetType().Namespace;
+            if (thisNamespace != null) {
+                context.Namespaces.Add(thisNamespace + ".*");
+            }
+
+            RegisterArea(context);
+        }
+
+        private static bool IsAreaRegistrationType(Type type) {
+            return
+                typeof(AreaRegistration).IsAssignableFrom(type) &&
+                type.GetConstructor(Type.EmptyTypes) != null;
+        }
+
+        public static void RegisterAllAreas() {
+            RegisterAllAreas(null);
+        }
+
+        public static void RegisterAllAreas(object state) {
+            RegisterAllAreas(RouteTable.Routes, new BuildManagerWrapper(), state);
+        }
+
+        internal static void RegisterAllAreas(RouteCollection routes, IBuildManager buildManager, object state) {
+            List<Type> areaRegistrationTypes = TypeCacheUtil.GetFilteredTypesFromAssemblies(_typeCacheName, IsAreaRegistrationType, buildManager);
+            foreach (Type areaRegistrationType in areaRegistrationTypes) {
+                AreaRegistration registration = (AreaRegistration)Activator.CreateInstance(areaRegistrationType);
+                registration.CreateContextAndRegister(routes, state);
+            }
+        }
+
+        public abstract void RegisterArea(AreaRegistrationContext context);
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/AreaRegistrationContext.cs b/mcs/class/System.Web.Mvc3/Mvc/AreaRegistrationContext.cs
new file mode 100644 (file)
index 0000000..4c0bf02
--- /dev/null
@@ -0,0 +1,93 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq;
+    using System.Web.Routing;
+
+    public class AreaRegistrationContext {
+
+        private readonly HashSet<string> _namespaces = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
+
+        public AreaRegistrationContext(string areaName, RouteCollection routes)
+            : this(areaName, routes, null) {
+        }
+
+        public AreaRegistrationContext(string areaName, RouteCollection routes, object state) {
+            if (String.IsNullOrEmpty(areaName)) {
+                throw Error.ParameterCannotBeNullOrEmpty("areaName");
+            }
+            if (routes == null) {
+                throw new ArgumentNullException("routes");
+            }
+
+            AreaName = areaName;
+            Routes = routes;
+            State = state;
+        }
+
+        public string AreaName {
+            get;
+            private set;
+        }
+
+        public ICollection<string> Namespaces {
+            get {
+                return _namespaces;
+            }
+        }
+
+        public RouteCollection Routes {
+            get;
+            private set;
+        }
+
+        public object State {
+            get;
+            private set;
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#", Justification = "This is not a regular URL as it may contain special routing characters.")]
+        public Route MapRoute(string name, string url) {
+            return MapRoute(name, url, (object)null /* defaults */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#", Justification = "This is not a regular URL as it may contain special routing characters.")]
+        public Route MapRoute(string name, string url, object defaults) {
+            return MapRoute(name, url, defaults, (object)null /* constraints */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#", Justification = "This is not a regular URL as it may contain special routing characters.")]
+        public Route MapRoute(string name, string url, object defaults, object constraints) {
+            return MapRoute(name, url, defaults, constraints, null /* namespaces */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#", Justification = "This is not a regular URL as it may contain special routing characters.")]
+        public Route MapRoute(string name, string url, string[] namespaces) {
+            return MapRoute(name, url, (object)null /* defaults */, namespaces);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#", Justification = "This is not a regular URL as it may contain special routing characters.")]
+        public Route MapRoute(string name, string url, object defaults, string[] namespaces) {
+            return MapRoute(name, url, defaults, null /* constraints */, namespaces);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#", Justification = "This is not a regular URL as it may contain special routing characters.")]
+        public Route MapRoute(string name, string url, object defaults, object constraints, string[] namespaces) {
+            if (namespaces == null && Namespaces != null) {
+                namespaces = Namespaces.ToArray();
+            }
+
+            Route route = Routes.MapRoute(name, url, defaults, constraints, namespaces);
+            route.DataTokens["area"] = AreaName;
+
+            // disabling the namespace lookup fallback mechanism keeps this areas from accidentally picking up
+            // controllers belonging to other areas
+            bool useNamespaceFallback = (namespaces == null || namespaces.Length == 0);
+            route.DataTokens["UseNamespaceFallback"] = useNamespaceFallback;
+
+            return route;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/AssociatedMetadataProvider.cs b/mcs/class/System.Web.Mvc3/Mvc/AssociatedMetadataProvider.cs
new file mode 100644 (file)
index 0000000..94c09aa
--- /dev/null
@@ -0,0 +1,93 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.ComponentModel;
+    using System.ComponentModel.DataAnnotations;
+    using System.Globalization;
+    using System.Linq;
+    using System.Web.Mvc.Resources;
+
+    // This class provides a good implementation of ModelMetadataProvider for people who will be
+    // using traditional classes with properties. It uses the buddy class support from
+    // DataAnnotations, and consolidates the three operations down to a single override
+    // for reading the attribute values and creating the metadata class.
+    public abstract class AssociatedMetadataProvider : ModelMetadataProvider {
+        private static void ApplyMetadataAwareAttributes(IEnumerable<Attribute> attributes, ModelMetadata result) {
+            foreach (IMetadataAware awareAttribute in attributes.OfType<IMetadataAware>()) {
+                awareAttribute.OnMetadataCreated(result);
+            }
+        }
+
+        protected abstract ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName);
+
+        protected virtual IEnumerable<Attribute> FilterAttributes(Type containerType, PropertyDescriptor propertyDescriptor, IEnumerable<Attribute> attributes) {
+            if (typeof(ViewPage).IsAssignableFrom(containerType) || typeof(ViewUserControl).IsAssignableFrom(containerType)) {
+                return attributes.Where(a => !(a is ReadOnlyAttribute));
+            }
+
+            return attributes;
+        }
+
+        public override IEnumerable<ModelMetadata> GetMetadataForProperties(object container, Type containerType) {
+            if (containerType == null) {
+                throw new ArgumentNullException("containerType");
+            }
+
+            return GetMetadataForPropertiesImpl(container, containerType);
+        }
+
+        private IEnumerable<ModelMetadata> GetMetadataForPropertiesImpl(object container, Type containerType) {
+            foreach (PropertyDescriptor property in GetTypeDescriptor(containerType).GetProperties()) {
+                Func<object> modelAccessor = container == null ? null : GetPropertyValueAccessor(container, property);
+                yield return GetMetadataForProperty(modelAccessor, containerType, property);
+            }
+        }
+
+        public override ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, string propertyName) {
+            if (containerType == null) {
+                throw new ArgumentNullException("containerType");
+            }
+            if (String.IsNullOrEmpty(propertyName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "propertyName");
+            }
+
+            ICustomTypeDescriptor typeDescriptor = GetTypeDescriptor(containerType);
+            PropertyDescriptor property = typeDescriptor.GetProperties().Find(propertyName, true);
+            if (property == null) {
+                throw new ArgumentException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.Common_PropertyNotFound,
+                        containerType.FullName, propertyName));
+            }
+
+            return GetMetadataForProperty(modelAccessor, containerType, property);
+        }
+
+        protected virtual ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, PropertyDescriptor propertyDescriptor) {
+            IEnumerable<Attribute> attributes = FilterAttributes(containerType, propertyDescriptor, propertyDescriptor.Attributes.Cast<Attribute>());
+            ModelMetadata result = CreateMetadata(attributes, containerType, modelAccessor, propertyDescriptor.PropertyType, propertyDescriptor.Name);
+            ApplyMetadataAwareAttributes(attributes, result);
+            return result;
+        }
+
+        public override ModelMetadata GetMetadataForType(Func<object> modelAccessor, Type modelType) {
+            if (modelType == null) {
+                throw new ArgumentNullException("modelType");
+            }
+
+            IEnumerable<Attribute> attributes = GetTypeDescriptor(modelType).GetAttributes().Cast<Attribute>();
+            ModelMetadata result = CreateMetadata(attributes, null /* containerType */, modelAccessor, modelType, null /* propertyName */);
+            ApplyMetadataAwareAttributes(attributes, result);
+            return result;
+        }
+
+        private static Func<object> GetPropertyValueAccessor(object container, PropertyDescriptor property) {
+            return () => property.GetValue(container);
+        }
+
+        protected virtual ICustomTypeDescriptor GetTypeDescriptor(Type type) {
+            return TypeDescriptorHelper.Get(type);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/AssociatedValidatorProvider.cs b/mcs/class/System.Web.Mvc3/Mvc/AssociatedValidatorProvider.cs
new file mode 100644 (file)
index 0000000..a360bd0
--- /dev/null
@@ -0,0 +1,51 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.ComponentModel;
+    using System.ComponentModel.DataAnnotations;
+    using System.Globalization;
+    using System.Linq;
+    using System.Web.Mvc.Resources;
+
+    public abstract class AssociatedValidatorProvider : ModelValidatorProvider {
+        protected virtual ICustomTypeDescriptor GetTypeDescriptor(Type type) {
+            return TypeDescriptorHelper.Get(type);
+        }
+
+        public override sealed IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context) {
+            if (metadata == null) {
+                throw new ArgumentNullException("metadata");
+            }
+            if (context == null) {
+                throw new ArgumentNullException("context");
+            }
+
+            if (metadata.ContainerType != null && !String.IsNullOrEmpty(metadata.PropertyName)) {
+                return GetValidatorsForProperty(metadata, context);
+            }
+
+            return GetValidatorsForType(metadata, context);
+        }
+
+        protected abstract IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes);
+
+        private IEnumerable<ModelValidator> GetValidatorsForProperty(ModelMetadata metadata, ControllerContext context) {
+            ICustomTypeDescriptor typeDescriptor = GetTypeDescriptor(metadata.ContainerType);
+            PropertyDescriptor property = typeDescriptor.GetProperties().Find(metadata.PropertyName, true);
+            if (property == null) {
+                throw new ArgumentException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.Common_PropertyNotFound,
+                        metadata.ContainerType.FullName, metadata.PropertyName),
+                    "metadata");
+            }
+
+            return GetValidators(metadata, context, property.Attributes.OfType<Attribute>());
+        }
+
+        private IEnumerable<ModelValidator> GetValidatorsForType(ModelMetadata metadata, ControllerContext context) {
+            return GetValidators(metadata, context, GetTypeDescriptor(metadata.ModelType).GetAttributes().Cast<Attribute>());
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Async/ActionDescriptorCreator.cs b/mcs/class/System.Web.Mvc3/Mvc/Async/ActionDescriptorCreator.cs
new file mode 100644 (file)
index 0000000..d746b3f
--- /dev/null
@@ -0,0 +1,6 @@
+namespace System.Web.Mvc.Async {
+    using System;
+
+    internal delegate ActionDescriptor ActionDescriptorCreator(string actionName, ControllerDescriptor controllerDescriptor);
+
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Async/AsyncActionDescriptor.cs b/mcs/class/System.Web.Mvc3/Mvc/Async/AsyncActionDescriptor.cs
new file mode 100644 (file)
index 0000000..fe408cf
--- /dev/null
@@ -0,0 +1,28 @@
+namespace System.Web.Mvc.Async {
+    using System;
+    using System.Collections.Generic;
+
+    public abstract class AsyncActionDescriptor : ActionDescriptor {
+
+        public abstract IAsyncResult BeginExecute(ControllerContext controllerContext, IDictionary<string, object> parameters, AsyncCallback callback, object state);
+
+        public abstract object EndExecute(IAsyncResult asyncResult);
+
+        public override object Execute(ControllerContext controllerContext, IDictionary<string, object> parameters) {
+            // execute an asynchronous task synchronously
+            IAsyncResult asyncResult = BeginExecute(controllerContext, parameters, null, null);
+            AsyncUtil.WaitForAsyncResultCompletion(asyncResult, controllerContext.HttpContext.ApplicationInstance); // blocks
+            return EndExecute(asyncResult);
+        }
+
+        internal static AsyncManager GetAsyncManager(ControllerBase controller) {
+            IAsyncManagerContainer helperContainer = controller as IAsyncManagerContainer;
+            if (helperContainer == null) {
+                throw Error.AsyncCommon_ControllerMustImplementIAsyncManagerContainer(controller.GetType());
+            }
+
+            return helperContainer.AsyncManager;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Async/AsyncActionMethodSelector.cs b/mcs/class/System.Web.Mvc3/Mvc/Async/AsyncActionMethodSelector.cs
new file mode 100644 (file)
index 0000000..5c05f18
--- /dev/null
@@ -0,0 +1,194 @@
+namespace System.Web.Mvc.Async {
+    using System;
+    using System.Collections.Generic;
+    using System.Globalization;
+    using System.Linq;
+    using System.Reflection;
+    using System.Text;
+    using System.Web.Mvc.Resources;
+
+    internal sealed class AsyncActionMethodSelector {
+
+        public AsyncActionMethodSelector(Type controllerType) {
+            ControllerType = controllerType;
+            PopulateLookupTables();
+        }
+
+        public Type ControllerType {
+            get;
+            private set;
+        }
+
+        public MethodInfo[] AliasedMethods {
+            get;
+            private set;
+        }
+
+        public ILookup<string, MethodInfo> NonAliasedMethods {
+            get;
+            private set;
+        }
+
+        private AmbiguousMatchException CreateAmbiguousActionMatchException(IEnumerable<MethodInfo> ambiguousMethods, string actionName) {
+            string ambiguityList = CreateAmbiguousMatchList(ambiguousMethods);
+            string message = String.Format(CultureInfo.CurrentCulture, MvcResources.ActionMethodSelector_AmbiguousMatch,
+                actionName, ControllerType.Name, ambiguityList);
+            return new AmbiguousMatchException(message);
+        }
+
+        private AmbiguousMatchException CreateAmbiguousMethodMatchException(IEnumerable<MethodInfo> ambiguousMethods, string methodName) {
+            string ambiguityList = CreateAmbiguousMatchList(ambiguousMethods);
+            string message = String.Format(CultureInfo.CurrentCulture, MvcResources.AsyncActionMethodSelector_AmbiguousMethodMatch,
+                methodName, ControllerType.Name, ambiguityList);
+            return new AmbiguousMatchException(message);
+        }
+
+        private static string CreateAmbiguousMatchList(IEnumerable<MethodInfo> ambiguousMethods) {
+            StringBuilder exceptionMessageBuilder = new StringBuilder();
+            foreach (MethodInfo methodInfo in ambiguousMethods) {
+                exceptionMessageBuilder.AppendLine();
+                exceptionMessageBuilder.AppendFormat(CultureInfo.CurrentCulture, MvcResources.ActionMethodSelector_AmbiguousMatchType, methodInfo, methodInfo.DeclaringType.FullName);
+            }
+
+            return exceptionMessageBuilder.ToString();
+        }
+
+        public ActionDescriptorCreator FindAction(ControllerContext controllerContext, string actionName) {
+            List<MethodInfo> methodsMatchingName = GetMatchingAliasedMethods(controllerContext, actionName);
+            methodsMatchingName.AddRange(NonAliasedMethods[actionName]);
+            List<MethodInfo> finalMethods = RunSelectionFilters(controllerContext, methodsMatchingName);
+
+            switch (finalMethods.Count) {
+                case 0:
+                    return null;
+
+                case 1:
+                    MethodInfo entryMethod = finalMethods[0];
+                    return GetActionDescriptorDelegate(entryMethod);
+
+                default:
+                    throw CreateAmbiguousActionMatchException(finalMethods, actionName);
+            }
+        }
+
+        private ActionDescriptorCreator GetActionDescriptorDelegate(MethodInfo entryMethod) {
+            // Is this the FooAsync() / FooCompleted() pattern?
+            if (IsAsyncSuffixedMethod(entryMethod)) {
+                string completionMethodName = entryMethod.Name.Substring(0, entryMethod.Name.Length - "Async".Length) + "Completed";
+                MethodInfo completionMethod = GetMethodByName(completionMethodName);
+                if (completionMethod != null) {
+                    return (actionName, controllerDescriptor) => new ReflectedAsyncActionDescriptor(entryMethod, completionMethod, actionName, controllerDescriptor);
+                }
+                else {
+                    throw Error.AsyncActionMethodSelector_CouldNotFindMethod(completionMethodName, ControllerType);
+                }
+            }
+
+            // Fallback to synchronous method
+            return (actionName, controllerDescriptor) => new ReflectedActionDescriptor(entryMethod, actionName, controllerDescriptor);
+        }
+
+        private static string GetCanonicalMethodName(MethodInfo methodInfo) {
+            string methodName = methodInfo.Name;
+            return (IsAsyncSuffixedMethod(methodInfo))
+                ? methodName.Substring(0, methodName.Length - "Async".Length)
+                : methodName;
+        }
+
+        internal List<MethodInfo> GetMatchingAliasedMethods(ControllerContext controllerContext, string actionName) {
+            // find all aliased methods which are opting in to this request
+            // to opt in, all attributes defined on the method must return true
+
+            var methods = from methodInfo in AliasedMethods
+                          let attrs = ReflectedAttributeCache.GetActionNameSelectorAttributes(methodInfo)
+                          where attrs.All(attr => attr.IsValidName(controllerContext, actionName, methodInfo))
+                          select methodInfo;
+            return methods.ToList();
+        }
+
+        private static bool IsAsyncSuffixedMethod(MethodInfo methodInfo) {
+            return methodInfo.Name.EndsWith("Async", StringComparison.OrdinalIgnoreCase);
+        }
+
+        private static bool IsCompletedSuffixedMethod(MethodInfo methodInfo) {
+            return methodInfo.Name.EndsWith("Completed", StringComparison.OrdinalIgnoreCase);
+        }
+
+        private static bool IsMethodDecoratedWithAliasingAttribute(MethodInfo methodInfo) {
+            return methodInfo.IsDefined(typeof(ActionNameSelectorAttribute), true /* inherit */);
+        }
+
+        private MethodInfo GetMethodByName(string methodName) {
+            List<MethodInfo> methods = (from MethodInfo methodInfo in ControllerType.GetMember(methodName, MemberTypes.Method, BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.IgnoreCase)
+                                        where IsValidActionMethod(methodInfo, false /* stripInfrastructureMethods */)
+                                        select methodInfo).ToList();
+
+            switch (methods.Count) {
+                case 0:
+                    return null;
+
+                case 1:
+                    return methods[0];
+
+                default:
+                    throw CreateAmbiguousMethodMatchException(methods, methodName);
+            }
+        }
+
+        private static bool IsValidActionMethod(MethodInfo methodInfo) {
+            return IsValidActionMethod(methodInfo, true /* stripInfrastructureMethods */);
+        }
+
+        private static bool IsValidActionMethod(MethodInfo methodInfo, bool stripInfrastructureMethods) {
+            if (methodInfo.IsSpecialName) {
+                // not a normal method, e.g. a constructor or an event
+                return false;
+            }
+
+            if (methodInfo.GetBaseDefinition().DeclaringType.IsAssignableFrom(typeof(AsyncController))) {
+                // is a method on Object, ControllerBase, Controller, or AsyncController
+                return false;
+            };
+
+            if (stripInfrastructureMethods) {
+                if (IsCompletedSuffixedMethod(methodInfo)) {
+                    // do not match FooCompleted() methods, as these are infrastructure methods
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        private void PopulateLookupTables() {
+            MethodInfo[] allMethods = ControllerType.GetMethods(BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public);
+            MethodInfo[] actionMethods = Array.FindAll(allMethods, IsValidActionMethod);
+
+            AliasedMethods = Array.FindAll(actionMethods, IsMethodDecoratedWithAliasingAttribute);
+            NonAliasedMethods = actionMethods.Except(AliasedMethods).ToLookup(GetCanonicalMethodName, StringComparer.OrdinalIgnoreCase);
+        }
+
+        private static List<MethodInfo> RunSelectionFilters(ControllerContext controllerContext, List<MethodInfo> methodInfos) {
+            // remove all methods which are opting out of this request
+            // to opt out, at least one attribute defined on the method must return false
+
+            List<MethodInfo> matchesWithSelectionAttributes = new List<MethodInfo>();
+            List<MethodInfo> matchesWithoutSelectionAttributes = new List<MethodInfo>();
+
+            foreach (MethodInfo methodInfo in methodInfos) {
+                ICollection<ActionMethodSelectorAttribute> attrs = ReflectedAttributeCache.GetActionMethodSelectorAttributes(methodInfo);
+                if (attrs.Count == 0) {
+                    matchesWithoutSelectionAttributes.Add(methodInfo);
+                }
+                else if (attrs.All(attr => attr.IsValidForRequest(controllerContext, methodInfo))) {
+                    matchesWithSelectionAttributes.Add(methodInfo);
+                }
+            }
+
+            // if a matching action method had a selection attribute, consider it more specific than a matching action method
+            // without a selection attribute
+            return (matchesWithSelectionAttributes.Count > 0) ? matchesWithSelectionAttributes : matchesWithoutSelectionAttributes;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Async/AsyncControllerActionInvoker.cs b/mcs/class/System.Web.Mvc3/Mvc/Async/AsyncControllerActionInvoker.cs
new file mode 100644 (file)
index 0000000..fe96d37
--- /dev/null
@@ -0,0 +1,270 @@
+namespace System.Web.Mvc.Async {
+    using System;
+    using System.Collections.Generic;
+    using System.Linq;
+    using System.Threading;
+
+    public class AsyncControllerActionInvoker : ControllerActionInvoker, IAsyncActionInvoker {
+
+        private static readonly object _invokeActionTag = new object();
+        private static readonly object _invokeActionMethodTag = new object();
+        private static readonly object _invokeActionMethodWithFiltersTag = new object();
+
+        public virtual IAsyncResult BeginInvokeAction(ControllerContext controllerContext, string actionName, AsyncCallback callback, object state) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+            if (String.IsNullOrEmpty(actionName)) {
+                throw Error.ParameterCannotBeNullOrEmpty("actionName");
+            }
+
+            ControllerDescriptor controllerDescriptor = GetControllerDescriptor(controllerContext);
+            ActionDescriptor actionDescriptor = controllerDescriptor.FindAction(controllerContext, actionName);
+            if (actionDescriptor != null) {
+                FilterInfo filterInfo = GetFilters(controllerContext, actionDescriptor);
+                Action continuation = null;
+
+                BeginInvokeDelegate beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState) {
+                    try {
+                        AuthorizationContext authContext = InvokeAuthorizationFilters(controllerContext, filterInfo.AuthorizationFilters, actionDescriptor);
+                        if (authContext.Result != null) {
+                            // the auth filter signaled that we should let it short-circuit the request
+                            continuation = () => InvokeActionResult(controllerContext, authContext.Result);
+                        }
+                        else {
+                            if (controllerContext.Controller.ValidateRequest) {
+                                ValidateRequest(controllerContext);
+                            }
+
+                            IDictionary<string, object> parameters = GetParameterValues(controllerContext, actionDescriptor);
+                            IAsyncResult asyncResult = BeginInvokeActionMethodWithFilters(controllerContext, filterInfo.ActionFilters, actionDescriptor, parameters, asyncCallback, asyncState);
+                            continuation = () => {
+                                ActionExecutedContext postActionContext = EndInvokeActionMethodWithFilters(asyncResult);
+                                InvokeActionResultWithFilters(controllerContext, filterInfo.ResultFilters, postActionContext.Result);
+                            };
+                            return asyncResult;
+                        }
+                    }
+                    catch (ThreadAbortException) {
+                        // This type of exception occurs as a result of Response.Redirect(), but we special-case so that
+                        // the filters don't see this as an error.
+                        throw;
+                    }
+                    catch (Exception ex) {
+                        // something blew up, so execute the exception filters
+                        ExceptionContext exceptionContext = InvokeExceptionFilters(controllerContext, filterInfo.ExceptionFilters, ex);
+                        if (!exceptionContext.ExceptionHandled) {
+                            throw;
+                        }
+
+                        continuation = () => InvokeActionResult(controllerContext, exceptionContext.Result);
+                    }
+
+                    return BeginInvokeAction_MakeSynchronousAsyncResult(asyncCallback, asyncState);
+                };
+
+                EndInvokeDelegate<bool> endDelegate = delegate(IAsyncResult asyncResult) {
+                    try {
+                        continuation();
+                    }
+                    catch (ThreadAbortException) {
+                        // This type of exception occurs as a result of Response.Redirect(), but we special-case so that
+                        // the filters don't see this as an error.
+                        throw;
+                    }
+                    catch (Exception ex) {
+                        // something blew up, so execute the exception filters
+                        ExceptionContext exceptionContext = InvokeExceptionFilters(controllerContext, filterInfo.ExceptionFilters, ex);
+                        if (!exceptionContext.ExceptionHandled) {
+                            throw;
+                        }
+                        InvokeActionResult(controllerContext, exceptionContext.Result);
+                    }
+
+                    return true;
+                };
+
+                return AsyncResultWrapper.Begin(callback, state, beginDelegate, endDelegate, _invokeActionTag);
+            }
+            else {
+                // Notify the controller that no action was found.
+                return BeginInvokeAction_ActionNotFound(callback, state);
+            }
+        }
+
+        private static IAsyncResult BeginInvokeAction_ActionNotFound(AsyncCallback callback, object state) {
+            BeginInvokeDelegate beginDelegate = BeginInvokeAction_MakeSynchronousAsyncResult;
+
+            EndInvokeDelegate<bool> endDelegate = delegate(IAsyncResult asyncResult) {
+                return false;
+            };
+
+            return AsyncResultWrapper.Begin(callback, state, beginDelegate, endDelegate, _invokeActionTag);
+        }
+
+        private static IAsyncResult BeginInvokeAction_MakeSynchronousAsyncResult(AsyncCallback callback, object state) {
+            SimpleAsyncResult asyncResult = new SimpleAsyncResult(state);
+            asyncResult.MarkCompleted(true /* completedSynchronously */, callback);
+            return asyncResult;
+        }
+
+        protected internal virtual IAsyncResult BeginInvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters, AsyncCallback callback, object state) {
+            AsyncActionDescriptor asyncActionDescriptor = actionDescriptor as AsyncActionDescriptor;
+            if (asyncActionDescriptor != null) {
+                return BeginInvokeAsynchronousActionMethod(controllerContext, asyncActionDescriptor, parameters, callback, state);
+            }
+            else {
+                return BeginInvokeSynchronousActionMethod(controllerContext, actionDescriptor, parameters, callback, state);
+            }
+        }
+
+        protected internal virtual IAsyncResult BeginInvokeActionMethodWithFilters(ControllerContext controllerContext, IList<IActionFilter> filters, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters, AsyncCallback callback, object state) {
+            Func<ActionExecutedContext> endContinuation = null;
+
+            BeginInvokeDelegate beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState) {
+                ActionExecutingContext preContext = new ActionExecutingContext(controllerContext, actionDescriptor, parameters);
+                IAsyncResult innerAsyncResult = null;
+
+                Func<Func<ActionExecutedContext>> beginContinuation = () => {
+                    innerAsyncResult = BeginInvokeActionMethod(controllerContext, actionDescriptor, parameters, asyncCallback, asyncState);
+                    return () =>
+                        new ActionExecutedContext(controllerContext, actionDescriptor, false /* canceled */, null /* exception */) {
+                            Result = EndInvokeActionMethod(innerAsyncResult)
+                        };
+                };
+
+                // need to reverse the filter list because the continuations are built up backward
+                Func<Func<ActionExecutedContext>> thunk = filters.Reverse().Aggregate(beginContinuation,
+                    (next, filter) => () => InvokeActionMethodFilterAsynchronously(filter, preContext, next));
+                endContinuation = thunk();
+
+                if (innerAsyncResult != null) {
+                    // we're just waiting for the inner result to complete
+                    return innerAsyncResult;
+                }
+                else {
+                    // something was short-circuited and the action was not called, so this was a synchronous operation
+                    SimpleAsyncResult newAsyncResult = new SimpleAsyncResult(asyncState);
+                    newAsyncResult.MarkCompleted(true /* completedSynchronously */, asyncCallback);
+                    return newAsyncResult;
+                }
+            };
+
+            EndInvokeDelegate<ActionExecutedContext> endDelegate = delegate(IAsyncResult asyncResult) {
+                return endContinuation();
+            };
+
+            return AsyncResultWrapper.Begin(callback, state, beginDelegate, endDelegate, _invokeActionMethodWithFiltersTag);
+        }
+
+        private IAsyncResult BeginInvokeAsynchronousActionMethod(ControllerContext controllerContext, AsyncActionDescriptor actionDescriptor, IDictionary<string, object> parameters, AsyncCallback callback, object state) {
+            BeginInvokeDelegate beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState) {
+                return actionDescriptor.BeginExecute(controllerContext, parameters, asyncCallback, asyncState);
+            };
+
+            EndInvokeDelegate<ActionResult> endDelegate = delegate(IAsyncResult asyncResult) {
+                object returnValue = actionDescriptor.EndExecute(asyncResult);
+                ActionResult result = CreateActionResult(controllerContext, actionDescriptor, returnValue);
+                return result;
+            };
+
+            return AsyncResultWrapper.Begin(callback, state, beginDelegate, endDelegate, _invokeActionMethodTag);
+        }
+
+        private IAsyncResult BeginInvokeSynchronousActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters, AsyncCallback callback, object state) {
+            return AsyncResultWrapper.BeginSynchronous(callback, state,
+                () => InvokeSynchronousActionMethod(controllerContext, actionDescriptor, parameters),
+                _invokeActionMethodTag);
+        }
+
+        public virtual bool EndInvokeAction(IAsyncResult asyncResult) {
+            return AsyncResultWrapper.End<bool>(asyncResult, _invokeActionTag);
+        }
+
+        protected internal virtual ActionResult EndInvokeActionMethod(IAsyncResult asyncResult) {
+            return AsyncResultWrapper.End<ActionResult>(asyncResult, _invokeActionMethodTag);
+        }
+
+        protected internal virtual ActionExecutedContext EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) {
+            return AsyncResultWrapper.End<ActionExecutedContext>(asyncResult, _invokeActionMethodWithFiltersTag);
+        }
+
+        protected override ControllerDescriptor GetControllerDescriptor(ControllerContext controllerContext) {
+            Type controllerType = controllerContext.Controller.GetType();
+            ControllerDescriptor controllerDescriptor = DescriptorCache.GetDescriptor(controllerType, () => new ReflectedAsyncControllerDescriptor(controllerType));
+            return controllerDescriptor;
+        }
+
+        internal static Func<ActionExecutedContext> InvokeActionMethodFilterAsynchronously(IActionFilter filter, ActionExecutingContext preContext, Func<Func<ActionExecutedContext>> nextInChain) {
+            filter.OnActionExecuting(preContext);
+            if (preContext.Result != null) {
+                ActionExecutedContext shortCircuitedPostContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, true /* canceled */, null /* exception */) {
+                    Result = preContext.Result
+                };
+                return () => shortCircuitedPostContext;
+            }
+
+            // There is a nested try / catch block here that contains much the same logic as the outer block.
+            // Since an exception can occur on either side of the asynchronous invocation, we need guards on
+            // on both sides. In the code below, the second side is represented by the nested delegate. This
+            // is really just a parallel of the synchronous ControllerActionInvoker.InvokeActionMethodFilter()
+            // method.
+
+            try {
+                Func<ActionExecutedContext> continuation = nextInChain();
+
+                // add our own continuation, then return the new function
+                return () => {
+                    ActionExecutedContext postContext;
+                    bool wasError = true;
+
+                    try {
+                        postContext = continuation();
+                        wasError = false;
+                    }
+                    catch (ThreadAbortException) {
+                        // This type of exception occurs as a result of Response.Redirect(), but we special-case so that
+                        // the filters don't see this as an error.
+                        postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, null /* exception */);
+                        filter.OnActionExecuted(postContext);
+                        throw;
+                    }
+                    catch (Exception ex) {
+                        postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, ex);
+                        filter.OnActionExecuted(postContext);
+                        if (!postContext.ExceptionHandled) {
+                            throw;
+                        }
+                    }
+                    if (!wasError) {
+                        filter.OnActionExecuted(postContext);
+                    }
+
+                    return postContext;
+                };
+            }
+            catch (ThreadAbortException) {
+                // This type of exception occurs as a result of Response.Redirect(), but we special-case so that
+                // the filters don't see this as an error.
+                ActionExecutedContext postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, null /* exception */);
+                filter.OnActionExecuted(postContext);
+                throw;
+            }
+            catch (Exception ex) {
+                ActionExecutedContext postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, ex);
+                filter.OnActionExecuted(postContext);
+                if (postContext.ExceptionHandled) {
+                    return () => postContext;
+                }
+                else {
+                    throw;
+                }
+            }
+        }
+
+        private ActionResult InvokeSynchronousActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters) {
+            return base.InvokeActionMethod(controllerContext, actionDescriptor, parameters);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Async/AsyncManager.cs b/mcs/class/System.Web.Mvc3/Mvc/Async/AsyncManager.cs
new file mode 100644 (file)
index 0000000..ba2c1f0
--- /dev/null
@@ -0,0 +1,67 @@
+namespace System.Web.Mvc.Async {
+    using System;
+    using System.Collections.Generic;
+    using System.Threading;
+
+    public class AsyncManager {
+
+        private readonly SynchronizationContext _syncContext;
+
+        // default timeout is 45 sec
+        // from: http://msdn.microsoft.com/en-us/library/system.web.ui.page.asynctimeout.aspx
+        private int _timeout = 45 * 1000;
+
+        public AsyncManager()
+            : this(null /* syncContext */) {
+        }
+
+        public AsyncManager(SynchronizationContext syncContext) {
+            _syncContext = syncContext ?? SynchronizationContextUtil.GetSynchronizationContext();
+
+            OutstandingOperations = new OperationCounter();
+            OutstandingOperations.Completed += delegate { Finish(); };
+
+            Parameters = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
+        }
+
+        public OperationCounter OutstandingOperations {
+            get;
+            private set;
+        }
+
+        public IDictionary<string, object> Parameters {
+            get;
+            private set;
+        }
+
+        public event EventHandler Finished;
+
+        // the developer may call this function to signal that all operations are complete instead of
+        // waiting for the operation counter to reach zero
+        public virtual void Finish() {
+            EventHandler handler = Finished;
+            if (handler != null) {
+                handler(this, EventArgs.Empty);
+            }
+        }
+
+        // executes a callback in the current synchronization context, which gives access to HttpContext and related items
+        public virtual void Sync(Action action) {
+            _syncContext.Sync(action);
+        }
+
+        // measured in milliseconds, Timeout.Infinite means 'no timeout'
+        public int Timeout {
+            get {
+                return _timeout;
+            }
+            set {
+                if (value < -1) {
+                    throw Error.AsyncCommon_InvalidTimeout("value");
+                }
+                _timeout = value;
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Async/AsyncResultWrapper.cs b/mcs/class/System.Web.Mvc3/Mvc/Async/AsyncResultWrapper.cs
new file mode 100644 (file)
index 0000000..c8e108b
--- /dev/null
@@ -0,0 +1,256 @@
+namespace System.Web.Mvc.Async {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Threading;
+
+    // This class is used for the following pattern:
+
+    // public IAsyncResult BeginInner(..., callback, state);
+    // public TInnerResult EndInner(asyncResult);
+    // public IAsyncResult BeginOuter(..., callback, state);
+    // public TOuterResult EndOuter(asyncResult);
+
+    // That is, Begin/EndOuter() wrap Begin/EndInner(), potentially with pre- and post-processing.
+
+    internal static class AsyncResultWrapper {
+
+        // helper methods
+
+        private static Func<AsyncVoid> MakeVoidDelegate(Action action) {
+            return () =>
+            {
+                action();
+                return default(AsyncVoid);
+            };
+        }
+
+        private static EndInvokeDelegate<AsyncVoid> MakeVoidDelegate(EndInvokeDelegate endDelegate) {
+            return ar =>
+            {
+                endDelegate(ar);
+                return default(AsyncVoid);
+            };
+        }
+
+        // kicks off an asynchronous operation
+
+        public static IAsyncResult Begin<TResult>(AsyncCallback callback, object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate<TResult> endDelegate) {
+            return Begin<TResult>(callback, state, beginDelegate, endDelegate, null /* tag */);
+        }
+
+        public static IAsyncResult Begin<TResult>(AsyncCallback callback, object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate<TResult> endDelegate, object tag) {
+            return Begin<TResult>(callback, state, beginDelegate, endDelegate, tag, Timeout.Infinite);
+        }
+
+        public static IAsyncResult Begin<TResult>(AsyncCallback callback, object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate<TResult> endDelegate, object tag, int timeout) {
+            WrappedAsyncResult<TResult> asyncResult = new WrappedAsyncResult<TResult>(beginDelegate, endDelegate, tag);
+            asyncResult.Begin(callback, state, timeout);
+            return asyncResult;
+        }
+
+        public static IAsyncResult Begin(AsyncCallback callback, object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate) {
+            return Begin(callback, state, beginDelegate, endDelegate, null /* tag */);
+        }
+
+        public static IAsyncResult Begin(AsyncCallback callback, object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate, object tag) {
+            return Begin(callback, state, beginDelegate, endDelegate, tag, Timeout.Infinite);
+        }
+
+        public static IAsyncResult Begin(AsyncCallback callback, object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate, object tag, int timeout) {
+            return Begin<AsyncVoid>(callback, state, beginDelegate, MakeVoidDelegate(endDelegate), tag, timeout);
+        }
+
+        // wraps a synchronous operation in an asynchronous wrapper, but still completes synchronously
+
+        public static IAsyncResult BeginSynchronous<TResult>(AsyncCallback callback, object state, Func<TResult> func) {
+            return BeginSynchronous<TResult>(callback, state, func, null /* tag */);
+        }
+
+        public static IAsyncResult BeginSynchronous<TResult>(AsyncCallback callback, object state, Func<TResult> func, object tag) {
+            // Begin() doesn't perform any work on its own and returns immediately.
+            BeginInvokeDelegate beginDelegate = (asyncCallback, asyncState) =>
+            {
+                SimpleAsyncResult innerAsyncResult = new SimpleAsyncResult(asyncState);
+                innerAsyncResult.MarkCompleted(true /* completedSynchronously */, asyncCallback);
+                return innerAsyncResult;
+            };
+
+            // The End() method blocks.
+            EndInvokeDelegate<TResult> endDelegate = _ =>
+            {
+                return func();
+            };
+
+            WrappedAsyncResult<TResult> asyncResult = new WrappedAsyncResult<TResult>(beginDelegate, endDelegate, tag);
+            asyncResult.Begin(callback, state, Timeout.Infinite);
+            return asyncResult;
+        }
+
+        public static IAsyncResult BeginSynchronous(AsyncCallback callback, object state, Action action) {
+            return BeginSynchronous(callback, state, action, null /* tag */);
+        }
+
+        public static IAsyncResult BeginSynchronous(AsyncCallback callback, object state, Action action, object tag) {
+            return BeginSynchronous<AsyncVoid>(callback, state, MakeVoidDelegate(action), tag);
+        }
+
+        // completes an asynchronous operation
+
+        public static TResult End<TResult>(IAsyncResult asyncResult) {
+            return End<TResult>(asyncResult, null /* tag */);
+        }
+
+        public static TResult End<TResult>(IAsyncResult asyncResult, object tag) {
+            return WrappedAsyncResult<TResult>.Cast(asyncResult, tag).End();
+        }
+
+        public static void End(IAsyncResult asyncResult) {
+            End(asyncResult, null /* tag */);
+        }
+
+        public static void End(IAsyncResult asyncResult, object tag) {
+            End<AsyncVoid>(asyncResult, tag);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "The Timer will be disposed of either when it fires or when the operation completes successfully.")]
+        private sealed class WrappedAsyncResult<TResult> : IAsyncResult {
+
+            private readonly BeginInvokeDelegate _beginDelegate;
+            private readonly object _beginDelegateLockObj = new object();
+            private readonly EndInvokeDelegate<TResult> _endDelegate;
+            private readonly SingleEntryGate _endExecutedGate = new SingleEntryGate(); // prevent End() from being called twice
+            private readonly SingleEntryGate _handleCallbackGate = new SingleEntryGate(); // prevent callback from being handled multiple times
+            private IAsyncResult _innerAsyncResult;
+            private AsyncCallback _originalCallback;
+            private readonly object _tag; // prevent an instance of this type from being passed to the wrong End() method
+            private volatile bool _timedOut;
+            private Timer _timer;
+
+            public WrappedAsyncResult(BeginInvokeDelegate beginDelegate, EndInvokeDelegate<TResult> endDelegate, object tag) {
+                _beginDelegate = beginDelegate;
+                _endDelegate = endDelegate;
+                _tag = tag;
+            }
+
+            public object AsyncState {
+                get {
+                    return _innerAsyncResult.AsyncState;
+                }
+            }
+
+            public WaitHandle AsyncWaitHandle {
+                get {
+                    return _innerAsyncResult.AsyncWaitHandle;
+                }
+            }
+
+            public bool CompletedSynchronously {
+                get {
+                    return _innerAsyncResult.CompletedSynchronously;
+                }
+            }
+
+            public bool IsCompleted {
+                get {
+                    return _innerAsyncResult.IsCompleted;
+                }
+            }
+
+            // kicks off the process, instantiates a timer if requested
+            public void Begin(AsyncCallback callback, object state, int timeout) {
+                _originalCallback = callback;
+                bool completedSynchronously;
+
+                // Force the target Begin() operation to complete before the callback can continue,
+                // since the target operation might perform post-processing of the data.
+                lock (_beginDelegateLockObj) {
+                    _innerAsyncResult = _beginDelegate(HandleAsynchronousCompletion, state);
+
+                    completedSynchronously = _innerAsyncResult.CompletedSynchronously;
+                    if (!completedSynchronously) {
+                        if (timeout > Timeout.Infinite) {
+                            CreateTimer(timeout);
+                        }
+                    }
+                }
+
+                if (completedSynchronously) {
+                    if (callback != null) {
+                        callback(this);
+                    }
+                }
+            }
+
+            public static WrappedAsyncResult<TResult> Cast(IAsyncResult asyncResult, object tag) {
+                if (asyncResult == null) {
+                    throw new ArgumentNullException("asyncResult");
+                }
+
+                WrappedAsyncResult<TResult> castResult = asyncResult as WrappedAsyncResult<TResult>;
+                if (castResult != null && Object.Equals(castResult._tag, tag)) {
+                    return castResult;
+                }
+                else {
+                    throw Error.AsyncCommon_InvalidAsyncResult("asyncResult");
+                }
+            }
+
+            private void CreateTimer(int timeout) {
+                // this method should be called within a lock(_beginDelegateLockObj)
+                _timer = new Timer(HandleTimeout, null, timeout, Timeout.Infinite /* disable periodic signaling */);
+            }
+
+            public TResult End() {
+                if (!_endExecutedGate.TryEnter()) {
+                    throw Error.AsyncCommon_AsyncResultAlreadyConsumed();
+                }
+
+                if (_timedOut) {
+                    throw new TimeoutException();
+                }
+                WaitForBeginToCompleteAndDestroyTimer();
+
+                return _endDelegate(_innerAsyncResult);
+            }
+
+            private void ExecuteAsynchronousCallback(bool timedOut) {
+                WaitForBeginToCompleteAndDestroyTimer();
+
+                if (_handleCallbackGate.TryEnter()) {
+                    _timedOut = timedOut;
+                    if (_originalCallback != null) {
+                        _originalCallback(this);
+                    }
+                }
+            }
+
+            private void HandleAsynchronousCompletion(IAsyncResult asyncResult) {
+                if (asyncResult.CompletedSynchronously) {
+                    // If the operation completed synchronously, the WrappedAsyncResult.Begin() method will handle it.
+                    return;
+                }
+
+                ExecuteAsynchronousCallback(false /* timedOut */);
+            }
+
+            private void HandleTimeout(object state) {
+                ExecuteAsynchronousCallback(true /* timedOut */);
+            }
+
+            private void WaitForBeginToCompleteAndDestroyTimer() {
+                lock (_beginDelegateLockObj) {
+                    // Wait for the target Begin() method to complete, as it might be performing
+                    // post-processing. This also forces a memory barrier, so _innerAsyncResult
+                    // is guaranteed to be non-null at this point.
+
+                    if (_timer != null) {
+                        _timer.Dispose();
+                    }
+                    _timer = null;
+                }
+            }
+
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Async/AsyncUtil.cs b/mcs/class/System.Web.Mvc3/Mvc/Async/AsyncUtil.cs
new file mode 100644 (file)
index 0000000..3984cdf
--- /dev/null
@@ -0,0 +1,63 @@
+namespace System.Web.Mvc.Async {
+    using System;
+    using System.Threading;
+
+    internal static class AsyncUtil {
+
+        public static void WaitForAsyncResultCompletion(IAsyncResult asyncResult, HttpApplication app) {
+            // based on HttpServerUtility.ExecuteInternal()
+
+            if (!asyncResult.IsCompleted) {
+                // suspend app lock while waiting, else might deadlock
+                bool needToRelock = false;
+
+                try {
+                    // .NET 2.0+ will not allow a ThreadAbortException to be thrown while a
+                    // thread is inside a finally block, so this pattern ensures that the
+                    // value of 'needToRelock' is correct.
+                    try { }
+                    finally {
+                        Monitor.Exit(app);
+                        needToRelock = true;
+                    }
+
+                    WaitHandle waitHandle = asyncResult.AsyncWaitHandle;
+
+                    if (waitHandle != null) {
+                        waitHandle.WaitOne();
+                    }
+                    else {
+                        while (!asyncResult.IsCompleted) {
+                            Thread.Sleep(1);
+                        }
+                    }
+                }
+                finally {
+                    if (needToRelock) {
+                        Monitor.Enter(app);
+                    }
+                }
+            }
+        }
+
+        public static AsyncCallback WrapCallbackForSynchronizedExecution(AsyncCallback callback, SynchronizationContext syncContext) {
+            if (callback == null || syncContext == null) {
+                return callback;
+            }
+
+            AsyncCallback newCallback = delegate(IAsyncResult asyncResult) {
+                if (asyncResult.CompletedSynchronously) {
+                    callback(asyncResult);
+                }
+                else {
+                    // Only take the application lock if this request completed asynchronously,
+                    // else we might end up in a deadlock situation.
+                    syncContext.Sync(() => callback(asyncResult));
+                }
+            };
+
+            return newCallback;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Async/AsyncVoid.cs b/mcs/class/System.Web.Mvc3/Mvc/Async/AsyncVoid.cs
new file mode 100644 (file)
index 0000000..feaf6a5
--- /dev/null
@@ -0,0 +1,7 @@
+namespace System.Web.Mvc.Async {
+    using System;
+
+    // Dummy type used for passing something resembling 'void' to the async delegate functions
+    internal struct AsyncVoid {
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Async/BeginInvokeDelegate.cs b/mcs/class/System.Web.Mvc3/Mvc/Async/BeginInvokeDelegate.cs
new file mode 100644 (file)
index 0000000..a3d8a42
--- /dev/null
@@ -0,0 +1,5 @@
+namespace System.Web.Mvc.Async {
+    using System;
+
+    internal delegate IAsyncResult BeginInvokeDelegate(AsyncCallback callback, object state);
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Async/EndInvokeDelegate.cs b/mcs/class/System.Web.Mvc3/Mvc/Async/EndInvokeDelegate.cs
new file mode 100644 (file)
index 0000000..edff357
--- /dev/null
@@ -0,0 +1,5 @@
+namespace System.Web.Mvc.Async {
+    using System;
+
+    internal delegate void EndInvokeDelegate(IAsyncResult asyncResult);
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Async/EndInvokeDelegate`1.cs b/mcs/class/System.Web.Mvc3/Mvc/Async/EndInvokeDelegate`1.cs
new file mode 100644 (file)
index 0000000..6ec804d
--- /dev/null
@@ -0,0 +1,5 @@
+namespace System.Web.Mvc.Async {
+    using System;
+
+    internal delegate TResult EndInvokeDelegate<TResult>(IAsyncResult asyncResult);
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Async/IAsyncActionInvoker.cs b/mcs/class/System.Web.Mvc3/Mvc/Async/IAsyncActionInvoker.cs
new file mode 100644 (file)
index 0000000..cafed24
--- /dev/null
@@ -0,0 +1,8 @@
+namespace System.Web.Mvc.Async {
+    using System;
+
+    public interface IAsyncActionInvoker : IActionInvoker {
+        IAsyncResult BeginInvokeAction(ControllerContext controllerContext, string actionName, AsyncCallback callback, object state);
+        bool EndInvokeAction(IAsyncResult asyncResult);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Async/IAsyncController.cs b/mcs/class/System.Web.Mvc3/Mvc/Async/IAsyncController.cs
new file mode 100644 (file)
index 0000000..35ad868
--- /dev/null
@@ -0,0 +1,8 @@
+namespace System.Web.Mvc.Async {
+    using System.Web.Routing;
+
+    public interface IAsyncController : IController {
+        IAsyncResult BeginExecute(RequestContext requestContext, AsyncCallback callback, object state);
+        void EndExecute(IAsyncResult asyncResult);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Async/IAsyncManagerContainer.cs b/mcs/class/System.Web.Mvc3/Mvc/Async/IAsyncManagerContainer.cs
new file mode 100644 (file)
index 0000000..4547f32
--- /dev/null
@@ -0,0 +1,10 @@
+namespace System.Web.Mvc.Async {
+
+    public interface IAsyncManagerContainer {
+
+        AsyncManager AsyncManager {
+            get;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Async/OperationCounter.cs b/mcs/class/System.Web.Mvc3/Mvc/Async/OperationCounter.cs
new file mode 100644 (file)
index 0000000..5c8e5e5
--- /dev/null
@@ -0,0 +1,50 @@
+namespace System.Web.Mvc.Async {
+    using System;
+    using System.Threading;
+
+    public sealed class OperationCounter {
+
+        private int _count;
+
+        public int Count {
+            get {
+                return Thread.VolatileRead(ref _count);
+            }
+        }
+
+        public event EventHandler Completed;
+
+        private int AddAndExecuteCallbackIfCompleted(int value) {
+            int newCount = Interlocked.Add(ref _count, value);
+            if (newCount == 0) {
+                OnCompleted();
+            }
+
+            return newCount;
+        }
+
+        public int Decrement() {
+            return AddAndExecuteCallbackIfCompleted(-1);
+        }
+
+        public int Decrement(int value) {
+            return AddAndExecuteCallbackIfCompleted(-value);
+        }
+
+        public int Increment() {
+            return AddAndExecuteCallbackIfCompleted(1);
+        }
+
+        public int Increment(int value) {
+            return AddAndExecuteCallbackIfCompleted(value);
+        }
+
+        private void OnCompleted() {
+            EventHandler handler = Completed;
+            if (handler != null) {
+                handler(this, EventArgs.Empty);
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Async/ReflectedAsyncActionDescriptor.cs b/mcs/class/System.Web.Mvc3/Mvc/Async/ReflectedAsyncActionDescriptor.cs
new file mode 100644 (file)
index 0000000..2523cac
--- /dev/null
@@ -0,0 +1,185 @@
+namespace System.Web.Mvc.Async {
+    using System;
+    using System.Collections.Generic;
+    using System.Linq;
+    using System.Reflection;
+    using System.Threading;
+
+    public class ReflectedAsyncActionDescriptor : AsyncActionDescriptor {
+
+        private readonly object _executeTag = new object();
+
+        private readonly string _actionName;
+        private readonly ControllerDescriptor _controllerDescriptor;
+        private ParameterDescriptor[] _parametersCache;
+        private readonly Lazy<string> _uniqueId;
+
+        public ReflectedAsyncActionDescriptor(MethodInfo asyncMethodInfo, MethodInfo completedMethodInfo, string actionName, ControllerDescriptor controllerDescriptor)
+            : this(asyncMethodInfo, completedMethodInfo, actionName, controllerDescriptor, true /* validateMethods */) {
+        }
+
+        internal ReflectedAsyncActionDescriptor(MethodInfo asyncMethodInfo, MethodInfo completedMethodInfo, string actionName, ControllerDescriptor controllerDescriptor, bool validateMethods) {
+            if (asyncMethodInfo == null) {
+                throw new ArgumentNullException("asyncMethodInfo");
+            }
+            if (completedMethodInfo == null) {
+                throw new ArgumentNullException("completedMethodInfo");
+            }
+            if (String.IsNullOrEmpty(actionName)) {
+                throw Error.ParameterCannotBeNullOrEmpty("actionName");
+            }
+            if (controllerDescriptor == null) {
+                throw new ArgumentNullException("controllerDescriptor");
+            }
+
+            if (validateMethods) {
+                string asyncFailedMessage = VerifyActionMethodIsCallable(asyncMethodInfo);
+                if (asyncFailedMessage != null) {
+                    throw new ArgumentException(asyncFailedMessage, "asyncMethodInfo");
+                }
+
+                string completedFailedMessage = VerifyActionMethodIsCallable(completedMethodInfo);
+                if (completedFailedMessage != null) {
+                    throw new ArgumentException(completedFailedMessage, "completedMethodInfo");
+                }
+            }
+
+            AsyncMethodInfo = asyncMethodInfo;
+            CompletedMethodInfo = completedMethodInfo;
+            _actionName = actionName;
+            _controllerDescriptor = controllerDescriptor;
+            _uniqueId = new Lazy<string>(CreateUniqueId);
+        }
+
+        public override string ActionName {
+            get {
+                return _actionName;
+            }
+        }
+
+        public MethodInfo AsyncMethodInfo {
+            get;
+            private set;
+        }
+
+        public MethodInfo CompletedMethodInfo {
+            get;
+            private set;
+        }
+
+        public override ControllerDescriptor ControllerDescriptor {
+            get {
+                return _controllerDescriptor;
+            }
+        }
+
+        public override string UniqueId {
+            get {
+                return _uniqueId.Value;
+            }
+        }
+
+        public override IAsyncResult BeginExecute(ControllerContext controllerContext, IDictionary<string, object> parameters, AsyncCallback callback, object state) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+            if (parameters == null) {
+                throw new ArgumentNullException("parameters");
+            }
+
+            AsyncManager asyncManager = GetAsyncManager(controllerContext.Controller);
+
+            BeginInvokeDelegate beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState) {
+                // call the XxxAsync() method
+                ParameterInfo[] parameterInfos = AsyncMethodInfo.GetParameters();
+                var rawParameterValues = from parameterInfo in parameterInfos
+                                         select ExtractParameterFromDictionary(parameterInfo, parameters, AsyncMethodInfo);
+                object[] parametersArray = rawParameterValues.ToArray();
+
+                TriggerListener listener = new TriggerListener();
+                SimpleAsyncResult asyncResult = new SimpleAsyncResult(asyncState);
+
+                // hook the Finished event to notify us upon completion
+                Trigger finishTrigger = listener.CreateTrigger();
+                asyncManager.Finished += delegate { finishTrigger.Fire(); };
+                asyncManager.OutstandingOperations.Increment();
+
+                // to simplify the logic, force the rest of the pipeline to execute in an asynchronous callback
+                listener.SetContinuation(() => ThreadPool.QueueUserWorkItem(_ => asyncResult.MarkCompleted(false /* completedSynchronously */, asyncCallback)));
+
+                // the inner operation might complete synchronously, so all setup work has to be done before this point
+                ActionMethodDispatcher dispatcher = DispatcherCache.GetDispatcher(AsyncMethodInfo);
+                dispatcher.Execute(controllerContext.Controller, parametersArray); // ignore return value from this method
+
+                // now that the XxxAsync() method has completed, kick off any pending operations
+                asyncManager.OutstandingOperations.Decrement();
+                listener.Activate();
+                return asyncResult;
+            };
+
+            EndInvokeDelegate<object> endDelegate = delegate(IAsyncResult asyncResult) {
+                // call the XxxCompleted() method
+                ParameterInfo[] completionParametersInfos = CompletedMethodInfo.GetParameters();
+                var rawCompletionParameterValues = from parameterInfo in completionParametersInfos
+                                                   select ExtractParameterOrDefaultFromDictionary(parameterInfo, asyncManager.Parameters);
+                object[] completionParametersArray = rawCompletionParameterValues.ToArray();
+
+                ActionMethodDispatcher dispatcher = DispatcherCache.GetDispatcher(CompletedMethodInfo);
+                object actionReturnValue = dispatcher.Execute(controllerContext.Controller, completionParametersArray);
+                return actionReturnValue;
+            };
+
+            return AsyncResultWrapper.Begin(callback, state, beginDelegate, endDelegate, _executeTag, asyncManager.Timeout);
+        }
+
+        private string CreateUniqueId() {
+            return base.UniqueId + DescriptorUtil.CreateUniqueId(AsyncMethodInfo, CompletedMethodInfo);
+        }
+
+        public override object EndExecute(IAsyncResult asyncResult) {
+            return AsyncResultWrapper.End<object>(asyncResult, _executeTag);
+        }
+
+        public override object[] GetCustomAttributes(bool inherit) {
+            return AsyncMethodInfo.GetCustomAttributes(inherit);
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit) {
+            return AsyncMethodInfo.GetCustomAttributes(attributeType, inherit);
+        }
+
+        internal override IEnumerable<FilterAttribute> GetFilterAttributes(bool useCache) {
+            if (useCache && GetType() == typeof(ReflectedAsyncActionDescriptor)) {
+                // Do not look at cache in types derived from this type because they might incorrectly implement GetCustomAttributes
+                return ReflectedAttributeCache.GetMethodFilterAttributes(AsyncMethodInfo);
+            }
+            return base.GetFilterAttributes(useCache);
+        }
+
+        public override ParameterDescriptor[] GetParameters() {
+            ParameterDescriptor[] parameters = LazilyFetchParametersCollection();
+
+            // need to clone array so that user modifications aren't accidentally stored
+            return (ParameterDescriptor[])parameters.Clone();
+        }
+
+        public override ICollection<ActionSelector> GetSelectors() {
+            // By default, we only look at filters on the XxxAsync() method.
+
+            ActionMethodSelectorAttribute[] attrs = (ActionMethodSelectorAttribute[])AsyncMethodInfo.GetCustomAttributes(typeof(ActionMethodSelectorAttribute), true /* inherit */);
+            ActionSelector[] selectors = Array.ConvertAll(attrs, attr => (ActionSelector)(controllerContext => attr.IsValidForRequest(controllerContext, AsyncMethodInfo)));
+            return selectors;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit) {
+            return AsyncMethodInfo.IsDefined(attributeType, inherit);
+        }
+
+        private ParameterDescriptor[] LazilyFetchParametersCollection() {
+            return DescriptorUtil.LazilyFetchOrCreateDescriptors<ParameterInfo, ParameterDescriptor>(
+                ref _parametersCache /* cacheLocation */,
+                AsyncMethodInfo.GetParameters /* initializer */,
+                parameterInfo => new ReflectedParameterDescriptor(parameterInfo, this) /* converter */);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Async/ReflectedAsyncControllerDescriptor.cs b/mcs/class/System.Web.Mvc3/Mvc/Async/ReflectedAsyncControllerDescriptor.cs
new file mode 100644 (file)
index 0000000..e1b6ef0
--- /dev/null
@@ -0,0 +1,69 @@
+namespace System.Web.Mvc.Async {
+    using System;
+    using System.Collections.Generic;
+
+    public class ReflectedAsyncControllerDescriptor : ControllerDescriptor {
+
+        private static readonly ActionDescriptor[] _emptyCanonicalActions = new ActionDescriptor[0];
+
+        private readonly Type _controllerType;
+        private readonly AsyncActionMethodSelector _selector;
+
+        public ReflectedAsyncControllerDescriptor(Type controllerType) {
+            if (controllerType == null) {
+                throw new ArgumentNullException("controllerType");
+            }
+
+            _controllerType = controllerType;
+            _selector = new AsyncActionMethodSelector(_controllerType);
+        }
+
+        public sealed override Type ControllerType {
+            get {
+                return _controllerType;
+            }
+        }
+
+        public override ActionDescriptor FindAction(ControllerContext controllerContext, string actionName) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+            if (String.IsNullOrEmpty(actionName)) {
+                throw Error.ParameterCannotBeNullOrEmpty("actionName");
+            }
+
+            ActionDescriptorCreator creator = _selector.FindAction(controllerContext, actionName);
+            if (creator == null) {
+                return null;
+            }
+
+            return creator(actionName, this);
+        }
+
+        public override ActionDescriptor[] GetCanonicalActions() {
+            // everything is looked up dymanically, so there are no 'canonical' actions
+            return _emptyCanonicalActions;
+        }
+
+        public override object[] GetCustomAttributes(bool inherit) {
+            return ControllerType.GetCustomAttributes(inherit);
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit) {
+            return ControllerType.GetCustomAttributes(attributeType, inherit);
+        }
+
+        internal override IEnumerable<FilterAttribute> GetFilterAttributes(bool useCache) {
+            if (useCache && GetType() == typeof(ReflectedAsyncControllerDescriptor)) {
+                // Do not look at cache in types derived from this type because they might incorrectly implement GetCustomAttributes
+                return ReflectedAttributeCache.GetTypeFilterAttributes(ControllerType);
+            }
+            return base.GetFilterAttributes(useCache);
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit) {
+            return ControllerType.IsDefined(attributeType, inherit);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Async/SimpleAsyncResult.cs b/mcs/class/System.Web.Mvc3/Mvc/Async/SimpleAsyncResult.cs
new file mode 100644 (file)
index 0000000..fb001d4
--- /dev/null
@@ -0,0 +1,55 @@
+namespace System.Web.Mvc.Async {
+    using System;
+    using System.Threading;
+
+    internal sealed class SimpleAsyncResult : IAsyncResult {
+
+        private readonly object _asyncState;
+        private bool _completedSynchronously;
+        private volatile bool _isCompleted;
+
+        public SimpleAsyncResult(object asyncState) {
+            _asyncState = asyncState;
+        }
+
+        public object AsyncState {
+            get {
+                return _asyncState;
+            }
+        }
+
+        // ASP.NET IAsyncResult objects should never expose a WaitHandle due to potential deadlocking
+        public WaitHandle AsyncWaitHandle {
+            get {
+                return null;
+            }
+        }
+
+        public bool CompletedSynchronously {
+            get {
+                return _completedSynchronously;
+            }
+        }
+
+        public bool IsCompleted {
+            get {
+                return _isCompleted;
+            }
+        }
+
+        // Proper order of execution:
+        // 1. Set the CompletedSynchronously property to the correct value
+        // 2. Set the IsCompleted flag
+        // 3. Execute the callback
+        // 4. Signal the WaitHandle (which we don't have)
+        public void MarkCompleted(bool completedSynchronously, AsyncCallback callback) {
+            _completedSynchronously = completedSynchronously;
+            _isCompleted = true;
+
+            if (callback != null) {
+                callback(this);
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Async/SingleEntryGate.cs b/mcs/class/System.Web.Mvc3/Mvc/Async/SingleEntryGate.cs
new file mode 100644 (file)
index 0000000..3a887c5
--- /dev/null
@@ -0,0 +1,20 @@
+namespace System.Web.Mvc.Async {
+    using System;
+    using System.Threading;
+
+    // used to synchronize access to a single-use consumable resource
+    internal sealed class SingleEntryGate {
+
+        private const int NOT_ENTERED = 0;
+        private const int ENTERED = 1;
+
+        private int _status;
+
+        // returns true if this is the first call to TryEnter(), false otherwise
+        public bool TryEnter() {
+            int oldStatus = Interlocked.Exchange(ref _status, ENTERED);
+            return (oldStatus == NOT_ENTERED);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Async/SynchronizationContextUtil.cs b/mcs/class/System.Web.Mvc3/Mvc/Async/SynchronizationContextUtil.cs
new file mode 100644 (file)
index 0000000..219da92
--- /dev/null
@@ -0,0 +1,47 @@
+namespace System.Web.Mvc.Async {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Threading;
+
+    internal static class SynchronizationContextUtil {
+
+        public static SynchronizationContext GetSynchronizationContext() {
+            // In a runtime environment, SynchronizationContext.Current will be set to an instance
+            // of AspNetSynchronizationContext. In a unit test environment, the Current property
+            // won't be set and we have to create one on the fly.
+            return SynchronizationContext.Current ?? new SynchronizationContext();
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "The exception is swallowed and immediately re-thrown")]
+        public static T Sync<T>(this SynchronizationContext syncContext, Func<T> func) {
+            T theValue = default(T);
+            Exception thrownException = null;
+
+            syncContext.Send(o =>
+            {
+                try {
+                    theValue = func();
+                }
+                catch (Exception ex) {
+                    // by default, the AspNetSynchronizationContext type will swallow thrown exceptions,
+                    // so we need to save and propagate them
+                    thrownException = ex;
+                }
+            }, null);
+
+            if (thrownException != null) {
+                throw Error.SynchronizationContextUtil_ExceptionThrown(thrownException);
+            }
+            return theValue;
+        }
+
+        public static void Sync(this SynchronizationContext syncContext, Action action) {
+            Sync<AsyncVoid>(syncContext, () =>
+            {
+                action();
+                return default(AsyncVoid);
+            });
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Async/SynchronousOperationException.cs b/mcs/class/System.Web.Mvc3/Mvc/Async/SynchronousOperationException.cs
new file mode 100644 (file)
index 0000000..ac590ed
--- /dev/null
@@ -0,0 +1,27 @@
+namespace System.Web.Mvc.Async {
+    using System;
+    using System.Runtime.Serialization;
+
+    // This exception type is thrown by the SynchronizationContextUtil helper class since the AspNetSynchronizationContext
+    // type swallows exceptions. The inner exception contains the data the user cares about.
+
+    [Serializable]
+    public sealed class SynchronousOperationException : HttpException {
+
+        public SynchronousOperationException() {
+        }
+
+        private SynchronousOperationException(SerializationInfo info, StreamingContext context)
+            : base(info, context) {
+        }
+
+        public SynchronousOperationException(string message)
+            : base(message) {
+        }
+
+        public SynchronousOperationException(string message, Exception innerException)
+            : base(message, innerException) {
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Async/Trigger.cs b/mcs/class/System.Web.Mvc3/Mvc/Async/Trigger.cs
new file mode 100644 (file)
index 0000000..6c5b6e1
--- /dev/null
@@ -0,0 +1,21 @@
+namespace System.Web.Mvc.Async {
+    using System;
+    using System.Runtime.Serialization;
+
+    // Provides a trigger for the TriggerListener class.
+
+    internal sealed class Trigger {
+
+        private readonly Action _fireAction;
+
+        // Constructor should only be called by TriggerListener.
+        internal Trigger(Action fireAction) {
+            _fireAction = fireAction;
+        }
+
+        public void Fire() {
+            _fireAction();
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Async/TriggerListener.cs b/mcs/class/System.Web.Mvc3/Mvc/Async/TriggerListener.cs
new file mode 100644 (file)
index 0000000..9f1c624
--- /dev/null
@@ -0,0 +1,56 @@
+namespace System.Web.Mvc.Async {
+    using System;
+    using System.Threading;
+
+    // This class is used to wait for triggers and a continuation. When the continuation has been provded
+    // and all triggers have been fired, the continuation is called. Similar to WaitHandle.WaitAll().
+    // New instances of this type are initially in the inactive state; activation is enabled by a call
+    // to Activate().
+
+    // This class is thread-safe.
+
+    internal sealed class TriggerListener {
+
+        private readonly Trigger _activateTrigger;
+        private volatile Action _continuation;
+        private readonly SingleEntryGate _continuationFiredGate = new SingleEntryGate();
+        private int _outstandingTriggers;
+        private readonly Trigger _setContinuationTrigger;
+
+        public TriggerListener() {
+            _activateTrigger = CreateTrigger();
+            _setContinuationTrigger = CreateTrigger();
+        }
+
+        public void Activate() {
+            _activateTrigger.Fire();
+        }
+
+        public Trigger CreateTrigger() {
+            Interlocked.Increment(ref _outstandingTriggers);
+
+            SingleEntryGate triggerFiredGate = new SingleEntryGate();
+            return new Trigger(() => {
+                if (triggerFiredGate.TryEnter()) {
+                    HandleTriggerFired();
+                }
+            });
+        }
+
+        private void HandleTriggerFired() {
+            if (Interlocked.Decrement(ref _outstandingTriggers) == 0) {
+                if (_continuationFiredGate.TryEnter()) {
+                    _continuation();
+                }
+            }
+        }
+
+        public void SetContinuation(Action continuation) {
+            if (continuation != null) {
+                _continuation = continuation;
+                _setContinuationTrigger.Fire();
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/AsyncController.cs b/mcs/class/System.Web.Mvc3/Mvc/AsyncController.cs
new file mode 100644 (file)
index 0000000..00e5a8b
--- /dev/null
@@ -0,0 +1,99 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Web.Mvc.Async;
+    using System.Web.Routing;
+
+    public abstract class AsyncController : Controller, IAsyncManagerContainer, IAsyncController {
+
+        private static readonly object _executeTag = new object();
+        private static readonly object _executeCoreTag = new object();
+
+        private readonly AsyncManager _asyncManager = new AsyncManager();
+
+        public AsyncManager AsyncManager {
+            get {
+                return _asyncManager;
+            }
+        }
+
+        protected virtual IAsyncResult BeginExecute(RequestContext requestContext, AsyncCallback callback, object state) {
+            if (requestContext == null) {
+                throw new ArgumentNullException("requestContext");
+            }
+
+            VerifyExecuteCalledOnce();
+            Initialize(requestContext);
+            return AsyncResultWrapper.Begin(callback, state, BeginExecuteCore, EndExecuteCore, _executeTag);
+        }
+
+        protected virtual IAsyncResult BeginExecuteCore(AsyncCallback callback, object state) {
+            // If code in this method needs to be updated, please also check the ExecuteCore() method
+            // of Controller to see if that code also must be updated.
+
+            PossiblyLoadTempData();
+            try {
+                string actionName = RouteData.GetRequiredString("action");
+                IActionInvoker invoker = ActionInvoker;
+                IAsyncActionInvoker asyncInvoker = invoker as IAsyncActionInvoker;
+                if (asyncInvoker != null) {
+                    // asynchronous invocation
+                    BeginInvokeDelegate beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState) {
+                        return asyncInvoker.BeginInvokeAction(ControllerContext, actionName, asyncCallback, asyncState);
+                    };
+
+                    EndInvokeDelegate endDelegate = delegate(IAsyncResult asyncResult) {
+                        if (!asyncInvoker.EndInvokeAction(asyncResult)) {
+                            HandleUnknownAction(actionName);
+                        }
+                    };
+
+                    return AsyncResultWrapper.Begin(callback, state, beginDelegate, endDelegate, _executeCoreTag);
+                }
+                else {
+                    // synchronous invocation
+                    Action action = () => {
+                        if (!invoker.InvokeAction(ControllerContext, actionName)) {
+                            HandleUnknownAction(actionName);
+                        }
+                    };
+                    return AsyncResultWrapper.BeginSynchronous(callback, state, action, _executeCoreTag);
+                }
+            }
+            catch {
+                PossiblySaveTempData();
+                throw;
+            }
+        }
+
+        protected override IActionInvoker CreateActionInvoker() {
+            return new AsyncControllerActionInvoker();
+        }
+
+        protected virtual void EndExecute(IAsyncResult asyncResult) {
+            AsyncResultWrapper.End(asyncResult, _executeTag);
+        }
+
+        protected virtual void EndExecuteCore(IAsyncResult asyncResult) {
+            // If code in this method needs to be updated, please also check the ExecuteCore() method
+            // of Controller to see if that code also must be updated.
+
+            try {
+                AsyncResultWrapper.End(asyncResult, _executeCoreTag);
+            }
+            finally {
+                PossiblySaveTempData();
+            }
+        }
+
+        #region IAsyncController Members
+        IAsyncResult IAsyncController.BeginExecute(RequestContext requestContext, AsyncCallback callback, object state) {
+            return BeginExecute(requestContext, callback, state);
+        }
+
+        void IAsyncController.EndExecute(IAsyncResult asyncResult) {
+            EndExecute(asyncResult);
+        }
+        #endregion
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/AsyncTimeoutAttribute.cs b/mcs/class/System.Web.Mvc3/Mvc/AsyncTimeoutAttribute.cs
new file mode 100644 (file)
index 0000000..0ab19ca
--- /dev/null
@@ -0,0 +1,40 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Web.Mvc.Async;
+
+    [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes", Justification = "Unsealed so that subclassed types can set properties in the default constructor.")]
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
+    public class AsyncTimeoutAttribute : ActionFilterAttribute {
+
+        // duration is specified in milliseconds
+        public AsyncTimeoutAttribute(int duration) {
+            if (duration < -1) {
+                throw Error.AsyncCommon_InvalidTimeout("duration");
+            }
+
+            Duration = duration;
+        }
+
+        public int Duration {
+            get;
+            private set;
+        }
+
+        public override void OnActionExecuting(ActionExecutingContext filterContext) {
+            if (filterContext == null) {
+                throw new ArgumentNullException("filterContext");
+            }
+
+            IAsyncManagerContainer container = filterContext.Controller as IAsyncManagerContainer;
+            if (container == null) {
+                throw Error.AsyncCommon_ControllerMustImplementIAsyncManagerContainer(filterContext.Controller.GetType());
+            }
+
+            container.AsyncManager.Timeout = Duration;
+
+            base.OnActionExecuting(filterContext);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/AuthorizationContext.cs b/mcs/class/System.Web.Mvc3/Mvc/AuthorizationContext.cs
new file mode 100644 (file)
index 0000000..8c72e72
--- /dev/null
@@ -0,0 +1,37 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+
+    public class AuthorizationContext : ControllerContext {
+
+        // parameterless constructor used for mocking
+        public AuthorizationContext() {
+        }
+
+        [Obsolete("The recommended alternative is the constructor AuthorizationContext(ControllerContext controllerContext, ActionDescriptor actionDescriptor).")]
+        public AuthorizationContext(ControllerContext controllerContext)
+            : base(controllerContext) {
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", Justification = "The virtual property setters are only to support mocking frameworks, in which case this constructor shouldn't be called anyway.")]
+        public AuthorizationContext(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
+            : base(controllerContext) {
+            if (actionDescriptor == null) {
+                throw new ArgumentNullException("actionDescriptor");
+            }
+
+            ActionDescriptor = actionDescriptor;
+        }
+
+        public virtual ActionDescriptor ActionDescriptor {
+            get;
+            set;
+        }
+
+        public ActionResult Result {
+            get;
+            set;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/AuthorizeAttribute.cs b/mcs/class/System.Web.Mvc3/Mvc/AuthorizeAttribute.cs
new file mode 100644 (file)
index 0000000..1a3cbf9
--- /dev/null
@@ -0,0 +1,131 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq;
+    using System.Security.Principal;
+    using System.Web;
+    using System.Web.Mvc.Resources;
+
+    [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes", Justification = "Unsealed so that subclassed types can set properties in the default constructor or override our behavior.")]
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
+    public class AuthorizeAttribute : FilterAttribute, IAuthorizationFilter {
+
+        private readonly object _typeId = new object();
+
+        private string _roles;
+        private string[] _rolesSplit = new string[0];
+        private string _users;
+        private string[] _usersSplit = new string[0];
+
+        public string Roles {
+            get {
+                return _roles ?? String.Empty;
+            }
+            set {
+                _roles = value;
+                _rolesSplit = SplitString(value);
+            }
+        }
+
+        public override object TypeId {
+            get {
+                return _typeId;
+            }
+        }
+
+        public string Users {
+            get {
+                return _users ?? String.Empty;
+            }
+            set {
+                _users = value;
+                _usersSplit = SplitString(value);
+            }
+        }
+
+        // This method must be thread-safe since it is called by the thread-safe OnCacheAuthorization() method.
+        protected virtual bool AuthorizeCore(HttpContextBase httpContext) {
+            if (httpContext == null) {
+                throw new ArgumentNullException("httpContext");
+            }
+
+            IPrincipal user = httpContext.User;
+            if (!user.Identity.IsAuthenticated) {
+                return false;
+            }
+
+            if (_usersSplit.Length > 0 && !_usersSplit.Contains(user.Identity.Name, StringComparer.OrdinalIgnoreCase)) {
+                return false;
+            }
+
+            if (_rolesSplit.Length > 0 && !_rolesSplit.Any(user.IsInRole)) {
+                return false;
+            }
+
+            return true;
+        }
+
+        private void CacheValidateHandler(HttpContext context, object data, ref HttpValidationStatus validationStatus) {
+            validationStatus = OnCacheAuthorization(new HttpContextWrapper(context));
+        }
+
+        public virtual void OnAuthorization(AuthorizationContext filterContext) {
+            if (filterContext == null) {
+                throw new ArgumentNullException("filterContext");
+            }
+
+            if (OutputCacheAttribute.IsChildActionCacheActive(filterContext)) {
+                // If a child action cache block is active, we need to fail immediately, even if authorization
+                // would have succeeded. The reason is that there's no way to hook a callback to rerun
+                // authorization before the fragment is served from the cache, so we can't guarantee that this
+                // filter will be re-run on subsequent requests.
+                throw new InvalidOperationException(MvcResources.AuthorizeAttribute_CannotUseWithinChildActionCache);
+            }
+
+            if (AuthorizeCore(filterContext.HttpContext)) {
+                // ** IMPORTANT **
+                // Since we're performing authorization at the action level, the authorization code runs
+                // after the output caching module. In the worst case this could allow an authorized user
+                // to cause the page to be cached, then an unauthorized user would later be served the
+                // cached page. We work around this by telling proxies not to cache the sensitive page,
+                // then we hook our custom authorization code into the caching mechanism so that we have
+                // the final say on whether a page should be served from the cache.
+
+                HttpCachePolicyBase cachePolicy = filterContext.HttpContext.Response.Cache;
+                cachePolicy.SetProxyMaxAge(new TimeSpan(0));
+                cachePolicy.AddValidationCallback(CacheValidateHandler, null /* data */);
+            }
+            else {
+                HandleUnauthorizedRequest(filterContext);
+            }
+        }
+
+        protected virtual void HandleUnauthorizedRequest(AuthorizationContext filterContext) {
+            // Returns HTTP 401 - see comment in HttpUnauthorizedResult.cs.
+            filterContext.Result = new HttpUnauthorizedResult();
+        }
+
+        // This method must be thread-safe since it is called by the caching module.
+        protected virtual HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext) {
+            if (httpContext == null) {
+                throw new ArgumentNullException("httpContext");
+            }
+
+            bool isAuthorized = AuthorizeCore(httpContext);
+            return (isAuthorized) ? HttpValidationStatus.Valid : HttpValidationStatus.IgnoreThisRequest;
+        }
+
+        internal static string[] SplitString(string original) {
+            if (String.IsNullOrEmpty(original)) {
+                return new string[0];
+            }
+
+            var split = from piece in original.Split(',')
+                        let trimmed = piece.Trim()
+                        where !String.IsNullOrEmpty(trimmed)
+                        select trimmed;
+            return split.ToArray();
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/BindAttribute.cs b/mcs/class/System.Web.Mvc3/Mvc/BindAttribute.cs
new file mode 100644 (file)
index 0000000..2273cb0
--- /dev/null
@@ -0,0 +1,51 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Linq;
+
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)]
+    public sealed class BindAttribute : Attribute {
+
+        private string _exclude;
+        private string[] _excludeSplit = new string[0];
+        private string _include;
+        private string[] _includeSplit = new string[0];
+
+        public string Exclude {
+            get {
+                return _exclude ?? String.Empty;
+            }
+            set {
+                _exclude = value;
+                _excludeSplit = AuthorizeAttribute.SplitString(value);
+            }
+        }
+
+        public string Include {
+            get {
+                return _include ?? String.Empty;
+            }
+            set {
+                _include = value;
+                _includeSplit = AuthorizeAttribute.SplitString(value);
+            }
+        }
+
+        public string Prefix {
+            get;
+            set;
+        }
+
+        internal static bool IsPropertyAllowed(string propertyName, string[] includeProperties, string[] excludeProperties) {
+            // We allow a property to be bound if its both in the include list AND not in the exclude list.
+            // An empty include list implies all properties are allowed.
+            // An empty exclude list implies no properties are disallowed.
+            bool includeProperty = (includeProperties == null) || (includeProperties.Length == 0) || includeProperties.Contains(propertyName, StringComparer.OrdinalIgnoreCase);
+            bool excludeProperty = (excludeProperties != null) && excludeProperties.Contains(propertyName, StringComparer.OrdinalIgnoreCase);
+            return includeProperty && !excludeProperty;
+        }
+
+        public bool IsPropertyAllowed(string propertyName) {
+            return IsPropertyAllowed(propertyName, _includeSplit, _excludeSplit);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/BuildManagerCompiledView.cs b/mcs/class/System.Web.Mvc3/Mvc/BuildManagerCompiledView.cs
new file mode 100644 (file)
index 0000000..a61e6c8
--- /dev/null
@@ -0,0 +1,78 @@
+namespace System.Web.Mvc {
+    using System.Globalization;
+    using System.IO;
+    using System.Web.Mvc.Resources;
+
+    public abstract class BuildManagerCompiledView : IView {
+        internal IViewPageActivator _viewPageActivator;
+        private IBuildManager _buildManager;
+        private ControllerContext _controllerContext;
+
+        protected BuildManagerCompiledView(ControllerContext controllerContext, string viewPath)
+            : this(controllerContext, viewPath, null) {
+        }
+
+        protected BuildManagerCompiledView(ControllerContext controllerContext, string viewPath, IViewPageActivator viewPageActivator) 
+            :this(controllerContext, viewPath, viewPageActivator, null){
+        }
+
+        internal BuildManagerCompiledView(ControllerContext controllerContext, string viewPath, IViewPageActivator viewPageActivator, IDependencyResolver dependencyResolver){
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+            if (String.IsNullOrEmpty(viewPath)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "viewPath");
+            }
+
+            _controllerContext = controllerContext;
+
+            ViewPath = viewPath;
+
+            _viewPageActivator = viewPageActivator ?? new BuildManagerViewEngine.DefaultViewPageActivator(dependencyResolver);
+        }
+
+        internal IBuildManager BuildManager {
+            get {
+                if (_buildManager == null) {
+                    _buildManager = new BuildManagerWrapper();
+                }
+                return _buildManager;
+            }
+            set {
+                _buildManager = value;
+            }
+        }
+
+        public string ViewPath {
+            get;
+            protected set;
+        }
+
+        public void Render(ViewContext viewContext, TextWriter writer) {
+            if (viewContext == null) {
+                throw new ArgumentNullException("viewContext");
+            }
+
+            object instance = null;
+
+            Type type = BuildManager.GetCompiledType(ViewPath);
+            if (type != null) {
+                instance = _viewPageActivator.Create(_controllerContext, type);
+            }
+
+            if (instance == null) {
+                throw new InvalidOperationException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.CshtmlView_ViewCouldNotBeCreated,
+                        ViewPath
+                    )
+                );
+            }
+
+            RenderView(viewContext, writer, instance);
+        }
+
+        protected abstract void RenderView(ViewContext viewContext, TextWriter writer, object instance);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/BuildManagerViewEngine.cs b/mcs/class/System.Web.Mvc3/Mvc/BuildManagerViewEngine.cs
new file mode 100644 (file)
index 0000000..eb9b8c9
--- /dev/null
@@ -0,0 +1,76 @@
+namespace System.Web.Mvc {
+    using System;
+
+    public abstract class BuildManagerViewEngine : VirtualPathProviderViewEngine {
+        private IBuildManager _buildManager;
+        private IViewPageActivator _viewPageActivator;
+        private IResolver<IViewPageActivator> _activatorResolver;
+
+        protected BuildManagerViewEngine()
+            : this(null, null, null) {
+        }
+
+        protected BuildManagerViewEngine(IViewPageActivator viewPageActivator)
+            : this(viewPageActivator, null, null) {
+        }
+
+        internal BuildManagerViewEngine(IViewPageActivator viewPageActivator, IResolver<IViewPageActivator> activatorResolver, IDependencyResolver dependencyResolver) {
+            if (viewPageActivator != null) {
+                _viewPageActivator = viewPageActivator;
+            }
+            else {
+                _activatorResolver = activatorResolver ?? new SingleServiceResolver<IViewPageActivator>(
+                    () => null,
+                    new DefaultViewPageActivator(dependencyResolver),
+                    "BuildManagerViewEngine constructor"
+                );
+            }
+        }
+
+        internal IBuildManager BuildManager {
+            get {
+                if (_buildManager == null)
+                    _buildManager = new BuildManagerWrapper();
+                return _buildManager;
+            }
+            set {
+                _buildManager = value;
+            }
+        }
+
+        protected override bool FileExists(ControllerContext controllerContext, string virtualPath) {
+            return BuildManager.FileExists(virtualPath);
+        }
+
+        protected IViewPageActivator ViewPageActivator {
+            get {
+                if (_viewPageActivator != null) {
+                    return _viewPageActivator;
+                }
+                _viewPageActivator = _activatorResolver.Current;
+                return _viewPageActivator;
+            }
+        }
+
+        internal class DefaultViewPageActivator : IViewPageActivator {
+            Func<IDependencyResolver> _resolverThunk;
+
+            public DefaultViewPageActivator()
+                : this(null) {
+            }
+
+            public DefaultViewPageActivator(IDependencyResolver resolver) {
+                if (resolver == null) {
+                    _resolverThunk = () => DependencyResolver.Current;
+                }
+                else {
+                    _resolverThunk = () => resolver;
+                }
+            }
+
+            public object Create(ControllerContext controllerContext, Type type) {
+                return _resolverThunk().GetService(type) ?? Activator.CreateInstance(type);
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/BuildManagerWrapper.cs b/mcs/class/System.Web.Mvc3/Mvc/BuildManagerWrapper.cs
new file mode 100644 (file)
index 0000000..c76621a
--- /dev/null
@@ -0,0 +1,27 @@
+namespace System.Web.Mvc {
+    using System.Collections;
+    using System.IO;
+    using System.Web.Compilation;
+
+    internal sealed class BuildManagerWrapper : IBuildManager {
+        bool IBuildManager.FileExists(string virtualPath) {
+            return BuildManager.GetObjectFactory(virtualPath, false) != null;
+        }
+
+        Type IBuildManager.GetCompiledType(string virtualPath) {
+            return BuildManager.GetCompiledType(virtualPath);
+        }
+
+        ICollection IBuildManager.GetReferencedAssemblies() {
+            return BuildManager.GetReferencedAssemblies();
+        }
+
+        Stream IBuildManager.ReadCachedFile(string fileName) {
+            return BuildManager.ReadCachedFile(fileName);
+        }
+
+        Stream IBuildManager.CreateCachedFile(string fileName) {
+            return BuildManager.CreateCachedFile(fileName);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ByteArrayModelBinder.cs b/mcs/class/System.Web.Mvc3/Mvc/ByteArrayModelBinder.cs
new file mode 100644 (file)
index 0000000..e9ea70a
--- /dev/null
@@ -0,0 +1,31 @@
+namespace System.Web.Mvc {
+    using System;
+
+    public class ByteArrayModelBinder : IModelBinder {
+        public virtual object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {
+            if (bindingContext == null) {
+                throw new ArgumentNullException("bindingContext");
+            }
+
+            ValueProviderResult valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
+
+            // case 1: there was no <input ... /> element containing this data
+            if (valueResult == null) {
+                return null;
+            }
+
+            string value = valueResult.AttemptedValue;
+
+            // case 2: there was an <input ... /> element but it was left blank
+            if (String.IsNullOrEmpty(value)) {
+                return null;
+            }
+
+            // Future proofing. If the byte array is actually an instance of System.Data.Linq.Binary
+            // then we need to remove these quotes put in place by the ToString() method.
+            string realValue = value.Replace("\"", String.Empty);
+            return Convert.FromBase64String(realValue);
+        }
+    }
+
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ChildActionOnlyAttribute.cs b/mcs/class/System.Web.Mvc3/Mvc/ChildActionOnlyAttribute.cs
new file mode 100644 (file)
index 0000000..509004b
--- /dev/null
@@ -0,0 +1,18 @@
+namespace System.Web.Mvc {
+    using System;
+
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
+    public sealed class ChildActionOnlyAttribute : FilterAttribute, IAuthorizationFilter {
+
+        public void OnAuthorization(AuthorizationContext filterContext) {
+            if (filterContext == null) {
+                throw new ArgumentNullException("filterContext");
+            }
+
+            if (!filterContext.IsChildAction) {
+                throw Error.ChildActionOnlyAttribute_MustBeInChildRequest(filterContext.ActionDescriptor);
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ChildActionValueProvider.cs b/mcs/class/System.Web.Mvc3/Mvc/ChildActionValueProvider.cs
new file mode 100644 (file)
index 0000000..fe8bb95
--- /dev/null
@@ -0,0 +1,35 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Globalization;
+
+    public sealed class ChildActionValueProvider : DictionaryValueProvider<object> {
+
+        public ChildActionValueProvider(ControllerContext controllerContext)
+            : base(controllerContext.RouteData.Values, CultureInfo.InvariantCulture) {
+        }
+
+        private static string _childActionValuesKey = Guid.NewGuid().ToString();
+
+        internal static string ChildActionValuesKey {
+            get {
+                return _childActionValuesKey;
+            }
+        }
+
+        public override ValueProviderResult GetValue(string key) {
+            if (key == null) {
+                throw new ArgumentNullException("key");
+            }
+
+            ValueProviderResult explicitValues = base.GetValue(ChildActionValuesKey);
+            if (explicitValues != null) {
+                DictionaryValueProvider<object> rawExplicitValues = explicitValues.RawValue as DictionaryValueProvider<object>;
+                if (rawExplicitValues != null) {
+                    return rawExplicitValues.GetValue(key);
+                }
+            }
+
+            return null;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ChildActionValueProviderFactory.cs b/mcs/class/System.Web.Mvc3/Mvc/ChildActionValueProviderFactory.cs
new file mode 100644 (file)
index 0000000..6a56f2f
--- /dev/null
@@ -0,0 +1,14 @@
+namespace System.Web.Mvc {
+    using System;
+
+    public sealed class ChildActionValueProviderFactory: ValueProviderFactory {
+
+        public override IValueProvider GetValueProvider(ControllerContext controllerContext) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+
+            return new ChildActionValueProvider(controllerContext);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ClientDataTypeModelValidatorProvider.cs b/mcs/class/System.Web.Mvc3/Mvc/ClientDataTypeModelValidatorProvider.cs
new file mode 100644 (file)
index 0000000..1a40dfe
--- /dev/null
@@ -0,0 +1,67 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Globalization;
+    using System.Linq;
+    using System.Web.Mvc.Resources;
+
+    public class ClientDataTypeModelValidatorProvider : ModelValidatorProvider {
+
+        private static readonly HashSet<Type> _numericTypes = new HashSet<Type>(new Type[] {
+            typeof(byte), typeof(sbyte),
+            typeof(short), typeof(ushort),
+            typeof(int), typeof(uint),
+            typeof(long), typeof(ulong),
+            typeof(float), typeof(double), typeof(decimal)
+        });
+
+        public override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context) {
+            if (metadata == null) {
+                throw new ArgumentNullException("metadata");
+            }
+            if (context == null) {
+                throw new ArgumentNullException("context");
+            }
+
+            return GetValidatorsImpl(metadata, context);
+        }
+
+        private static IEnumerable<ModelValidator> GetValidatorsImpl(ModelMetadata metadata, ControllerContext context) {
+            Type type = metadata.ModelType;
+            if (IsNumericType(type)) {
+                yield return new NumericModelValidator(metadata, context);
+            }
+        }
+
+        private static bool IsNumericType(Type type) {
+            Type underlyingType = Nullable.GetUnderlyingType(type); // strip off the Nullable<>
+            return _numericTypes.Contains(underlyingType ?? type);
+        }
+
+        internal sealed class NumericModelValidator : ModelValidator {
+            public NumericModelValidator(ModelMetadata metadata, ControllerContext controllerContext)
+                : base(metadata, controllerContext) {
+            }
+
+            public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() {
+                ModelClientValidationRule rule = new ModelClientValidationRule() {
+                    ValidationType = "number",
+                    ErrorMessage = MakeErrorString(Metadata.GetDisplayName())
+                };
+
+                return new ModelClientValidationRule[] { rule };
+            }
+
+            private static string MakeErrorString(string displayName) {
+                // use CurrentCulture since this message is intended for the site visitor
+                return String.Format(CultureInfo.CurrentCulture, MvcResources.ClientDataTypeModelValidatorProvider_FieldMustBeNumeric, displayName);
+            }
+
+            public override IEnumerable<ModelValidationResult> Validate(object container) {
+                // this is not a server-side validator
+                return Enumerable.Empty<ModelValidationResult>();
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/CompareAttribute.cs b/mcs/class/System.Web.Mvc3/Mvc/CompareAttribute.cs
new file mode 100644 (file)
index 0000000..ae5f63b
--- /dev/null
@@ -0,0 +1,52 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.ComponentModel.DataAnnotations;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Reflection;
+    using System.Web.Mvc.Resources;
+
+    [AttributeUsage(AttributeTargets.Property)]
+    [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes", Justification = "This attribute is designed to be a base class for other attributes.")]
+    public class CompareAttribute : ValidationAttribute, IClientValidatable {
+
+        public CompareAttribute(string otherProperty)
+            : base(MvcResources.CompareAttribute_MustMatch) {
+            if (otherProperty == null) {
+                throw new ArgumentNullException("otherProperty");
+            }
+            OtherProperty = otherProperty;
+        }
+
+        public string OtherProperty { get; private set; }
+
+        public override string FormatErrorMessage(string name) {
+            return String.Format(CultureInfo.CurrentCulture, ErrorMessageString, name, OtherProperty);
+        }
+
+        protected override ValidationResult IsValid(object value, ValidationContext validationContext) {
+            PropertyInfo otherPropertyInfo = validationContext.ObjectType.GetProperty(OtherProperty);
+            if (otherPropertyInfo == null) {
+                return new ValidationResult(String.Format(CultureInfo.CurrentCulture, MvcResources.CompareAttribute_UnknownProperty, OtherProperty));
+            }
+
+            object otherPropertyValue = otherPropertyInfo.GetValue(validationContext.ObjectInstance, null);
+            if (!Equals(value, otherPropertyValue)) {
+                return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
+            }
+            return null;
+        }
+
+        public static string FormatPropertyForClientValidation(string property) {
+            if (property == null) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "property");
+            }
+            return "*." + property;
+        }
+
+        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) {
+            yield return new ModelClientValidationEqualToRule(FormatErrorMessage(metadata.GetDisplayName()), FormatPropertyForClientValidation(OtherProperty));
+        }
+    }
+}
\ No newline at end of file
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ContentResult.cs b/mcs/class/System.Web.Mvc3/Mvc/ContentResult.cs
new file mode 100644 (file)
index 0000000..7cdce03
--- /dev/null
@@ -0,0 +1,41 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Text;
+    using System.Web;
+
+    public class ContentResult : ActionResult {
+
+        public string Content {
+            get;
+            set;
+        }
+
+        public Encoding ContentEncoding {
+            get;
+            set;
+        }
+
+        public string ContentType {
+            get;
+            set;
+        }
+
+        public override void ExecuteResult(ControllerContext context) {
+            if (context == null) {
+                throw new ArgumentNullException("context");
+            }
+
+            HttpResponseBase response = context.HttpContext.Response;
+
+            if (!String.IsNullOrEmpty(ContentType)) {
+                response.ContentType = ContentType;
+            }
+            if (ContentEncoding != null) {
+                response.ContentEncoding = ContentEncoding;
+            }
+            if (Content != null) {
+                response.Write(Content);
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Controller.cs b/mcs/class/System.Web.Mvc3/Mvc/Controller.cs
new file mode 100644 (file)
index 0000000..3370cae
--- /dev/null
@@ -0,0 +1,645 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.IO;
+    using System.Security.Principal;
+    using System.Text;
+    using System.Web;
+    using System.Web.Mvc.Resources;
+    using System.Web.Routing;
+
+    public abstract class Controller : ControllerBase, IActionFilter, IAuthorizationFilter, IDisposable, IExceptionFilter, IResultFilter {
+
+        private IActionInvoker _actionInvoker;
+        private ModelBinderDictionary _binders;
+        private RouteCollection _routeCollection;
+        private ITempDataProvider _tempDataProvider;
+
+        public IActionInvoker ActionInvoker {
+            get {
+                if (_actionInvoker == null) {
+                    _actionInvoker = CreateActionInvoker();
+                }
+                return _actionInvoker;
+            }
+            set {
+                _actionInvoker = value;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Property is settable so that the dictionary can be provided for unit testing purposes.")]
+        protected internal ModelBinderDictionary Binders {
+            get {
+                if (_binders == null) {
+                    _binders = ModelBinders.Binders;
+                }
+                return _binders;
+            }
+            set {
+                _binders = value;
+            }
+        }
+
+        public HttpContextBase HttpContext {
+            get {
+                return ControllerContext == null ? null : ControllerContext.HttpContext;
+            }
+        }
+
+        public ModelStateDictionary ModelState {
+            get {
+                return ViewData.ModelState;
+            }
+        }
+
+        public HttpRequestBase Request {
+            get {
+                return HttpContext == null ? null : HttpContext.Request;
+            }
+        }
+
+        public HttpResponseBase Response {
+            get {
+                return HttpContext == null ? null : HttpContext.Response;
+            }
+        }
+
+        internal RouteCollection RouteCollection {
+            get {
+                if (_routeCollection == null) {
+                    _routeCollection = RouteTable.Routes;
+                }
+                return _routeCollection;
+            }
+            set {
+                _routeCollection = value;
+            }
+        }
+
+        public RouteData RouteData {
+            get {
+                return ControllerContext == null ? null : ControllerContext.RouteData;
+            }
+        }
+
+        public HttpServerUtilityBase Server {
+            get {
+                return HttpContext == null ? null : HttpContext.Server;
+            }
+        }
+
+        public HttpSessionStateBase Session {
+            get {
+                return HttpContext == null ? null : HttpContext.Session;
+            }
+        }
+
+        public ITempDataProvider TempDataProvider {
+            get {
+                if (_tempDataProvider == null) {
+                    _tempDataProvider = CreateTempDataProvider();
+                }
+                return _tempDataProvider;
+            }
+            set {
+                _tempDataProvider = value;
+            }
+        }
+
+        public UrlHelper Url {
+            get;
+            set;
+        }
+
+        public IPrincipal User {
+            get {
+                return HttpContext == null ? null : HttpContext.User;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", MessageId = "0#", Justification = "'Content' refers to ContentResult type; 'content' refers to ContentResult.Content property.")]
+        protected internal ContentResult Content(string content) {
+            return Content(content, null /* contentType */);
+        }
+
+        [SuppressMessage("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", MessageId = "0#", Justification = "'Content' refers to ContentResult type; 'content' refers to ContentResult.Content property.")]
+        protected internal ContentResult Content(string content, string contentType) {
+            return Content(content, contentType, null /* contentEncoding */);
+        }
+
+        [SuppressMessage("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", MessageId = "0#", Justification = "'Content' refers to ContentResult type; 'content' refers to ContentResult.Content property.")]
+        protected internal virtual ContentResult Content(string content, string contentType, Encoding contentEncoding) {
+            return new ContentResult {
+                Content = content,
+                ContentType = contentType,
+                ContentEncoding = contentEncoding
+            };
+        }
+
+        protected virtual IActionInvoker CreateActionInvoker() {
+            return new ControllerActionInvoker();
+        }
+
+        protected virtual ITempDataProvider CreateTempDataProvider() {
+            return new SessionStateTempDataProvider();
+        }
+
+        // The default invoker will never match methods defined on the Controller type, so
+        // the Dispose() method is not web-callable.  However, in general, since implicitly-
+        // implemented interface methods are public, they are web-callable unless decorated with
+        // [NonAction].
+        public void Dispose() {
+            Dispose(true /* disposing */);
+            GC.SuppressFinalize(this);
+        }
+
+        protected virtual void Dispose(bool disposing) {
+        }
+
+        protected override void ExecuteCore() {
+            // If code in this method needs to be updated, please also check the BeginExecuteCore() and
+            // EndExecuteCore() methods of AsyncController to see if that code also must be updated.
+
+            PossiblyLoadTempData();
+            try {
+                string actionName = RouteData.GetRequiredString("action");
+                if (!ActionInvoker.InvokeAction(ControllerContext, actionName)) {
+                    HandleUnknownAction(actionName);
+                }
+            }
+            finally {
+                PossiblySaveTempData();
+            }
+        }
+
+        protected internal FileContentResult File(byte[] fileContents, string contentType) {
+            return File(fileContents, contentType, null /* fileDownloadName */);
+        }
+
+        protected internal virtual FileContentResult File(byte[] fileContents, string contentType, string fileDownloadName) {
+            return new FileContentResult(fileContents, contentType) { FileDownloadName = fileDownloadName };
+        }
+
+        protected internal FileStreamResult File(Stream fileStream, string contentType) {
+            return File(fileStream, contentType, null /* fileDownloadName */);
+        }
+
+        protected internal virtual FileStreamResult File(Stream fileStream, string contentType, string fileDownloadName) {
+            return new FileStreamResult(fileStream, contentType) { FileDownloadName = fileDownloadName };
+        }
+
+        protected internal FilePathResult File(string fileName, string contentType) {
+            return File(fileName, contentType, null /* fileDownloadName */);
+        }
+
+        protected internal virtual FilePathResult File(string fileName, string contentType, string fileDownloadName) {
+            return new FilePathResult(fileName, contentType) { FileDownloadName = fileDownloadName };
+        }
+
+        protected virtual void HandleUnknownAction(string actionName) {
+            throw new HttpException(404, String.Format(CultureInfo.CurrentCulture,
+                MvcResources.Controller_UnknownAction, actionName, GetType().FullName));
+        }
+
+        protected internal HttpNotFoundResult HttpNotFound() {
+            return HttpNotFound(null);
+        }
+
+        protected internal virtual HttpNotFoundResult HttpNotFound(string statusDescription) {
+            return new HttpNotFoundResult(statusDescription);
+        }
+
+        protected internal virtual JavaScriptResult JavaScript(string script) {
+            return new JavaScriptResult { Script = script };
+        }
+
+        protected internal JsonResult Json(object data) {
+            return Json(data, null /* contentType */, null /* contentEncoding */, JsonRequestBehavior.DenyGet);
+        }
+
+        protected internal JsonResult Json(object data, string contentType) {
+            return Json(data, contentType, null /* contentEncoding */, JsonRequestBehavior.DenyGet);
+        }
+
+        protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding) {
+            return Json(data, contentType, contentEncoding, JsonRequestBehavior.DenyGet);
+        }
+
+        protected internal JsonResult Json(object data, JsonRequestBehavior behavior) {
+            return Json(data, null /* contentType */, null /* contentEncoding */, behavior);
+        }
+
+        protected internal JsonResult Json(object data, string contentType, JsonRequestBehavior behavior) {
+            return Json(data, contentType, null /* contentEncoding */, behavior);
+        }
+
+        protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior) {
+            return new JsonResult {
+                Data = data,
+                ContentType = contentType,
+                ContentEncoding = contentEncoding,
+                JsonRequestBehavior = behavior
+            };
+        }
+
+        protected override void Initialize(RequestContext requestContext) {
+            base.Initialize(requestContext);
+            Url = new UrlHelper(requestContext);
+        }
+
+        protected virtual void OnActionExecuting(ActionExecutingContext filterContext) {
+        }
+
+        protected virtual void OnActionExecuted(ActionExecutedContext filterContext) {
+        }
+
+        protected virtual void OnAuthorization(AuthorizationContext filterContext) {
+        }
+
+        protected virtual void OnException(ExceptionContext filterContext) {
+        }
+
+        protected virtual void OnResultExecuted(ResultExecutedContext filterContext) {
+        }
+
+        protected virtual void OnResultExecuting(ResultExecutingContext filterContext) {
+        }
+
+        protected internal PartialViewResult PartialView() {
+            return PartialView(null /* viewName */, null /* model */);
+        }
+
+        protected internal PartialViewResult PartialView(object model) {
+            return PartialView(null /* viewName */, model);
+        }
+
+        protected internal PartialViewResult PartialView(string viewName) {
+            return PartialView(viewName, null /* model */);
+        }
+
+        protected internal virtual PartialViewResult PartialView(string viewName, object model) {
+            if (model != null) {
+                ViewData.Model = model;
+            }
+
+            return new PartialViewResult {
+                ViewName = viewName,
+                ViewData = ViewData,
+                TempData = TempData
+            };
+        }
+
+        internal void PossiblyLoadTempData() {
+            if (!ControllerContext.IsChildAction) {
+                TempData.Load(ControllerContext, TempDataProvider);
+            }
+        }
+
+        internal void PossiblySaveTempData() {
+            if (!ControllerContext.IsChildAction) {
+                TempData.Save(ControllerContext, TempDataProvider);
+            }
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "0#", Justification = "Response.Redirect() takes its URI as a string parameter.")]
+        protected internal virtual RedirectResult Redirect(string url) {
+            if (String.IsNullOrEmpty(url)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "url");
+            }
+
+            return new RedirectResult(url);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "0#", Justification = "Response.RedirectPermanent() takes its URI as a string parameter.")]
+        protected internal virtual RedirectResult RedirectPermanent(string url) {
+            if (String.IsNullOrEmpty(url)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "url");
+            }
+
+            return new RedirectResult(url, permanent: true);
+        }
+
+        protected internal RedirectToRouteResult RedirectToAction(string actionName) {
+            return RedirectToAction(actionName, (RouteValueDictionary)null);
+        }
+
+        protected internal RedirectToRouteResult RedirectToAction(string actionName, object routeValues) {
+            return RedirectToAction(actionName, new RouteValueDictionary(routeValues));
+        }
+
+        protected internal RedirectToRouteResult RedirectToAction(string actionName, RouteValueDictionary routeValues) {
+            return RedirectToAction(actionName, null /* controllerName */, routeValues);
+        }
+
+        protected internal RedirectToRouteResult RedirectToAction(string actionName, string controllerName) {
+            return RedirectToAction(actionName, controllerName, (RouteValueDictionary)null);
+        }
+
+        protected internal RedirectToRouteResult RedirectToAction(string actionName, string controllerName, object routeValues) {
+            return RedirectToAction(actionName, controllerName, new RouteValueDictionary(routeValues));
+        }
+
+        protected internal virtual RedirectToRouteResult RedirectToAction(string actionName, string controllerName, RouteValueDictionary routeValues) {
+            RouteValueDictionary mergedRouteValues;
+
+            if (RouteData == null) {
+                mergedRouteValues = RouteValuesHelpers.MergeRouteValues(actionName, controllerName, null, routeValues, includeImplicitMvcValues: true);
+            }
+            else {
+                mergedRouteValues = RouteValuesHelpers.MergeRouteValues(actionName, controllerName, RouteData.Values, routeValues, includeImplicitMvcValues: true);
+            }
+
+            return new RedirectToRouteResult(mergedRouteValues);
+        }
+
+        protected internal RedirectToRouteResult RedirectToActionPermanent(string actionName) {
+            return RedirectToActionPermanent(actionName, (RouteValueDictionary)null);
+        }
+
+        protected internal RedirectToRouteResult RedirectToActionPermanent(string actionName, object routeValues) {
+            return RedirectToActionPermanent(actionName, new RouteValueDictionary(routeValues));
+        }
+
+        protected internal RedirectToRouteResult RedirectToActionPermanent(string actionName, RouteValueDictionary routeValues) {
+            return RedirectToActionPermanent(actionName, null /* controllerName */, routeValues);
+        }
+
+        protected internal RedirectToRouteResult RedirectToActionPermanent(string actionName, string controllerName) {
+            return RedirectToActionPermanent(actionName, controllerName, (RouteValueDictionary)null);
+        }
+
+        protected internal RedirectToRouteResult RedirectToActionPermanent(string actionName, string controllerName, object routeValues) {
+            return RedirectToActionPermanent(actionName, controllerName, new RouteValueDictionary(routeValues));
+        }
+
+        protected internal virtual RedirectToRouteResult RedirectToActionPermanent(string actionName, string controllerName, RouteValueDictionary routeValues) {
+            RouteValueDictionary implicitRouteValues = (RouteData != null) ? RouteData.Values : null;
+
+            RouteValueDictionary mergedRouteValues =
+                RouteValuesHelpers.MergeRouteValues(actionName, controllerName, implicitRouteValues, routeValues, includeImplicitMvcValues: true);
+
+            return new RedirectToRouteResult(null, mergedRouteValues, permanent: true);
+        }
+
+        protected internal RedirectToRouteResult RedirectToRoute(object routeValues) {
+            return RedirectToRoute(new RouteValueDictionary(routeValues));
+        }
+
+        protected internal RedirectToRouteResult RedirectToRoute(RouteValueDictionary routeValues) {
+            return RedirectToRoute(null /* routeName */, routeValues);
+        }
+
+        protected internal RedirectToRouteResult RedirectToRoute(string routeName) {
+            return RedirectToRoute(routeName, (RouteValueDictionary)null);
+        }
+
+        protected internal RedirectToRouteResult RedirectToRoute(string routeName, object routeValues) {
+            return RedirectToRoute(routeName, new RouteValueDictionary(routeValues));
+        }
+
+        protected internal virtual RedirectToRouteResult RedirectToRoute(string routeName, RouteValueDictionary routeValues) {
+            return new RedirectToRouteResult(routeName, RouteValuesHelpers.GetRouteValues(routeValues));
+        }
+
+        protected internal RedirectToRouteResult RedirectToRoutePermanent(object routeValues) {
+            return RedirectToRoutePermanent(new RouteValueDictionary(routeValues));
+        }
+
+        protected internal RedirectToRouteResult RedirectToRoutePermanent(RouteValueDictionary routeValues) {
+            return RedirectToRoutePermanent(null /* routeName */, routeValues);
+        }
+
+        protected internal RedirectToRouteResult RedirectToRoutePermanent(string routeName) {
+            return RedirectToRoutePermanent(routeName, (RouteValueDictionary)null);
+        }
+
+        protected internal RedirectToRouteResult RedirectToRoutePermanent(string routeName, object routeValues) {
+            return RedirectToRoutePermanent(routeName, new RouteValueDictionary(routeValues));
+        }
+
+        protected internal virtual RedirectToRouteResult RedirectToRoutePermanent(string routeName, RouteValueDictionary routeValues) {
+            return new RedirectToRouteResult(routeName, RouteValuesHelpers.GetRouteValues(routeValues), permanent: true);
+        }
+
+        protected internal bool TryUpdateModel<TModel>(TModel model) where TModel : class {
+            return TryUpdateModel(model, null, null, null, ValueProvider);
+        }
+
+        protected internal bool TryUpdateModel<TModel>(TModel model, string prefix) where TModel : class {
+            return TryUpdateModel(model, prefix, null, null, ValueProvider);
+        }
+
+        protected internal bool TryUpdateModel<TModel>(TModel model, string[] includeProperties) where TModel : class {
+            return TryUpdateModel(model, null, includeProperties, null, ValueProvider);
+        }
+
+        protected internal bool TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties) where TModel : class {
+            return TryUpdateModel(model, prefix, includeProperties, null, ValueProvider);
+        }
+
+        protected internal bool TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) where TModel : class {
+            return TryUpdateModel(model, prefix, includeProperties, excludeProperties, ValueProvider);
+        }
+
+        protected internal bool TryUpdateModel<TModel>(TModel model, IValueProvider valueProvider) where TModel : class {
+            return TryUpdateModel(model, null, null, null, valueProvider);
+        }
+
+        protected internal bool TryUpdateModel<TModel>(TModel model, string prefix, IValueProvider valueProvider) where TModel : class {
+            return TryUpdateModel(model, prefix, null, null, valueProvider);
+        }
+
+        protected internal bool TryUpdateModel<TModel>(TModel model, string[] includeProperties, IValueProvider valueProvider) where TModel : class {
+            return TryUpdateModel(model, null, includeProperties, null, valueProvider);
+        }
+
+        protected internal bool TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, IValueProvider valueProvider) where TModel : class {
+            return TryUpdateModel(model, prefix, includeProperties, null, valueProvider);
+        }
+
+        protected internal bool TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties, IValueProvider valueProvider) where TModel : class {
+            if (model == null) {
+                throw new ArgumentNullException("model");
+            }
+            if (valueProvider == null) {
+                throw new ArgumentNullException("valueProvider");
+            }
+
+            Predicate<string> propertyFilter = propertyName => BindAttribute.IsPropertyAllowed(propertyName, includeProperties, excludeProperties);
+            IModelBinder binder = Binders.GetBinder(typeof(TModel));
+
+            ModelBindingContext bindingContext = new ModelBindingContext() {
+                ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, typeof(TModel)),
+                ModelName = prefix,
+                ModelState = ModelState,
+                PropertyFilter = propertyFilter,
+                ValueProvider = valueProvider
+            };
+            binder.BindModel(ControllerContext, bindingContext);
+            return ModelState.IsValid;
+        }
+
+        protected internal bool TryValidateModel(object model) {
+            return TryValidateModel(model, null /* prefix */);
+        }
+
+        protected internal bool TryValidateModel(object model, string prefix) {
+            if (model == null) {
+                throw new ArgumentNullException("model");
+            }
+
+            ModelMetadata metadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, model.GetType());
+
+            foreach (ModelValidationResult validationResult in ModelValidator.GetModelValidator(metadata, ControllerContext).Validate(null)) {
+                ModelState.AddModelError(DefaultModelBinder.CreateSubPropertyName(prefix, validationResult.MemberName), validationResult.Message);
+            }
+
+            return ModelState.IsValid;
+        }
+
+        protected internal void UpdateModel<TModel>(TModel model) where TModel : class {
+            UpdateModel(model, null, null, null, ValueProvider);
+        }
+
+        protected internal void UpdateModel<TModel>(TModel model, string prefix) where TModel : class {
+            UpdateModel(model, prefix, null, null, ValueProvider);
+        }
+
+        protected internal void UpdateModel<TModel>(TModel model, string[] includeProperties) where TModel : class {
+            UpdateModel(model, null, includeProperties, null, ValueProvider);
+        }
+
+        protected internal void UpdateModel<TModel>(TModel model, string prefix, string[] includeProperties) where TModel : class {
+            UpdateModel(model, prefix, includeProperties, null, ValueProvider);
+        }
+
+        protected internal void UpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) where TModel : class {
+            UpdateModel(model, prefix, includeProperties, excludeProperties, ValueProvider);
+        }
+
+        protected internal void UpdateModel<TModel>(TModel model, IValueProvider valueProvider) where TModel : class {
+            UpdateModel(model, null, null, null, valueProvider);
+        }
+
+        protected internal void UpdateModel<TModel>(TModel model, string prefix, IValueProvider valueProvider) where TModel : class {
+            UpdateModel(model, prefix, null, null, valueProvider);
+        }
+
+        protected internal void UpdateModel<TModel>(TModel model, string[] includeProperties, IValueProvider valueProvider) where TModel : class {
+            UpdateModel(model, null, includeProperties, null, valueProvider);
+        }
+
+        protected internal void UpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, IValueProvider valueProvider) where TModel : class {
+            UpdateModel(model, prefix, includeProperties, null, valueProvider);
+        }
+
+        protected internal void UpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties, IValueProvider valueProvider) where TModel : class {
+            bool success = TryUpdateModel(model, prefix, includeProperties, excludeProperties, valueProvider);
+            if (!success) {
+                string message = String.Format(CultureInfo.CurrentCulture, MvcResources.Controller_UpdateModel_UpdateUnsuccessful,
+                    typeof(TModel).FullName);
+                throw new InvalidOperationException(message);
+            }
+        }
+
+        protected internal void ValidateModel(object model) {
+            ValidateModel(model, null /* prefix */);
+        }
+
+        protected internal void ValidateModel(object model, string prefix) {
+            if (!TryValidateModel(model, prefix)) {
+                throw new InvalidOperationException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.Controller_Validate_ValidationFailed,
+                        model.GetType().FullName
+                    )
+                );
+            }
+        }
+
+        protected internal ViewResult View() {
+            return View(null /* viewName */, null /* masterName */, null /* model */);
+        }
+
+        protected internal ViewResult View(object model) {
+            return View(null /* viewName */, null /* masterName */, model);
+        }
+
+        protected internal ViewResult View(string viewName) {
+            return View(viewName, null /* masterName */, null /* model */);
+        }
+
+        protected internal ViewResult View(string viewName, string masterName) {
+            return View(viewName, masterName, null /* model */);
+        }
+
+        protected internal ViewResult View(string viewName, object model) {
+            return View(viewName, null /* masterName */, model);
+        }
+
+        protected internal virtual ViewResult View(string viewName, string masterName, object model) {
+            if (model != null) {
+                ViewData.Model = model;
+            }
+
+            return new ViewResult {
+                ViewName = viewName,
+                MasterName = masterName,
+                ViewData = ViewData,
+                TempData = TempData
+            };
+        }
+
+        [SuppressMessage("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", MessageId = "0#", Justification = "The method name 'View' is a convenient shorthand for 'CreateViewResult'.")]
+        protected internal ViewResult View(IView view) {
+            return View(view, null /* model */);
+        }
+
+        [SuppressMessage("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", MessageId = "0#", Justification = "The method name 'View' is a convenient shorthand for 'CreateViewResult'.")]
+        protected internal virtual ViewResult View(IView view, object model) {
+            if (model != null) {
+                ViewData.Model = model;
+            }
+
+            return new ViewResult {
+                View = view,
+                ViewData = ViewData,
+                TempData = TempData
+            };
+        }
+
+        #region IActionFilter Members
+        void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext) {
+            OnActionExecuting(filterContext);
+        }
+
+        void IActionFilter.OnActionExecuted(ActionExecutedContext filterContext) {
+            OnActionExecuted(filterContext);
+        }
+        #endregion
+
+        #region IAuthorizationFilter Members
+        void IAuthorizationFilter.OnAuthorization(AuthorizationContext filterContext) {
+            OnAuthorization(filterContext);
+        }
+        #endregion
+
+        #region IExceptionFilter Members
+        void IExceptionFilter.OnException(ExceptionContext filterContext) {
+            OnException(filterContext);
+        }
+        #endregion
+
+        #region IResultFilter Members
+        void IResultFilter.OnResultExecuting(ResultExecutingContext filterContext) {
+            OnResultExecuting(filterContext);
+        }
+
+        void IResultFilter.OnResultExecuted(ResultExecutedContext filterContext) {
+            OnResultExecuted(filterContext);
+        }
+        #endregion
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ControllerActionInvoker.cs b/mcs/class/System.Web.Mvc3/Mvc/ControllerActionInvoker.cs
new file mode 100644 (file)
index 0000000..f1eb3e7
--- /dev/null
@@ -0,0 +1,313 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Linq;
+    using System.Threading;
+    using System.Web;
+    using System.Web.Mvc.Resources;
+    using Microsoft.Web.Infrastructure.DynamicValidationHelper;
+
+    public class ControllerActionInvoker : IActionInvoker {
+
+        private readonly static ControllerDescriptorCache _staticDescriptorCache = new ControllerDescriptorCache();
+
+        private ModelBinderDictionary _binders;
+        private Func<ControllerContext, ActionDescriptor, IEnumerable<Filter>> _getFiltersThunk = (cc, ad) => FilterProviders.Providers.GetFilters(cc, ad);
+        private ControllerDescriptorCache _instanceDescriptorCache;
+
+        public ControllerActionInvoker() {
+        }
+
+        internal ControllerActionInvoker(params object[] filters)
+            :this() {
+            if (filters != null) {
+                _getFiltersThunk = (cc, ad) => filters.Select(f => new Filter(f, FilterScope.Action, null));
+            }
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Property is settable so that the dictionary can be provided for unit testing purposes.")]
+        protected internal ModelBinderDictionary Binders {
+            get {
+                if (_binders == null) {
+                    _binders = ModelBinders.Binders;
+                }
+                return _binders;
+            }
+            set {
+                _binders = value;
+            }
+        }
+
+        internal ControllerDescriptorCache DescriptorCache {
+            get {
+                if (_instanceDescriptorCache == null) {
+                    _instanceDescriptorCache = _staticDescriptorCache;
+                }
+                return _instanceDescriptorCache;
+            }
+            set {
+                _instanceDescriptorCache = value;
+            }
+        }
+
+        protected virtual ActionResult CreateActionResult(ControllerContext controllerContext, ActionDescriptor actionDescriptor, object actionReturnValue) {
+            if (actionReturnValue == null) {
+                return new EmptyResult();
+            }
+
+            ActionResult actionResult = (actionReturnValue as ActionResult) ??
+                new ContentResult { Content = Convert.ToString(actionReturnValue, CultureInfo.InvariantCulture) };
+            return actionResult;
+        }
+
+        protected virtual ControllerDescriptor GetControllerDescriptor(ControllerContext controllerContext) {
+            Type controllerType = controllerContext.Controller.GetType();
+            ControllerDescriptor controllerDescriptor = DescriptorCache.GetDescriptor(controllerType, () => new ReflectedControllerDescriptor(controllerType));
+            return controllerDescriptor;
+        }
+
+        protected virtual ActionDescriptor FindAction(ControllerContext controllerContext, ControllerDescriptor controllerDescriptor, string actionName) {
+            ActionDescriptor actionDescriptor = controllerDescriptor.FindAction(controllerContext, actionName);
+            return actionDescriptor;
+        }
+
+        protected virtual FilterInfo GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor) {
+            return new FilterInfo(_getFiltersThunk(controllerContext, actionDescriptor));
+        }
+
+        private IModelBinder GetModelBinder(ParameterDescriptor parameterDescriptor) {
+            // look on the parameter itself, then look in the global table
+            return parameterDescriptor.BindingInfo.Binder ?? Binders.GetBinder(parameterDescriptor.ParameterType);
+        }
+
+        protected virtual object GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) {
+            // collect all of the necessary binding properties
+            Type parameterType = parameterDescriptor.ParameterType;
+            IModelBinder binder = GetModelBinder(parameterDescriptor);
+            IValueProvider valueProvider = controllerContext.Controller.ValueProvider;
+            string parameterName = parameterDescriptor.BindingInfo.Prefix ?? parameterDescriptor.ParameterName;
+            Predicate<string> propertyFilter = GetPropertyFilter(parameterDescriptor);
+
+            // finally, call into the binder
+            ModelBindingContext bindingContext = new ModelBindingContext() {
+                FallbackToEmptyPrefix = (parameterDescriptor.BindingInfo.Prefix == null), // only fall back if prefix not specified
+                ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, parameterType),
+                ModelName = parameterName,
+                ModelState = controllerContext.Controller.ViewData.ModelState,
+                PropertyFilter = propertyFilter,
+                ValueProvider = valueProvider
+            };
+
+            object result = binder.BindModel(controllerContext, bindingContext);
+            return result ?? parameterDescriptor.DefaultValue;
+        }
+
+        protected virtual IDictionary<string, object> GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) {
+            Dictionary<string, object> parametersDict = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
+            ParameterDescriptor[] parameterDescriptors = actionDescriptor.GetParameters();
+
+            foreach (ParameterDescriptor parameterDescriptor in parameterDescriptors) {
+                parametersDict[parameterDescriptor.ParameterName] = GetParameterValue(controllerContext, parameterDescriptor);
+            }
+            return parametersDict;
+        }
+
+        private static Predicate<string> GetPropertyFilter(ParameterDescriptor parameterDescriptor) {
+            ParameterBindingInfo bindingInfo = parameterDescriptor.BindingInfo;
+            return propertyName => BindAttribute.IsPropertyAllowed(propertyName, bindingInfo.Include.ToArray(), bindingInfo.Exclude.ToArray());
+        }
+
+        public virtual bool InvokeAction(ControllerContext controllerContext, string actionName) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+            if (String.IsNullOrEmpty(actionName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "actionName");
+            }
+
+            ControllerDescriptor controllerDescriptor = GetControllerDescriptor(controllerContext);
+            ActionDescriptor actionDescriptor = FindAction(controllerContext, controllerDescriptor, actionName);
+            if (actionDescriptor != null) {
+                FilterInfo filterInfo = GetFilters(controllerContext, actionDescriptor);
+
+                try {
+                    AuthorizationContext authContext = InvokeAuthorizationFilters(controllerContext, filterInfo.AuthorizationFilters, actionDescriptor);
+                    if (authContext.Result != null) {
+                        // the auth filter signaled that we should let it short-circuit the request
+                        InvokeActionResult(controllerContext, authContext.Result);
+                    }
+                    else {
+                        if (controllerContext.Controller.ValidateRequest) {
+                            ValidateRequest(controllerContext);
+                        }
+
+                        IDictionary<string, object> parameters = GetParameterValues(controllerContext, actionDescriptor);
+                        ActionExecutedContext postActionContext = InvokeActionMethodWithFilters(controllerContext, filterInfo.ActionFilters, actionDescriptor, parameters);
+                        InvokeActionResultWithFilters(controllerContext, filterInfo.ResultFilters, postActionContext.Result);
+                    }
+                }
+                catch (ThreadAbortException) {
+                    // This type of exception occurs as a result of Response.Redirect(), but we special-case so that
+                    // the filters don't see this as an error.
+                    throw;
+                }
+                catch (Exception ex) {
+                    // something blew up, so execute the exception filters
+                    ExceptionContext exceptionContext = InvokeExceptionFilters(controllerContext, filterInfo.ExceptionFilters, ex);
+                    if (!exceptionContext.ExceptionHandled) {
+                        throw;
+                    }
+                    InvokeActionResult(controllerContext, exceptionContext.Result);
+                }
+
+                return true;
+            }
+
+            // notify controller that no method matched
+            return false;
+        }
+
+        protected virtual ActionResult InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters) {
+            object returnValue = actionDescriptor.Execute(controllerContext, parameters);
+            ActionResult result = CreateActionResult(controllerContext, actionDescriptor, returnValue);
+            return result;
+        }
+
+        internal static ActionExecutedContext InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func<ActionExecutedContext> continuation) {
+            filter.OnActionExecuting(preContext);
+            if (preContext.Result != null) {
+                return new ActionExecutedContext(preContext, preContext.ActionDescriptor, true /* canceled */, null /* exception */) {
+                    Result = preContext.Result
+                };
+            }
+
+            bool wasError = false;
+            ActionExecutedContext postContext = null;
+            try {
+                postContext = continuation();
+            }
+            catch (ThreadAbortException) {
+                // This type of exception occurs as a result of Response.Redirect(), but we special-case so that
+                // the filters don't see this as an error.
+                postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, null /* exception */);
+                filter.OnActionExecuted(postContext);
+                throw;
+            }
+            catch (Exception ex) {
+                wasError = true;
+                postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, ex);
+                filter.OnActionExecuted(postContext);
+                if (!postContext.ExceptionHandled) {
+                    throw;
+                }
+            }
+            if (!wasError) {
+                filter.OnActionExecuted(postContext);
+            }
+            return postContext;
+        }
+
+        protected virtual ActionExecutedContext InvokeActionMethodWithFilters(ControllerContext controllerContext, IList<IActionFilter> filters, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters) {
+            ActionExecutingContext preContext = new ActionExecutingContext(controllerContext, actionDescriptor, parameters);
+            Func<ActionExecutedContext> continuation = () =>
+                new ActionExecutedContext(controllerContext, actionDescriptor, false /* canceled */, null /* exception */) {
+                    Result = InvokeActionMethod(controllerContext, actionDescriptor, parameters)
+                };
+
+            // need to reverse the filter list because the continuations are built up backward
+            Func<ActionExecutedContext> thunk = filters.Reverse().Aggregate(continuation,
+                (next, filter) => () => InvokeActionMethodFilter(filter, preContext, next));
+            return thunk();
+        }
+
+        protected virtual void InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) {
+            actionResult.ExecuteResult(controllerContext);
+        }
+
+        internal static ResultExecutedContext InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func<ResultExecutedContext> continuation) {
+            filter.OnResultExecuting(preContext);
+            if (preContext.Cancel) {
+                return new ResultExecutedContext(preContext, preContext.Result, true /* canceled */, null /* exception */);
+            }
+
+            bool wasError = false;
+            ResultExecutedContext postContext = null;
+            try {
+                postContext = continuation();
+            }
+            catch (ThreadAbortException) {
+                // This type of exception occurs as a result of Response.Redirect(), but we special-case so that
+                // the filters don't see this as an error.
+                postContext = new ResultExecutedContext(preContext, preContext.Result, false /* canceled */, null /* exception */);
+                filter.OnResultExecuted(postContext);
+                throw;
+            }
+            catch (Exception ex) {
+                wasError = true;
+                postContext = new ResultExecutedContext(preContext, preContext.Result, false /* canceled */, ex);
+                filter.OnResultExecuted(postContext);
+                if (!postContext.ExceptionHandled) {
+                    throw;
+                }
+            }
+            if (!wasError) {
+                filter.OnResultExecuted(postContext);
+            }
+            return postContext;
+        }
+
+        protected virtual ResultExecutedContext InvokeActionResultWithFilters(ControllerContext controllerContext, IList<IResultFilter> filters, ActionResult actionResult) {
+            ResultExecutingContext preContext = new ResultExecutingContext(controllerContext, actionResult);
+            Func<ResultExecutedContext> continuation = delegate {
+                InvokeActionResult(controllerContext, actionResult);
+                return new ResultExecutedContext(controllerContext, actionResult, false /* canceled */, null /* exception */);
+            };
+
+            // need to reverse the filter list because the continuations are built up backward
+            Func<ResultExecutedContext> thunk = filters.Reverse().Aggregate(continuation,
+                (next, filter) => () => InvokeActionResultFilter(filter, preContext, next));
+            return thunk();
+        }
+
+        protected virtual AuthorizationContext InvokeAuthorizationFilters(ControllerContext controllerContext, IList<IAuthorizationFilter> filters, ActionDescriptor actionDescriptor) {
+            AuthorizationContext context = new AuthorizationContext(controllerContext, actionDescriptor);
+            foreach (IAuthorizationFilter filter in filters) {
+                filter.OnAuthorization(context);
+                // short-circuit evaluation
+                if (context.Result != null) {
+                    break;
+                }
+            }
+
+            return context;
+        }
+
+        protected virtual ExceptionContext InvokeExceptionFilters(ControllerContext controllerContext, IList<IExceptionFilter> filters, Exception exception) {
+            ExceptionContext context = new ExceptionContext(controllerContext, exception);
+            foreach (IExceptionFilter filter in filters.Reverse()) {
+                filter.OnException(context);
+            }
+
+            return context;
+        }
+
+        internal static void ValidateRequest(ControllerContext controllerContext) {
+            if (controllerContext.IsChildAction) {
+                return;
+            }
+
+            // DevDiv 214040: Enable Request Validation by default for all controller requests
+            // 
+            // Earlier versions of this method dereferenced Request.RawUrl to force validation of
+            // that field. This was necessary for Routing before ASP.NET v4, which read the incoming
+            // path from RawUrl. Request validation has been moved earlier in the pipeline by default and
+            // routing no longer consumes this property, so we don't have to either.
+
+            ValidationUtility.EnableDynamicValidation(HttpContext.Current);
+            controllerContext.HttpContext.Request.ValidateInput();
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ControllerBase.cs b/mcs/class/System.Web.Mvc3/Mvc/ControllerBase.cs
new file mode 100644 (file)
index 0000000..509da4f
--- /dev/null
@@ -0,0 +1,120 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Web.Mvc.Async;
+    using System.Web.Mvc.Resources;
+    using System.Web.Routing;
+    using System.Web.WebPages;
+    using System.Web.WebPages.Scope;
+
+    public abstract class ControllerBase : IController {
+
+        private readonly SingleEntryGate _executeWasCalledGate = new SingleEntryGate();
+
+        private DynamicViewDataDictionary _dynamicViewDataDictionary;
+        private TempDataDictionary _tempDataDictionary;
+        private bool _validateRequest = true;
+        private IValueProvider _valueProvider;
+        private ViewDataDictionary _viewDataDictionary;
+
+        public ControllerContext ControllerContext {
+            get;
+            set;
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "This property is settable so that unit tests can provide mock implementations.")]
+        public TempDataDictionary TempData {
+            get {
+                if (ControllerContext != null && ControllerContext.IsChildAction) {
+                    return ControllerContext.ParentActionViewContext.TempData;
+                }
+                if (_tempDataDictionary == null) {
+                    _tempDataDictionary = new TempDataDictionary();
+                }
+                return _tempDataDictionary;
+            }
+            set {
+                _tempDataDictionary = value;
+            }
+        }
+
+        public bool ValidateRequest {
+            get {
+                return _validateRequest;
+            }
+            set {
+                _validateRequest = value;
+            }
+        }
+
+        public IValueProvider ValueProvider {
+            get {
+                if (_valueProvider == null) {
+                    _valueProvider = ValueProviderFactories.Factories.GetValueProvider(ControllerContext);
+                }
+                return _valueProvider;
+            }
+            set {
+                _valueProvider = value;
+            }
+        }
+
+        public dynamic ViewBag {
+            get {
+                if (_dynamicViewDataDictionary == null) {
+                    _dynamicViewDataDictionary = new DynamicViewDataDictionary(() => ViewData);
+                }
+                return _dynamicViewDataDictionary;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "This property is settable so that unit tests can provide mock implementations.")]
+        public ViewDataDictionary ViewData {
+            get {
+                if (_viewDataDictionary == null) {
+                    _viewDataDictionary = new ViewDataDictionary();
+                }
+                return _viewDataDictionary;
+            }
+            set {
+                _viewDataDictionary = value;
+            }
+        }
+
+        protected virtual void Execute(RequestContext requestContext) {
+            if (requestContext == null) {
+                throw new ArgumentNullException("requestContext");
+            }
+            if (requestContext.HttpContext == null) {
+                throw new ArgumentException(MvcResources.ControllerBase_CannotExecuteWithNullHttpContext, "requestContext");
+            }
+
+            VerifyExecuteCalledOnce();
+            Initialize(requestContext);
+
+            using (ScopeStorage.CreateTransientScope()) {
+                ExecuteCore();
+            }
+        }
+
+        protected abstract void ExecuteCore();
+
+        protected virtual void Initialize(RequestContext requestContext) {
+            ControllerContext = new ControllerContext(requestContext, this);
+        }
+
+        internal void VerifyExecuteCalledOnce() {
+            if (!_executeWasCalledGate.TryEnter()) {
+                string message = String.Format(CultureInfo.CurrentCulture, MvcResources.ControllerBase_CannotHandleMultipleRequests, GetType());
+                throw new InvalidOperationException(message);
+            }
+        }
+
+        #region IController Members
+        void IController.Execute(RequestContext requestContext) {
+            Execute(requestContext);
+        }
+        #endregion
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ControllerBuilder.cs b/mcs/class/System.Web.Mvc3/Mvc/ControllerBuilder.cs
new file mode 100644 (file)
index 0000000..1df29c3
--- /dev/null
@@ -0,0 +1,81 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Web.Mvc.Resources;
+
+    public class ControllerBuilder {
+
+        private Func<IControllerFactory> _factoryThunk = () => null;
+        private static ControllerBuilder _instance = new ControllerBuilder();
+        private HashSet<string> _namespaces = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
+        private IResolver<IControllerFactory> _serviceResolver;
+
+        public ControllerBuilder()
+            : this(null) {
+        }
+
+        internal ControllerBuilder(IResolver<IControllerFactory> serviceResolver) {
+            _serviceResolver = serviceResolver ?? new SingleServiceResolver<IControllerFactory>(
+                () => _factoryThunk(),
+                 new DefaultControllerFactory { ControllerBuilder = this },
+                "ControllerBuilder.GetControllerFactory"
+            );
+        }
+
+        public static ControllerBuilder Current {
+            get {
+                return _instance;
+            }
+        }
+
+        public HashSet<string> DefaultNamespaces {
+            get {
+                return _namespaces;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "Calling method multiple times might return different objects.")]
+        public IControllerFactory GetControllerFactory() {
+            return _serviceResolver.Current;
+        }
+
+        public void SetControllerFactory(IControllerFactory controllerFactory) {
+            if (controllerFactory == null) {
+                throw new ArgumentNullException("controllerFactory");
+            }
+
+            _factoryThunk = () => controllerFactory;
+        }
+
+        public void SetControllerFactory(Type controllerFactoryType) {
+            if (controllerFactoryType == null) {
+                throw new ArgumentNullException("controllerFactoryType");
+            }
+            if (!typeof(IControllerFactory).IsAssignableFrom(controllerFactoryType)) {
+                throw new ArgumentException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.ControllerBuilder_MissingIControllerFactory,
+                        controllerFactoryType),
+                    "controllerFactoryType");
+            }
+
+            _factoryThunk = delegate() {
+                try {
+                    return (IControllerFactory)Activator.CreateInstance(controllerFactoryType);
+                }
+                catch (Exception ex) {
+                    throw new InvalidOperationException(
+                        String.Format(
+                            CultureInfo.CurrentCulture,
+                            MvcResources.ControllerBuilder_ErrorCreatingControllerFactory,
+                            controllerFactoryType),
+                        ex);
+                }
+            };
+        }
+    }
+}
+
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ControllerContext.cs b/mcs/class/System.Web.Mvc3/Mvc/ControllerContext.cs
new file mode 100644 (file)
index 0000000..756a4be
--- /dev/null
@@ -0,0 +1,120 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Web;
+    using System.Web.Routing;
+    using System.Web.Mvc.Html;
+
+    // Though many of the properties on ControllerContext and its subclassed types are virtual, there are still sealed
+    // properties (like ControllerContext.RequestContext, ActionExecutingContext.Result, etc.). If these properties
+    // were virtual, a mocking framework might override them with incorrect behavior (property getters would return
+    // null, property setters would be no-ops). By sealing these properties, we are forcing them to have the default
+    // "get or store a value" semantics that they were intended to have.
+
+    public class ControllerContext {
+
+        private HttpContextBase _httpContext;
+        private RequestContext _requestContext;
+        private RouteData _routeData;
+
+        internal const string PARENT_ACTION_VIEWCONTEXT = "ParentActionViewContext";
+
+        // parameterless constructor used for mocking
+        public ControllerContext() {
+        }
+
+        // copy constructor - allows for subclassed types to take an existing ControllerContext as a parameter
+        // and we'll automatically set the appropriate properties
+        [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", Justification = "The virtual property setters are only to support mocking frameworks, in which case this constructor shouldn't be called anyway.")]
+        protected ControllerContext(ControllerContext controllerContext) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+
+            Controller = controllerContext.Controller;
+            RequestContext = controllerContext.RequestContext;
+        }
+
+        public ControllerContext(HttpContextBase httpContext, RouteData routeData, ControllerBase controller)
+            : this(new RequestContext(httpContext, routeData), controller) {
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", Justification = "The virtual property setters are only to support mocking frameworks, in which case this constructor shouldn't be called anyway.")]
+        public ControllerContext(RequestContext requestContext, ControllerBase controller) {
+            if (requestContext == null) {
+                throw new ArgumentNullException("requestContext");
+            }
+            if (controller == null) {
+                throw new ArgumentNullException("controller");
+            }
+
+            RequestContext = requestContext;
+            Controller = controller;
+        }
+
+        public virtual ControllerBase Controller {
+            get;
+            set;
+        }
+
+        public virtual HttpContextBase HttpContext {
+            get {
+                if (_httpContext == null) {
+                    _httpContext = (_requestContext != null) ? _requestContext.HttpContext : new EmptyHttpContext();
+                }
+                return _httpContext;
+            }
+            set {
+                _httpContext = value;
+            }
+        }
+
+        public virtual bool IsChildAction {
+            get {
+                RouteData routeData = RouteData;
+                if (routeData == null) {
+                    return false;
+                }
+                return routeData.DataTokens.ContainsKey(PARENT_ACTION_VIEWCONTEXT);
+            }
+        }
+
+        public ViewContext ParentActionViewContext {
+            get {
+                return RouteData.DataTokens[PARENT_ACTION_VIEWCONTEXT] as ViewContext;
+            }
+        }
+
+        public RequestContext RequestContext {
+            get {
+                if (_requestContext == null) {
+                    // still need explicit calls to constructors since the property getters are virtual and might return null
+                    HttpContextBase httpContext = HttpContext ?? new EmptyHttpContext();
+                    RouteData routeData = RouteData ?? new RouteData();
+
+                    _requestContext = new RequestContext(httpContext, routeData);
+                }
+                return _requestContext;
+            }
+            set {
+                _requestContext = value;
+            }
+        }
+
+        public virtual RouteData RouteData {
+            get {
+                if (_routeData == null) {
+                    _routeData = (_requestContext != null) ? _requestContext.RouteData : new RouteData();
+                }
+                return _routeData;
+            }
+            set {
+                _routeData = value;
+            }
+        }
+
+        private sealed class EmptyHttpContext : HttpContextBase {
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ControllerDescriptor.cs b/mcs/class/System.Web.Mvc3/Mvc/ControllerDescriptor.cs
new file mode 100644 (file)
index 0000000..121b36a
--- /dev/null
@@ -0,0 +1,71 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq;
+    using System.Reflection;
+
+    public abstract class ControllerDescriptor : ICustomAttributeProvider, IUniquelyIdentifiable {
+
+        private readonly Lazy<string> _uniqueId;
+
+        protected ControllerDescriptor() {
+            _uniqueId = new Lazy<string>(CreateUniqueId);
+        }
+
+        public virtual string ControllerName {
+            get {
+                string typeName = ControllerType.Name;
+                if (typeName.EndsWith("Controller", StringComparison.OrdinalIgnoreCase)) {
+                    return typeName.Substring(0, typeName.Length - "Controller".Length);
+                }
+
+                return typeName;
+            }
+        }
+
+        public abstract Type ControllerType {
+            get;
+        }
+
+        [SuppressMessage("Microsoft.Security", "CA2119:SealMethodsThatSatisfyPrivateInterfaces", Justification = "This is overridden elsewhere in System.Web.Mvc")]
+        public virtual string UniqueId {
+            get {
+                return _uniqueId.Value;
+            }
+        }
+
+        private string CreateUniqueId() {
+            return DescriptorUtil.CreateUniqueId(GetType(), ControllerName, ControllerType);
+        }
+
+        public abstract ActionDescriptor FindAction(ControllerContext controllerContext, string actionName);
+
+        public abstract ActionDescriptor[] GetCanonicalActions();
+
+        public virtual object[] GetCustomAttributes(bool inherit) {
+            return GetCustomAttributes(typeof(object), inherit);
+        }
+
+        public virtual object[] GetCustomAttributes(Type attributeType, bool inherit) {
+            if (attributeType == null) {
+                throw new ArgumentNullException("attributeType");
+            }
+
+            return (object[])Array.CreateInstance(attributeType, 0);
+        }
+
+        internal virtual IEnumerable<FilterAttribute> GetFilterAttributes(bool useCache) {
+            return GetCustomAttributes(typeof(FilterAttribute), inherit: true).Cast<FilterAttribute>();
+        }
+
+        public virtual bool IsDefined(Type attributeType, bool inherit) {
+            if (attributeType == null) {
+                throw new ArgumentNullException("attributeType");
+            }
+
+            return false;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ControllerDescriptorCache.cs b/mcs/class/System.Web.Mvc3/Mvc/ControllerDescriptorCache.cs
new file mode 100644 (file)
index 0000000..01c91ba
--- /dev/null
@@ -0,0 +1,14 @@
+namespace System.Web.Mvc {
+    using System;
+
+    internal sealed class ControllerDescriptorCache : ReaderWriterCache<Type, ControllerDescriptor> {
+
+        public ControllerDescriptorCache() {
+        }
+
+        public ControllerDescriptor GetDescriptor(Type controllerType, Func<ControllerDescriptor> creator) {
+            return FetchOrCreateItem(controllerType, creator);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ControllerInstanceFilterProvider.cs b/mcs/class/System.Web.Mvc3/Mvc/ControllerInstanceFilterProvider.cs
new file mode 100644 (file)
index 0000000..207375c
--- /dev/null
@@ -0,0 +1,12 @@
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+
+    public class ControllerInstanceFilterProvider : IFilterProvider {
+        public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor) {
+            if (controllerContext.Controller != null) {
+                // Use FilterScope.First and Order of Int32.MinValue to ensure controller instance methods always run first
+                yield return new Filter(controllerContext.Controller, FilterScope.First, Int32.MinValue);
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ControllerTypeCache.cs b/mcs/class/System.Web.Mvc3/Mvc/ControllerTypeCache.cs
new file mode 100644 (file)
index 0000000..ba76e65
--- /dev/null
@@ -0,0 +1,115 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Linq;
+    using System.Reflection;
+
+    internal sealed class ControllerTypeCache {
+
+        private const string _typeCacheName = "MVC-ControllerTypeCache.xml";
+
+        private Dictionary<string, ILookup<string, Type>> _cache;
+        private object _lockObj = new object();
+
+        internal int Count {
+            get {
+                int count = 0;
+                foreach (var lookup in _cache.Values) {
+                    foreach (var grouping in lookup) {
+                        count += grouping.Count();
+                    }
+                }
+                return count;
+            }
+        }
+
+        public void EnsureInitialized(IBuildManager buildManager) {
+            if (_cache == null) {
+                lock (_lockObj) {
+                    if (_cache == null) {
+                        List<Type> controllerTypes = TypeCacheUtil.GetFilteredTypesFromAssemblies(_typeCacheName, IsControllerType, buildManager);
+                        var groupedByName = controllerTypes.GroupBy(
+                            t => t.Name.Substring(0, t.Name.Length - "Controller".Length),
+                            StringComparer.OrdinalIgnoreCase);
+                        _cache = groupedByName.ToDictionary(
+                            g => g.Key,
+                            g => g.ToLookup(t => t.Namespace ?? String.Empty, StringComparer.OrdinalIgnoreCase),
+                            StringComparer.OrdinalIgnoreCase);
+                    }
+                }
+            }
+        }
+
+        public ICollection<Type> GetControllerTypes(string controllerName, HashSet<string> namespaces) {
+            HashSet<Type> matchingTypes = new HashSet<Type>();
+
+            ILookup<string, Type> nsLookup;
+            if (_cache.TryGetValue(controllerName, out nsLookup)) {
+                // this friendly name was located in the cache, now cycle through namespaces
+                if (namespaces != null) {
+                    foreach (string requestedNamespace in namespaces) {
+                        foreach (var targetNamespaceGrouping in nsLookup) {
+                            if (IsNamespaceMatch(requestedNamespace, targetNamespaceGrouping.Key)) {
+                                matchingTypes.UnionWith(targetNamespaceGrouping);
+                            }
+                        }
+                    }
+                }
+                else {
+                    // if the namespaces parameter is null, search *every* namespace
+                    foreach (var nsGroup in nsLookup) {
+                        matchingTypes.UnionWith(nsGroup);
+                    }
+                }
+            }
+
+            return matchingTypes;
+        }
+
+        internal static bool IsControllerType(Type t) {
+            return
+                t != null &&
+                t.IsPublic &&
+                t.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase) &&
+                !t.IsAbstract &&
+                typeof(IController).IsAssignableFrom(t);
+        }
+
+        internal static bool IsNamespaceMatch(string requestedNamespace, string targetNamespace) {
+            // degenerate cases
+            if (requestedNamespace == null) {
+                return false;
+            }
+            else if (requestedNamespace.Length == 0) {
+                return true;
+            }
+
+            if (!requestedNamespace.EndsWith(".*", StringComparison.OrdinalIgnoreCase)) {
+                // looking for exact namespace match
+                return String.Equals(requestedNamespace, targetNamespace, StringComparison.OrdinalIgnoreCase);
+            }
+            else {
+                // looking for exact or sub-namespace match
+                requestedNamespace = requestedNamespace.Substring(0, requestedNamespace.Length - ".*".Length);
+                if (!targetNamespace.StartsWith(requestedNamespace, StringComparison.OrdinalIgnoreCase)) {
+                    return false;
+                }
+
+                if (requestedNamespace.Length == targetNamespace.Length) {
+                    // exact match
+                    return true;
+                }
+                else if (targetNamespace[requestedNamespace.Length] == '.') {
+                    // good prefix match, e.g. requestedNamespace = "Foo.Bar" and targetNamespace = "Foo.Bar.Baz"
+                    return true;
+                }
+                else {
+                    // bad prefix match, e.g. requestedNamespace = "Foo.Bar" and targetNamespace = "Foo.Bar2"
+                    return false;
+                }
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/CustomModelBinderAttribute.cs b/mcs/class/System.Web.Mvc3/Mvc/CustomModelBinderAttribute.cs
new file mode 100644 (file)
index 0000000..b0feb7e
--- /dev/null
@@ -0,0 +1,14 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+
+    [AttributeUsage(ValidTargets, AllowMultiple = false, Inherited = false)]
+    public abstract class CustomModelBinderAttribute : Attribute {
+
+        internal const AttributeTargets ValidTargets = AttributeTargets.Class | AttributeTargets.Enum | AttributeTargets.Interface | AttributeTargets.Parameter | AttributeTargets.Struct;
+
+        [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "This method can potentially perform a non-trivial amount of work.")]
+        public abstract IModelBinder GetBinder();
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/DataAnnotationsModelMetadata.cs b/mcs/class/System.Web.Mvc3/Mvc/DataAnnotationsModelMetadata.cs
new file mode 100644 (file)
index 0000000..b171f6b
--- /dev/null
@@ -0,0 +1,51 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.ComponentModel.DataAnnotations;
+    using System.Globalization;
+    using System.Reflection;
+    using System.Web.Mvc.Resources;
+
+    public class DataAnnotationsModelMetadata : ModelMetadata {
+        private DisplayColumnAttribute _displayColumnAttribute;
+
+        public DataAnnotationsModelMetadata(DataAnnotationsModelMetadataProvider provider, Type containerType,
+                                            Func<object> modelAccessor, Type modelType, string propertyName,
+                                            DisplayColumnAttribute displayColumnAttribute)
+            : base(provider, containerType, modelAccessor, modelType, propertyName) {
+            _displayColumnAttribute = displayColumnAttribute;
+        }
+
+        protected override string GetSimpleDisplayText() {
+            if (Model != null) {
+                if (_displayColumnAttribute != null && !String.IsNullOrEmpty(_displayColumnAttribute.DisplayColumn)) {
+                    PropertyInfo displayColumnProperty = ModelType.GetProperty(_displayColumnAttribute.DisplayColumn, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance);
+                    ValidateDisplayColumnAttribute(_displayColumnAttribute, displayColumnProperty, ModelType);
+
+                    object simpleDisplayTextValue = displayColumnProperty.GetValue(Model, new object[0]);
+                    if (simpleDisplayTextValue != null) {
+                        return simpleDisplayTextValue.ToString();
+                    }
+                }
+            }
+
+            return base.GetSimpleDisplayText();
+        }
+
+        private static void ValidateDisplayColumnAttribute(DisplayColumnAttribute displayColumnAttribute, PropertyInfo displayColumnProperty, Type modelType) {
+            if (displayColumnProperty == null) {
+                throw new InvalidOperationException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.DataAnnotationsModelMetadataProvider_UnknownProperty,
+                        modelType.FullName, displayColumnAttribute.DisplayColumn));
+            }
+            if (displayColumnProperty.GetGetMethod() == null) {
+                throw new InvalidOperationException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.DataAnnotationsModelMetadataProvider_UnreadableProperty,
+                        modelType.FullName, displayColumnAttribute.DisplayColumn));
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/DataAnnotationsModelMetadataProvider.cs b/mcs/class/System.Web.Mvc3/Mvc/DataAnnotationsModelMetadataProvider.cs
new file mode 100644 (file)
index 0000000..9f849ee
--- /dev/null
@@ -0,0 +1,98 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.ComponentModel;
+    using System.ComponentModel.DataAnnotations;
+    using System.Linq;
+
+    public class DataAnnotationsModelMetadataProvider : AssociatedMetadataProvider {
+
+        protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName) {
+            List<Attribute> attributeList = new List<Attribute>(attributes);
+            DisplayColumnAttribute displayColumnAttribute = attributeList.OfType<DisplayColumnAttribute>().FirstOrDefault();
+            DataAnnotationsModelMetadata result = new DataAnnotationsModelMetadata(this, containerType, modelAccessor, modelType, propertyName, displayColumnAttribute);
+
+            // Do [HiddenInput] before [UIHint], so you can override the template hint
+            HiddenInputAttribute hiddenInputAttribute = attributeList.OfType<HiddenInputAttribute>().FirstOrDefault();
+            if (hiddenInputAttribute != null) {
+                result.TemplateHint = "HiddenInput";
+                result.HideSurroundingHtml = !hiddenInputAttribute.DisplayValue;
+            }
+
+            // We prefer [UIHint("...", PresentationLayer = "MVC")] but will fall back to [UIHint("...")]
+            IEnumerable<UIHintAttribute> uiHintAttributes = attributeList.OfType<UIHintAttribute>();
+            UIHintAttribute uiHintAttribute = uiHintAttributes.FirstOrDefault(a => String.Equals(a.PresentationLayer, "MVC", StringComparison.OrdinalIgnoreCase))
+                                           ?? uiHintAttributes.FirstOrDefault(a => String.IsNullOrEmpty(a.PresentationLayer));
+            if (uiHintAttribute != null) {
+                result.TemplateHint = uiHintAttribute.UIHint;
+            }
+
+            DataTypeAttribute dataTypeAttribute = attributeList.OfType<DataTypeAttribute>().FirstOrDefault();
+            if (dataTypeAttribute != null) {
+                result.DataTypeName = dataTypeAttribute.ToDataTypeName();
+            }
+
+            EditableAttribute editable = attributes.OfType<EditableAttribute>().FirstOrDefault();
+            if (editable != null) {
+                result.IsReadOnly = !editable.AllowEdit;
+            }
+            else {
+                ReadOnlyAttribute readOnlyAttribute = attributeList.OfType<ReadOnlyAttribute>().FirstOrDefault();
+                if (readOnlyAttribute != null) {
+                    result.IsReadOnly = readOnlyAttribute.IsReadOnly;
+                }
+            }
+
+            DisplayFormatAttribute displayFormatAttribute = attributeList.OfType<DisplayFormatAttribute>().FirstOrDefault();
+            if (displayFormatAttribute == null && dataTypeAttribute != null) {
+                displayFormatAttribute = dataTypeAttribute.DisplayFormat;
+            }
+            if (displayFormatAttribute != null) {
+                result.NullDisplayText = displayFormatAttribute.NullDisplayText;
+                result.DisplayFormatString = displayFormatAttribute.DataFormatString;
+                result.ConvertEmptyStringToNull = displayFormatAttribute.ConvertEmptyStringToNull;
+
+                if (displayFormatAttribute.ApplyFormatInEditMode) {
+                    result.EditFormatString = displayFormatAttribute.DataFormatString;
+                }
+
+                if (!displayFormatAttribute.HtmlEncode && String.IsNullOrWhiteSpace(result.DataTypeName)) {
+                    result.DataTypeName = DataTypeUtil.HtmlTypeName;
+                }
+            }
+
+            ScaffoldColumnAttribute scaffoldColumnAttribute = attributeList.OfType<ScaffoldColumnAttribute>().FirstOrDefault();
+            if (scaffoldColumnAttribute != null) {
+                result.ShowForDisplay = result.ShowForEdit = scaffoldColumnAttribute.Scaffold;
+            }
+
+            DisplayAttribute display = attributes.OfType<DisplayAttribute>().FirstOrDefault();
+            string name = null;
+            if (display != null) {
+                result.Description = display.GetDescription();
+                result.ShortDisplayName = display.GetShortName();
+                result.Watermark = display.GetPrompt();
+                result.Order = display.GetOrder() ?? ModelMetadata.DefaultOrder;
+
+                name = display.GetName();
+            }
+
+            if (name != null) {
+                result.DisplayName = name;
+            }
+            else {
+                DisplayNameAttribute displayNameAttribute = attributeList.OfType<DisplayNameAttribute>().FirstOrDefault();
+                if (displayNameAttribute != null) {
+                    result.DisplayName = displayNameAttribute.DisplayName;
+                }
+            }
+
+            RequiredAttribute requiredAttribute = attributeList.OfType<RequiredAttribute>().FirstOrDefault();
+            if (requiredAttribute != null) {
+                result.IsRequired = true;
+            }
+
+            return result;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/DataAnnotationsModelValidator.cs b/mcs/class/System.Web.Mvc3/Mvc/DataAnnotationsModelValidator.cs
new file mode 100644 (file)
index 0000000..296f7f4
--- /dev/null
@@ -0,0 +1,61 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.ComponentModel.DataAnnotations;
+    using System.Linq;
+
+    public class DataAnnotationsModelValidator : ModelValidator {
+        public DataAnnotationsModelValidator(ModelMetadata metadata, ControllerContext context, ValidationAttribute attribute)
+            : base(metadata, context) {
+
+            if (attribute == null) {
+                throw new ArgumentNullException("attribute");
+            }
+
+            Attribute = attribute;
+        }
+
+        protected internal ValidationAttribute Attribute { get; private set; }
+
+        protected internal string ErrorMessage {
+            get {
+                return Attribute.FormatErrorMessage(Metadata.GetDisplayName());
+            }
+        }
+
+        public override bool IsRequired {
+            get {
+                return Attribute is RequiredAttribute;
+            }
+        }
+
+        internal static ModelValidator Create(ModelMetadata metadata, ControllerContext context, ValidationAttribute attribute) {
+            return new DataAnnotationsModelValidator(metadata, context, attribute);
+        }
+
+        public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() {
+            IEnumerable<ModelClientValidationRule> results = base.GetClientValidationRules();
+
+            IClientValidatable clientValidatable = Attribute as IClientValidatable;
+            if (clientValidatable != null) {
+                results = results.Concat(clientValidatable.GetClientValidationRules(Metadata, ControllerContext));
+            }
+
+            return results;
+        }
+
+        public override IEnumerable<ModelValidationResult> Validate(object container) {
+            // Per the WCF RIA Services team, instance can never be null (if you have
+            // no parent, you pass yourself for the "instance" parameter).
+            ValidationContext context = new ValidationContext(container ?? Metadata.Model, null, null);
+            context.DisplayName = Metadata.GetDisplayName();
+
+            ValidationResult result = Attribute.GetValidationResult(Metadata.Model, context);
+            if (result != ValidationResult.Success) {
+                yield return new ModelValidationResult {
+                    Message = result.ErrorMessage
+                };
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/DataAnnotationsModelValidatorProvider.cs b/mcs/class/System.Web.Mvc3/Mvc/DataAnnotationsModelValidatorProvider.cs
new file mode 100644 (file)
index 0000000..6a5c579
--- /dev/null
@@ -0,0 +1,342 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.ComponentModel.DataAnnotations;
+    using System.Globalization;
+    using System.Linq;
+    using System.Reflection;
+    using System.Threading;
+    using System.Web.Mvc.Resources;
+
+    // A factory for validators based on ValidationAttribute
+    public delegate ModelValidator DataAnnotationsModelValidationFactory(ModelMetadata metadata, ControllerContext context, ValidationAttribute attribute);
+
+    // A factory for validators based on IValidatableObject
+    public delegate ModelValidator DataAnnotationsValidatableObjectAdapterFactory(ModelMetadata metadata, ControllerContext context);
+
+    /// <summary>
+    /// An implementation of <see cref="ModelValidatorProvider"/> which providers validators
+    /// for attributes which derive from <see cref="ValidationAttribute"/>. It also provides
+    /// a validator for types which implement <see cref="IValidatableObject"/>. To support
+    /// client side validation, you can either register adapters through the static methods
+    /// on this class, or by having your validation attributes implement
+    /// <see cref="IClientValidatable"/>. The logic to support IClientValidatable
+    /// is implemented in <see cref="DataAnnotationsModelValidator"/>.
+    /// </summary>
+    public class DataAnnotationsModelValidatorProvider : AssociatedValidatorProvider {
+        private static bool _addImplicitRequiredAttributeForValueTypes = true;
+        private static ReaderWriterLockSlim _adaptersLock = new ReaderWriterLockSlim();
+
+        // Factories for validation attributes
+
+        internal static DataAnnotationsModelValidationFactory DefaultAttributeFactory =
+            (metadata, context, attribute) => new DataAnnotationsModelValidator(metadata, context, attribute);
+
+        internal static Dictionary<Type, DataAnnotationsModelValidationFactory> AttributeFactories = new Dictionary<Type, DataAnnotationsModelValidationFactory>() {
+            {
+                typeof(RangeAttribute),
+                (metadata, context, attribute) => new RangeAttributeAdapter(metadata, context, (RangeAttribute)attribute)
+            },
+            {
+                typeof(RegularExpressionAttribute),
+                (metadata, context, attribute) => new RegularExpressionAttributeAdapter(metadata, context, (RegularExpressionAttribute)attribute)
+            },
+            {
+                typeof(RequiredAttribute),
+                (metadata, context, attribute) => new RequiredAttributeAdapter(metadata, context, (RequiredAttribute)attribute)
+            },
+            {
+                typeof(StringLengthAttribute),
+                (metadata, context, attribute) => new StringLengthAttributeAdapter(metadata, context, (StringLengthAttribute)attribute)
+            },
+        };
+
+        // Factories for IValidatableObject models
+
+        internal static DataAnnotationsValidatableObjectAdapterFactory DefaultValidatableFactory =
+            (metadata, context) => new ValidatableObjectAdapter(metadata, context);
+
+        internal static Dictionary<Type, DataAnnotationsValidatableObjectAdapterFactory> ValidatableFactories = new Dictionary<Type, DataAnnotationsValidatableObjectAdapterFactory>();
+
+        public static bool AddImplicitRequiredAttributeForValueTypes {
+            get {
+                return _addImplicitRequiredAttributeForValueTypes;
+            }
+            set {
+                _addImplicitRequiredAttributeForValueTypes = value;
+            }
+        }
+
+        protected override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes) {
+            _adaptersLock.EnterReadLock();
+
+            try {
+                List<ModelValidator> results = new List<ModelValidator>();
+
+                // Add an implied [Required] attribute for any non-nullable value type,
+                // unless they've configured us not to do that.
+                if (AddImplicitRequiredAttributeForValueTypes &&
+                        metadata.IsRequired &&
+                        !attributes.Any(a => a is RequiredAttribute)) {
+                    attributes = attributes.Concat(new[] { new RequiredAttribute() });
+                }
+
+                // Produce a validator for each validation attribute we find
+                foreach (ValidationAttribute attribute in attributes.OfType<ValidationAttribute>()) {
+                    DataAnnotationsModelValidationFactory factory;
+                    if (!AttributeFactories.TryGetValue(attribute.GetType(), out factory)) {
+                        factory = DefaultAttributeFactory;
+                    }
+                    results.Add(factory(metadata, context, attribute));
+                }
+
+                // Produce a validator if the type supports IValidatableObject
+                if (typeof(IValidatableObject).IsAssignableFrom(metadata.ModelType)) {
+                    DataAnnotationsValidatableObjectAdapterFactory factory;
+                    if (!ValidatableFactories.TryGetValue(metadata.ModelType, out factory)) {
+                        factory = DefaultValidatableFactory;
+                    }
+                    results.Add(factory(metadata, context));
+                }
+
+                return results;
+            }
+            finally {
+                _adaptersLock.ExitReadLock();
+            }
+        }
+
+        #region Validation attribute adapter registration
+
+        public static void RegisterAdapter(Type attributeType, Type adapterType) {
+            ValidateAttributeType(attributeType);
+            ValidateAttributeAdapterType(adapterType);
+            ConstructorInfo constructor = GetAttributeAdapterConstructor(attributeType, adapterType);
+
+            _adaptersLock.EnterWriteLock();
+
+            try {
+                AttributeFactories[attributeType] = (metadata, context, attribute) => (ModelValidator)constructor.Invoke(new object[] { metadata, context, attribute });
+            }
+            finally {
+                _adaptersLock.ExitWriteLock();
+            }
+        }
+
+        public static void RegisterAdapterFactory(Type attributeType, DataAnnotationsModelValidationFactory factory) {
+            ValidateAttributeType(attributeType);
+            ValidateAttributeFactory(factory);
+
+            _adaptersLock.EnterWriteLock();
+
+            try {
+                AttributeFactories[attributeType] = factory;
+            }
+            finally {
+                _adaptersLock.ExitWriteLock();
+            }
+        }
+
+        public static void RegisterDefaultAdapter(Type adapterType) {
+            ValidateAttributeAdapterType(adapterType);
+            ConstructorInfo constructor = GetAttributeAdapterConstructor(typeof(ValidationAttribute), adapterType);
+
+            DefaultAttributeFactory = (metadata, context, attribute) => (ModelValidator)constructor.Invoke(new object[] { metadata, context, attribute });
+        }
+
+        public static void RegisterDefaultAdapterFactory(DataAnnotationsModelValidationFactory factory) {
+            ValidateAttributeFactory(factory);
+
+            DefaultAttributeFactory = factory;
+        }
+
+        // Helpers 
+
+        private static ConstructorInfo GetAttributeAdapterConstructor(Type attributeType, Type adapterType) {
+            ConstructorInfo constructor = adapterType.GetConstructor(new[] { typeof(ModelMetadata), typeof(ControllerContext), attributeType });
+            if (constructor == null) {
+                throw new ArgumentException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.DataAnnotationsModelValidatorProvider_ConstructorRequirements,
+                        adapterType.FullName,
+                        typeof(ModelMetadata).FullName,
+                        typeof(ControllerContext).FullName,
+                        attributeType.FullName
+                    ),
+                    "adapterType"
+                );
+            }
+
+            return constructor;
+        }
+
+        private static void ValidateAttributeAdapterType(Type adapterType) {
+            if (adapterType == null) {
+                throw new ArgumentNullException("adapterType");
+            }
+            if (!typeof(ModelValidator).IsAssignableFrom(adapterType)) {
+                throw new ArgumentException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.Common_TypeMustDriveFromType,
+                        adapterType.FullName,
+                        typeof(ModelValidator).FullName
+                    ),
+                    "adapterType"
+                );
+            }
+        }
+
+        private static void ValidateAttributeType(Type attributeType) {
+            if (attributeType == null) {
+                throw new ArgumentNullException("attributeType");
+            }
+            if (!typeof(ValidationAttribute).IsAssignableFrom(attributeType)) {
+                throw new ArgumentException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.Common_TypeMustDriveFromType,
+                        attributeType.FullName,
+                        typeof(ValidationAttribute).FullName
+                    ),
+                    "attributeType");
+            }
+        }
+
+        private static void ValidateAttributeFactory(DataAnnotationsModelValidationFactory factory) {
+            if (factory == null) {
+                throw new ArgumentNullException("factory");
+            }
+        }
+
+        #endregion
+
+        #region IValidatableObject adapter registration
+
+        /// <summary>
+        /// Registers an adapter type for the given <see cref="modelType"/>, which must
+        /// implement <see cref="IValidatableObject"/>. The adapter type must derive from
+        /// <see cref="ModelValidator"/> and it must contain a public constructor
+        /// which takes two parameters of types <see cref="ModelMetadata"/> and
+        /// <see cref="ControllerContext"/>.
+        /// </summary>
+        public static void RegisterValidatableObjectAdapter(Type modelType, Type adapterType) {
+            ValidateValidatableModelType(modelType);
+            ValidateValidatableAdapterType(adapterType);
+            ConstructorInfo constructor = GetValidatableAdapterConstructor(adapterType);
+
+            _adaptersLock.EnterWriteLock();
+
+            try {
+                ValidatableFactories[modelType] = (metadata, context) => (ModelValidator)constructor.Invoke(new object[] { metadata, context });
+            }
+            finally {
+                _adaptersLock.ExitWriteLock();
+            }
+        }
+
+        /// <summary>
+        /// Registers an adapter factory for the given <see cref="modelType"/>, which must
+        /// implement <see cref="IValidatableObject"/>.
+        /// </summary>
+        public static void RegisterValidatableObjectAdapterFactory(Type modelType, DataAnnotationsValidatableObjectAdapterFactory factory) {
+            ValidateValidatableModelType(modelType);
+            ValidateValidatableFactory(factory);
+
+            _adaptersLock.EnterWriteLock();
+
+            try {
+                ValidatableFactories[modelType] = factory;
+            }
+            finally {
+                _adaptersLock.ExitWriteLock();
+            }
+        }
+
+        /// <summary>
+        /// Registers the default adapter type for objects which implement
+        /// <see cref="IValidatableObject"/>. The adapter type must derive from
+        /// <see cref="ModelValidator"/> and it must contain a public constructor
+        /// which takes two parameters of types <see cref="ModelMetadata"/> and
+        /// <see cref="ControllerContext"/>.
+        /// </summary>
+        public static void RegisterDefaultValidatableObjectAdapter(Type adapterType) {
+            ValidateValidatableAdapterType(adapterType);
+            ConstructorInfo constructor = GetValidatableAdapterConstructor(adapterType);
+
+            DefaultValidatableFactory = (metadata, context) => (ModelValidator)constructor.Invoke(new object[] { metadata, context });
+        }
+
+        /// <summary>
+        /// Registers the default adapter factory for objects which implement
+        /// <see cref="IValidatableObject"/>.
+        /// </summary>
+        public static void RegisterDefaultValidatableObjectAdapterFactory(DataAnnotationsValidatableObjectAdapterFactory factory) {
+            ValidateValidatableFactory(factory);
+
+            DefaultValidatableFactory = factory;
+        }
+
+        // Helpers 
+
+        private static ConstructorInfo GetValidatableAdapterConstructor(Type adapterType) {
+            ConstructorInfo constructor = adapterType.GetConstructor(new[] { typeof(ModelMetadata), typeof(ControllerContext) });
+            if (constructor == null) {
+                throw new ArgumentException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.DataAnnotationsModelValidatorProvider_ValidatableConstructorRequirements,
+                        adapterType.FullName,
+                        typeof(ModelMetadata).FullName,
+                        typeof(ControllerContext).FullName
+                    ),
+                    "adapterType"
+                );
+            }
+
+            return constructor;
+        }
+
+        private static void ValidateValidatableAdapterType(Type adapterType) {
+            if (adapterType == null) {
+                throw new ArgumentNullException("adapterType");
+            }
+            if (!typeof(ModelValidator).IsAssignableFrom(adapterType)) {
+                throw new ArgumentException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.Common_TypeMustDriveFromType,
+                        adapterType.FullName,
+                        typeof(ModelValidator).FullName
+                    ),
+                    "adapterType");
+            }
+        }
+
+        private static void ValidateValidatableModelType(Type modelType) {
+            if (modelType == null) {
+                throw new ArgumentNullException("modelType");
+            }
+            if (!typeof(IValidatableObject).IsAssignableFrom(modelType)) {
+                throw new ArgumentException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.Common_TypeMustDriveFromType,
+                        modelType.FullName,
+                        typeof(IValidatableObject).FullName
+                    ),
+                    "modelType"
+                );
+            }
+        }
+
+        private static void ValidateValidatableFactory(DataAnnotationsValidatableObjectAdapterFactory factory) {
+            if (factory == null) {
+                throw new ArgumentNullException("factory");
+            }
+        }
+
+        #endregion
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/DataAnnotationsModelValidator`1.cs b/mcs/class/System.Web.Mvc3/Mvc/DataAnnotationsModelValidator`1.cs
new file mode 100644 (file)
index 0000000..b29def9
--- /dev/null
@@ -0,0 +1,14 @@
+namespace System.Web.Mvc {
+    using System.ComponentModel.DataAnnotations;
+
+    public class DataAnnotationsModelValidator<TAttribute> : DataAnnotationsModelValidator where TAttribute : ValidationAttribute {
+        public DataAnnotationsModelValidator(ModelMetadata metadata, ControllerContext context, TAttribute attribute)
+            : base(metadata, context, attribute) { }
+
+        protected new TAttribute Attribute {
+            get {
+                return (TAttribute)base.Attribute;
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/DataErrorInfoModelValidatorProvider.cs b/mcs/class/System.Web.Mvc3/Mvc/DataErrorInfoModelValidatorProvider.cs
new file mode 100644 (file)
index 0000000..6ef1026
--- /dev/null
@@ -0,0 +1,75 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.ComponentModel;
+    using System.Linq;
+
+    public class DataErrorInfoModelValidatorProvider : ModelValidatorProvider {
+
+        public override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context) {
+            if (metadata == null) {
+                throw new ArgumentNullException("metadata");
+            }
+            if (context == null) {
+                throw new ArgumentNullException("context");
+            }
+
+            return GetValidatorsImpl(metadata, context);
+        }
+
+        private static IEnumerable<ModelValidator> GetValidatorsImpl(ModelMetadata metadata, ControllerContext context) {
+            // If the metadata describes a model that implements IDataErrorInfo, we should call its
+            // Error property at the appropriate time.
+            if (TypeImplementsIDataErrorInfo(metadata.ModelType)) {
+                yield return new DataErrorInfoClassModelValidator(metadata, context);
+            }
+
+            // If the metadata describes a property of a container that implements IDataErrorInfo,
+            // we should call its Item indexer at the appropriate time.
+            if (TypeImplementsIDataErrorInfo(metadata.ContainerType)) {
+                yield return new DataErrorInfoPropertyModelValidator(metadata, context);
+            }
+        }
+
+        private static bool TypeImplementsIDataErrorInfo(Type type) {
+            return typeof(IDataErrorInfo).IsAssignableFrom(type);
+        }
+
+        internal sealed class DataErrorInfoClassModelValidator : ModelValidator {
+            public DataErrorInfoClassModelValidator(ModelMetadata metadata, ControllerContext controllerContext)
+                : base(metadata, controllerContext) {
+            }
+            public override IEnumerable<ModelValidationResult> Validate(object container) {
+                IDataErrorInfo castModel = Metadata.Model as IDataErrorInfo;
+                if (castModel != null) {
+                    string errorMessage = castModel.Error;
+                    if (!String.IsNullOrEmpty(errorMessage)) {
+                        return new ModelValidationResult[] {
+                            new ModelValidationResult() { Message = errorMessage }
+                        };
+                    }
+                }
+                return Enumerable.Empty<ModelValidationResult>();
+            }
+        }
+
+        internal sealed class DataErrorInfoPropertyModelValidator : ModelValidator {
+            public DataErrorInfoPropertyModelValidator(ModelMetadata metadata, ControllerContext controllerContext)
+                : base(metadata, controllerContext) {
+            }
+            public override IEnumerable<ModelValidationResult> Validate(object container) {
+                IDataErrorInfo castContainer = container as IDataErrorInfo;
+                if (castContainer != null && !String.Equals(Metadata.PropertyName, "error", StringComparison.OrdinalIgnoreCase)) {
+                    string errorMessage = castContainer[Metadata.PropertyName];
+                    if (!String.IsNullOrEmpty(errorMessage)) {
+                        return new ModelValidationResult[] {
+                            new ModelValidationResult() { Message = errorMessage }
+                        };
+                    }
+                }
+                return Enumerable.Empty<ModelValidationResult>();
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/DataTypeUtil.cs b/mcs/class/System.Web.Mvc3/Mvc/DataTypeUtil.cs
new file mode 100644 (file)
index 0000000..181b036
--- /dev/null
@@ -0,0 +1,64 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.ComponentModel.DataAnnotations;
+
+    internal static class DataTypeUtil {
+        internal static readonly string CurrencyTypeName = DataType.Currency.ToString();
+        internal static readonly string DateTypeName = DataType.Date.ToString();
+        internal static readonly string DateTimeTypeName = DataType.DateTime.ToString();
+        internal static readonly string DurationTypeName = DataType.Duration.ToString();
+        internal static readonly string EmailAddressTypeName = DataType.EmailAddress.ToString();
+        internal static readonly string HtmlTypeName = DataType.Html.ToString();
+        internal static readonly string ImageUrlTypeName = DataType.ImageUrl.ToString();
+        internal static readonly string MultiLineTextTypeName = DataType.MultilineText.ToString();
+        internal static readonly string PasswordTypeName = DataType.Password.ToString();
+        internal static readonly string PhoneNumberTypeName = DataType.PhoneNumber.ToString();
+        internal static readonly string TextTypeName = DataType.Text.ToString();
+        internal static readonly string TimeTypeName = DataType.Time.ToString();
+        internal static readonly string UrlTypeName = DataType.Url.ToString();
+
+        // This is a faster version of GetDataTypeName(). It internally calls ToString() on the enum
+        // value, which can be quite slow because of value verification.
+        internal static string ToDataTypeName(this DataTypeAttribute attribute, Func<DataTypeAttribute, Boolean> isDataType = null) {
+            if (isDataType == null) {
+                isDataType = t => t.GetType().Equals(typeof(DataTypeAttribute));
+            }
+
+            // GetDataTypeName is virtual, so this is only safe if they haven't derived from DataTypeAttribute.
+            // However, if they derive from DataTypeAttribute, they can help their own perf by overriding GetDataTypeName
+            // and returning an appropriate string without invoking the ToString() on the enum.
+            if (isDataType(attribute)) {
+                switch (attribute.DataType) {
+                    case DataType.Currency:
+                        return CurrencyTypeName;
+                    case DataType.Date:
+                        return DateTypeName;
+                    case DataType.DateTime:
+                        return DateTimeTypeName;
+                    case DataType.Duration:
+                        return DurationTypeName;
+                    case DataType.EmailAddress:
+                        return EmailAddressTypeName;
+                    case DataType.Html:
+                        return HtmlTypeName;
+                    case DataType.ImageUrl:
+                        return ImageUrlTypeName;
+                    case DataType.MultilineText:
+                        return MultiLineTextTypeName;
+                    case DataType.Password:
+                        return PasswordTypeName;
+                    case DataType.PhoneNumber:
+                        return PhoneNumberTypeName;
+                    case DataType.Text:
+                        return TextTypeName;
+                    case DataType.Time:
+                        return TimeTypeName;
+                    case DataType.Url:
+                        return UrlTypeName;
+                }
+            }
+
+            return attribute.GetDataTypeName();
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/DefaultControllerFactory.cs b/mcs/class/System.Web.Mvc3/Mvc/DefaultControllerFactory.cs
new file mode 100644 (file)
index 0000000..e91c9eb
--- /dev/null
@@ -0,0 +1,260 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections;
+    using System.Collections.Concurrent;
+    using System.Collections.Generic;
+    using System.Globalization;
+    using System.Linq;
+    using System.Text;
+    using System.Web;
+    using System.Web.Mvc.Resources;
+    using System.Web.Routing;
+    using System.Web.SessionState;
+
+    public class DefaultControllerFactory : IControllerFactory {
+        private IBuildManager _buildManager;
+        private IResolver<IControllerActivator> _activatorResolver;
+        private IControllerActivator _controllerActivator;
+        private ControllerBuilder _controllerBuilder;
+        private ControllerTypeCache _instanceControllerTypeCache;
+        private static readonly ConcurrentDictionary<Type, SessionStateBehavior> _sessionStateCache = new ConcurrentDictionary<Type, SessionStateBehavior>();
+        private static ControllerTypeCache _staticControllerTypeCache = new ControllerTypeCache();
+
+        public DefaultControllerFactory()
+            : this(null, null, null) {
+        }
+
+        public DefaultControllerFactory(IControllerActivator controllerActivator)
+            : this(controllerActivator, null, null) {
+        }
+
+        internal DefaultControllerFactory(IControllerActivator controllerActivator, IResolver<IControllerActivator> activatorResolver, IDependencyResolver dependencyResolver) {
+            if (controllerActivator != null) {
+                _controllerActivator = controllerActivator;
+            }
+            else {
+                _activatorResolver = activatorResolver ?? new SingleServiceResolver<IControllerActivator>(
+                    () => null,
+                    new DefaultControllerActivator(dependencyResolver),
+                    "DefaultControllerFactory contstructor"
+                );
+            }
+        }
+
+        private IControllerActivator ControllerActivator {
+            get {
+                if (_controllerActivator != null) {
+                    return _controllerActivator;
+                }
+                _controllerActivator = _activatorResolver.Current;
+                return _controllerActivator;
+            }
+        }
+
+        internal IBuildManager BuildManager {
+            get {
+                if (_buildManager == null) {
+                    _buildManager = new BuildManagerWrapper();
+                }
+                return _buildManager;
+            }
+            set {
+                _buildManager = value;
+            }
+        }
+
+        internal ControllerBuilder ControllerBuilder {
+            get {
+                return _controllerBuilder ?? ControllerBuilder.Current;
+            }
+            set {
+                _controllerBuilder = value;
+            }
+        }
+
+        internal ControllerTypeCache ControllerTypeCache {
+            get {
+                return _instanceControllerTypeCache ?? _staticControllerTypeCache;
+            }
+            set {
+                _instanceControllerTypeCache = value;
+            }
+        }
+
+        internal static InvalidOperationException CreateAmbiguousControllerException(RouteBase route, string controllerName, ICollection<Type> matchingTypes) {
+            // we need to generate an exception containing all the controller types
+            StringBuilder typeList = new StringBuilder();
+            foreach (Type matchedType in matchingTypes) {
+                typeList.AppendLine();
+                typeList.Append(matchedType.FullName);
+            }
+
+            string errorText;
+            Route castRoute = route as Route;
+            if (castRoute != null) {
+                errorText = String.Format(CultureInfo.CurrentCulture, MvcResources.DefaultControllerFactory_ControllerNameAmbiguous_WithRouteUrl,
+                    controllerName, castRoute.Url, typeList);
+            }
+            else {
+                errorText = String.Format(CultureInfo.CurrentCulture, MvcResources.DefaultControllerFactory_ControllerNameAmbiguous_WithoutRouteUrl,
+                    controllerName, typeList);
+            }
+
+            return new InvalidOperationException(errorText);
+        }
+
+        public virtual IController CreateController(RequestContext requestContext, string controllerName) {
+            if (requestContext == null) {
+                throw new ArgumentNullException("requestContext");
+            }
+            if (String.IsNullOrEmpty(controllerName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "controllerName");
+            }
+            Type controllerType = GetControllerType(requestContext, controllerName);
+            IController controller = GetControllerInstance(requestContext, controllerType);
+            return controller;
+        }
+
+        protected internal virtual IController GetControllerInstance(RequestContext requestContext, Type controllerType) {
+            if (controllerType == null) {
+                throw new HttpException(404,
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.DefaultControllerFactory_NoControllerFound,
+                        requestContext.HttpContext.Request.Path));
+            }
+            if (!typeof(IController).IsAssignableFrom(controllerType)) {
+                throw new ArgumentException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.DefaultControllerFactory_TypeDoesNotSubclassControllerBase,
+                        controllerType),
+                    "controllerType");
+            }
+            return ControllerActivator.Create(requestContext, controllerType);
+        }
+
+        protected internal virtual SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, Type controllerType) {
+            if (controllerType == null) {
+                return SessionStateBehavior.Default;
+            }
+
+            return _sessionStateCache.GetOrAdd(
+                controllerType,
+                type =>
+                {
+                    var attr = type.GetCustomAttributes(typeof(SessionStateAttribute), inherit: true)
+                                   .OfType<SessionStateAttribute>()
+                                   .FirstOrDefault();
+
+                    return (attr != null) ? attr.Behavior : SessionStateBehavior.Default;
+                }
+            );
+        }
+
+        protected internal virtual Type GetControllerType(RequestContext requestContext, string controllerName) {
+            if (String.IsNullOrEmpty(controllerName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "controllerName");
+            }
+
+            // first search in the current route's namespace collection
+            object routeNamespacesObj;
+            Type match;
+            if (requestContext != null && requestContext.RouteData.DataTokens.TryGetValue("Namespaces", out routeNamespacesObj)) {
+                IEnumerable<string> routeNamespaces = routeNamespacesObj as IEnumerable<string>;
+                if (routeNamespaces != null && routeNamespaces.Any()) {
+                    HashSet<string> nsHash = new HashSet<string>(routeNamespaces, StringComparer.OrdinalIgnoreCase);
+                    match = GetControllerTypeWithinNamespaces(requestContext.RouteData.Route, controllerName, nsHash);
+
+                    // the UseNamespaceFallback key might not exist, in which case its value is implicitly "true"
+                    if (match != null || false.Equals(requestContext.RouteData.DataTokens["UseNamespaceFallback"])) {
+                        // got a match or the route requested we stop looking
+                        return match;
+                    }
+                }
+            }
+
+            // then search in the application's default namespace collection
+            if (ControllerBuilder.DefaultNamespaces.Count > 0) {
+                HashSet<string> nsDefaults = new HashSet<string>(ControllerBuilder.DefaultNamespaces, StringComparer.OrdinalIgnoreCase);
+                match = GetControllerTypeWithinNamespaces(requestContext.RouteData.Route, controllerName, nsDefaults);
+                if (match != null) {
+                    return match;
+                }
+            }
+
+            // if all else fails, search every namespace
+            return GetControllerTypeWithinNamespaces(requestContext.RouteData.Route, controllerName, null /* namespaces */);
+        }
+
+        private Type GetControllerTypeWithinNamespaces(RouteBase route, string controllerName, HashSet<string> namespaces) {
+            // Once the master list of controllers has been created we can quickly index into it
+            ControllerTypeCache.EnsureInitialized(BuildManager);
+
+            ICollection<Type> matchingTypes = ControllerTypeCache.GetControllerTypes(controllerName, namespaces);
+            switch (matchingTypes.Count) {
+                case 0:
+                    // no matching types
+                    return null;
+
+                case 1:
+                    // single matching type
+                    return matchingTypes.First();
+
+                default:
+                    // multiple matching types
+                    throw CreateAmbiguousControllerException(route, controllerName, matchingTypes);
+            }
+        }
+
+        public virtual void ReleaseController(IController controller) {
+            IDisposable disposable = controller as IDisposable;
+            if (disposable != null) {
+                disposable.Dispose();
+            }
+        }
+
+        SessionStateBehavior IControllerFactory.GetControllerSessionBehavior(RequestContext requestContext, string controllerName) {
+            if (requestContext == null) {
+                throw new ArgumentNullException("requestContext");
+            }
+            if (String.IsNullOrEmpty(controllerName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "controllerName");
+            }
+
+            Type controllerType = GetControllerType(requestContext, controllerName);
+            return GetControllerSessionBehavior(requestContext, controllerType);
+        }
+
+        private class DefaultControllerActivator : IControllerActivator {
+            Func<IDependencyResolver> _resolverThunk;
+
+            public DefaultControllerActivator()
+                : this(null) {
+            }
+
+            public DefaultControllerActivator(IDependencyResolver resolver) {
+                if (resolver == null) {
+                    _resolverThunk = () => DependencyResolver.Current;
+                }
+                else {
+                    _resolverThunk = () => resolver;
+                }
+            }
+
+            public IController Create(RequestContext requestContext, Type controllerType) {
+                try {
+                    return (IController)(_resolverThunk().GetService(controllerType) ?? Activator.CreateInstance(controllerType));
+                }
+                catch (Exception ex) {
+                    throw new InvalidOperationException(
+                        String.Format(
+                            CultureInfo.CurrentCulture,
+                            MvcResources.DefaultControllerFactory_ErrorCreatingController,
+                            controllerType),
+                        ex);
+                }
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/DefaultModelBinder.cs b/mcs/class/System.Web.Mvc3/Mvc/DefaultModelBinder.cs
new file mode 100644 (file)
index 0000000..065e3ad
--- /dev/null
@@ -0,0 +1,706 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.ComponentModel;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Linq;
+    using System.Reflection;
+    using System.Runtime.CompilerServices;
+    using System.Web.Mvc.Resources;
+
+    public class DefaultModelBinder : IModelBinder {
+
+        private ModelBinderDictionary _binders;
+        private static string _resourceClassKey;
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Property is settable so that the dictionary can be provided for unit testing purposes.")]
+        protected internal ModelBinderDictionary Binders {
+            get {
+                if (_binders == null) {
+                    _binders = ModelBinders.Binders;
+                }
+                return _binders;
+            }
+            set {
+                _binders = value;
+            }
+        }
+
+        public static string ResourceClassKey {
+            get {
+                return _resourceClassKey ?? String.Empty;
+            }
+            set {
+                _resourceClassKey = value;
+            }
+        }
+
+        private static void AddValueRequiredMessageToModelState(ControllerContext controllerContext, ModelStateDictionary modelState, string modelStateKey, Type elementType, object value) {
+            if (value == null && !TypeHelpers.TypeAllowsNullValue(elementType) && modelState.IsValidField(modelStateKey)) {
+                modelState.AddModelError(modelStateKey, GetValueRequiredResource(controllerContext));
+            }
+        }
+
+        internal void BindComplexElementalModel(ControllerContext controllerContext, ModelBindingContext bindingContext, object model) {
+            // need to replace the property filter + model object and create an inner binding context
+            ModelBindingContext newBindingContext = CreateComplexElementalModelBindingContext(controllerContext, bindingContext, model);
+
+            // validation
+            if (OnModelUpdating(controllerContext, newBindingContext)) {
+                BindProperties(controllerContext, newBindingContext);
+                OnModelUpdated(controllerContext, newBindingContext);
+            }
+        }
+
+        internal object BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {
+            object model = bindingContext.Model;
+            Type modelType = bindingContext.ModelType;
+
+            // if we're being asked to create an array, create a list instead, then coerce to an array after the list is created
+            if (model == null && modelType.IsArray) {
+                Type elementType = modelType.GetElementType();
+                Type listType = typeof(List<>).MakeGenericType(elementType);
+                object collection = CreateModel(controllerContext, bindingContext, listType);
+
+                ModelBindingContext arrayBindingContext = new ModelBindingContext() {
+                    ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => collection, listType),
+                    ModelName = bindingContext.ModelName,
+                    ModelState = bindingContext.ModelState,
+                    PropertyFilter = bindingContext.PropertyFilter,
+                    ValueProvider = bindingContext.ValueProvider
+                };
+                IList list = (IList)UpdateCollection(controllerContext, arrayBindingContext, elementType);
+
+                if (list == null) {
+                    return null;
+                }
+
+                Array array = Array.CreateInstance(elementType, list.Count);
+                list.CopyTo(array, 0);
+                return array;
+            }
+
+            if (model == null) {
+                model = CreateModel(controllerContext, bindingContext, modelType);
+            }
+
+            // special-case IDictionary<,> and ICollection<>
+            Type dictionaryType = TypeHelpers.ExtractGenericInterface(modelType, typeof(IDictionary<,>));
+            if (dictionaryType != null) {
+                Type[] genericArguments = dictionaryType.GetGenericArguments();
+                Type keyType = genericArguments[0];
+                Type valueType = genericArguments[1];
+
+                ModelBindingContext dictionaryBindingContext = new ModelBindingContext() {
+                    ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, modelType),
+                    ModelName = bindingContext.ModelName,
+                    ModelState = bindingContext.ModelState,
+                    PropertyFilter = bindingContext.PropertyFilter,
+                    ValueProvider = bindingContext.ValueProvider
+                };
+                object dictionary = UpdateDictionary(controllerContext, dictionaryBindingContext, keyType, valueType);
+                return dictionary;
+            }
+
+            Type enumerableType = TypeHelpers.ExtractGenericInterface(modelType, typeof(IEnumerable<>));
+            if (enumerableType != null) {
+                Type elementType = enumerableType.GetGenericArguments()[0];
+
+                Type collectionType = typeof(ICollection<>).MakeGenericType(elementType);
+                if (collectionType.IsInstanceOfType(model)) {
+                    ModelBindingContext collectionBindingContext = new ModelBindingContext() {
+                        ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, modelType),
+                        ModelName = bindingContext.ModelName,
+                        ModelState = bindingContext.ModelState,
+                        PropertyFilter = bindingContext.PropertyFilter,
+                        ValueProvider = bindingContext.ValueProvider
+                    };
+                    object collection = UpdateCollection(controllerContext, collectionBindingContext, elementType);
+                    return collection;
+                }
+            }
+
+            // otherwise, just update the properties on the complex type
+            BindComplexElementalModel(controllerContext, bindingContext, model);
+            return model;
+        }
+
+        public virtual object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {
+            if (bindingContext == null) {
+                throw new ArgumentNullException("bindingContext");
+            }
+
+            bool performedFallback = false;
+
+            if (!String.IsNullOrEmpty(bindingContext.ModelName) && !bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName)) {
+                // We couldn't find any entry that began with the prefix. If this is the top-level element, fall back
+                // to the empty prefix.
+                if (bindingContext.FallbackToEmptyPrefix) {
+                    bindingContext = new ModelBindingContext() {
+                        ModelMetadata = bindingContext.ModelMetadata,
+                        ModelState = bindingContext.ModelState,
+                        PropertyFilter = bindingContext.PropertyFilter,
+                        ValueProvider = bindingContext.ValueProvider
+                    };
+                    performedFallback = true;
+                }
+                else {
+                    return null;
+                }
+            }
+
+            // Simple model = int, string, etc.; determined by calling TypeConverter.CanConvertFrom(typeof(string))
+            // or by seeing if a value in the request exactly matches the name of the model we're binding.
+            // Complex type = everything else.
+            if (!performedFallback) {
+                bool performRequestValidation = ShouldPerformRequestValidation(controllerContext, bindingContext);
+                ValueProviderResult vpResult = bindingContext.UnvalidatedValueProvider.GetValue(bindingContext.ModelName, skipValidation: !performRequestValidation);
+                if (vpResult != null) {
+                    return BindSimpleModel(controllerContext, bindingContext, vpResult);
+                }
+            }
+            if (!bindingContext.ModelMetadata.IsComplexType) {
+                return null;
+            }
+
+            return BindComplexModel(controllerContext, bindingContext);
+        }
+
+        private void BindProperties(ControllerContext controllerContext, ModelBindingContext bindingContext) {
+            IEnumerable<PropertyDescriptor> properties = GetFilteredModelProperties(controllerContext, bindingContext);
+            foreach (PropertyDescriptor property in properties) {
+                BindProperty(controllerContext, bindingContext, property);
+            }
+        }
+
+        protected virtual void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor) {
+            // need to skip properties that aren't part of the request, else we might hit a StackOverflowException
+            string fullPropertyKey = CreateSubPropertyName(bindingContext.ModelName, propertyDescriptor.Name);
+            if (!bindingContext.ValueProvider.ContainsPrefix(fullPropertyKey)) {
+                return;
+            }
+
+            // call into the property's model binder
+            IModelBinder propertyBinder = Binders.GetBinder(propertyDescriptor.PropertyType);
+            object originalPropertyValue = propertyDescriptor.GetValue(bindingContext.Model);
+            ModelMetadata propertyMetadata = bindingContext.PropertyMetadata[propertyDescriptor.Name];
+            propertyMetadata.Model = originalPropertyValue;
+            ModelBindingContext innerBindingContext = new ModelBindingContext() {
+                ModelMetadata = propertyMetadata,
+                ModelName = fullPropertyKey,
+                ModelState = bindingContext.ModelState,
+                ValueProvider = bindingContext.ValueProvider
+            };
+            object newPropertyValue = GetPropertyValue(controllerContext, innerBindingContext, propertyDescriptor, propertyBinder);
+            propertyMetadata.Model = newPropertyValue;
+
+            // validation
+            ModelState modelState = bindingContext.ModelState[fullPropertyKey];
+            if (modelState == null || modelState.Errors.Count == 0) {
+                if (OnPropertyValidating(controllerContext, bindingContext, propertyDescriptor, newPropertyValue)) {
+                    SetProperty(controllerContext, bindingContext, propertyDescriptor, newPropertyValue);
+                    OnPropertyValidated(controllerContext, bindingContext, propertyDescriptor, newPropertyValue);
+                }
+            }
+            else {
+                SetProperty(controllerContext, bindingContext, propertyDescriptor, newPropertyValue);
+
+                // Convert FormatExceptions (type conversion failures) into InvalidValue messages
+                foreach (ModelError error in modelState.Errors.Where(err => String.IsNullOrEmpty(err.ErrorMessage) && err.Exception != null).ToList()) {
+                    for (Exception exception = error.Exception; exception != null; exception = exception.InnerException) {
+                        if (exception is FormatException) {
+                            string displayName = propertyMetadata.GetDisplayName();
+                            string errorMessageTemplate = GetValueInvalidResource(controllerContext);
+                            string errorMessage = String.Format(CultureInfo.CurrentCulture, errorMessageTemplate, modelState.Value.AttemptedValue, displayName);
+                            modelState.Errors.Remove(error);
+                            modelState.Errors.Add(errorMessage);
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+
+        internal object BindSimpleModel(ControllerContext controllerContext, ModelBindingContext bindingContext, ValueProviderResult valueProviderResult) {
+            bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);
+
+            // if the value provider returns an instance of the requested data type, we can just short-circuit
+            // the evaluation and return that instance
+            if (bindingContext.ModelType.IsInstanceOfType(valueProviderResult.RawValue)) {
+                return valueProviderResult.RawValue;
+            }
+
+            // since a string is an IEnumerable<char>, we want it to skip the two checks immediately following
+            if (bindingContext.ModelType != typeof(string)) {
+
+                // conversion results in 3 cases, as below
+                if (bindingContext.ModelType.IsArray) {
+                    // case 1: user asked for an array
+                    // ValueProviderResult.ConvertTo() understands array types, so pass in the array type directly
+                    object modelArray = ConvertProviderResult(bindingContext.ModelState, bindingContext.ModelName, valueProviderResult, bindingContext.ModelType);
+                    return modelArray;
+                }
+
+                Type enumerableType = TypeHelpers.ExtractGenericInterface(bindingContext.ModelType, typeof(IEnumerable<>));
+                if (enumerableType != null) {
+                    // case 2: user asked for a collection rather than an array
+                    // need to call ConvertTo() on the array type, then copy the array to the collection
+                    object modelCollection = CreateModel(controllerContext, bindingContext, bindingContext.ModelType);
+                    Type elementType = enumerableType.GetGenericArguments()[0];
+                    Type arrayType = elementType.MakeArrayType();
+                    object modelArray = ConvertProviderResult(bindingContext.ModelState, bindingContext.ModelName, valueProviderResult, arrayType);
+
+                    Type collectionType = typeof(ICollection<>).MakeGenericType(elementType);
+                    if (collectionType.IsInstanceOfType(modelCollection)) {
+                        CollectionHelpers.ReplaceCollection(elementType, modelCollection, modelArray);
+                    }
+                    return modelCollection;
+                }
+            }
+
+            // case 3: user asked for an individual element
+            object model = ConvertProviderResult(bindingContext.ModelState, bindingContext.ModelName, valueProviderResult, bindingContext.ModelType);
+            return model;
+        }
+
+        private static bool CanUpdateReadonlyTypedReference(Type type) {
+            // value types aren't strictly immutable, but because they have copy-by-value semantics
+            // we can't update a value type that is marked readonly
+            if (type.IsValueType) {
+                return false;
+            }
+
+            // arrays are mutable, but because we can't change their length we shouldn't try
+            // to update an array that is referenced readonly
+            if (type.IsArray) {
+                return false;
+            }
+
+            // special-case known common immutable types
+            if (type == typeof(string)) {
+                return false;
+            }
+
+            return true;
+        }
+
+        [SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.Web.Mvc.ValueProviderResult.ConvertTo(System.Type)", Justification = "The target object should make the correct culture determination, not this method.")]
+        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "We're recording this exception so that we can act on it later.")]
+        private static object ConvertProviderResult(ModelStateDictionary modelState, string modelStateKey, ValueProviderResult valueProviderResult, Type destinationType) {
+            try {
+                object convertedValue = valueProviderResult.ConvertTo(destinationType);
+                return convertedValue;
+            }
+            catch (Exception ex) {
+                modelState.AddModelError(modelStateKey, ex);
+                return null;
+            }
+        }
+
+        internal ModelBindingContext CreateComplexElementalModelBindingContext(ControllerContext controllerContext, ModelBindingContext bindingContext, object model) {
+            BindAttribute bindAttr = (BindAttribute)GetTypeDescriptor(controllerContext, bindingContext).GetAttributes()[typeof(BindAttribute)];
+            Predicate<string> newPropertyFilter = (bindAttr != null)
+                ? propertyName => bindAttr.IsPropertyAllowed(propertyName) && bindingContext.PropertyFilter(propertyName)
+                : bindingContext.PropertyFilter;
+
+            ModelBindingContext newBindingContext = new ModelBindingContext() {
+                ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, bindingContext.ModelType),
+                ModelName = bindingContext.ModelName,
+                ModelState = bindingContext.ModelState,
+                PropertyFilter = newPropertyFilter,
+                ValueProvider = bindingContext.ValueProvider
+            };
+
+            return newBindingContext;
+        }
+
+        protected virtual object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) {
+            Type typeToCreate = modelType;
+
+            // we can understand some collection interfaces, e.g. IList<>, IDictionary<,>
+            if (modelType.IsGenericType) {
+                Type genericTypeDefinition = modelType.GetGenericTypeDefinition();
+                if (genericTypeDefinition == typeof(IDictionary<,>)) {
+                    typeToCreate = typeof(Dictionary<,>).MakeGenericType(modelType.GetGenericArguments());
+                }
+                else if (genericTypeDefinition == typeof(IEnumerable<>) || genericTypeDefinition == typeof(ICollection<>) || genericTypeDefinition == typeof(IList<>)) {
+                    typeToCreate = typeof(List<>).MakeGenericType(modelType.GetGenericArguments());
+                }
+            }
+
+            // fallback to the type's default constructor
+            return Activator.CreateInstance(typeToCreate);
+        }
+
+        protected static string CreateSubIndexName(string prefix, int index) {
+            return String.Format(CultureInfo.InvariantCulture, "{0}[{1}]", prefix, index);
+        }
+
+        protected static string CreateSubIndexName(string prefix, string index) {
+            return String.Format(CultureInfo.InvariantCulture, "{0}[{1}]", prefix, index);
+        }
+
+        protected internal static string CreateSubPropertyName(string prefix, string propertyName) {
+            if (String.IsNullOrEmpty(prefix)) {
+                return propertyName;
+            }
+            else if (String.IsNullOrEmpty(propertyName)) {
+                return prefix;
+            }
+            else {
+                return prefix + "." + propertyName;
+            }
+        }
+
+        protected IEnumerable<PropertyDescriptor> GetFilteredModelProperties(ControllerContext controllerContext, ModelBindingContext bindingContext) {
+            PropertyDescriptorCollection properties = GetModelProperties(controllerContext, bindingContext);
+            Predicate<string> propertyFilter = bindingContext.PropertyFilter;
+
+            return from PropertyDescriptor property in properties
+                   where ShouldUpdateProperty(property, propertyFilter)
+                   select property;
+        }
+
+        [SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.Web.Mvc.ValueProviderResult.ConvertTo(System.Type)", Justification = "ValueProviderResult already handles culture conversion appropriately.")]
+        private static void GetIndexes(ModelBindingContext bindingContext, out bool stopOnIndexNotFound, out IEnumerable<string> indexes) {
+            string indexKey = CreateSubPropertyName(bindingContext.ModelName, "index");
+            ValueProviderResult vpResult = bindingContext.ValueProvider.GetValue(indexKey);
+
+            if (vpResult != null) {
+                string[] indexesArray = vpResult.ConvertTo(typeof(string[])) as string[];
+                if (indexesArray != null) {
+                    stopOnIndexNotFound = false;
+                    indexes = indexesArray;
+                    return;
+                }
+            }
+
+            // just use a simple zero-based system
+            stopOnIndexNotFound = true;
+            indexes = GetZeroBasedIndexes();
+        }
+
+        protected virtual PropertyDescriptorCollection GetModelProperties(ControllerContext controllerContext, ModelBindingContext bindingContext) {
+            return GetTypeDescriptor(controllerContext, bindingContext).GetProperties();
+        }
+
+        protected virtual object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder) {
+            object value = propertyBinder.BindModel(controllerContext, bindingContext);
+
+            if (bindingContext.ModelMetadata.ConvertEmptyStringToNull && Object.Equals(value, String.Empty)) {
+                return null;
+            }
+
+            return value;
+        }
+
+        protected virtual ICustomTypeDescriptor GetTypeDescriptor(ControllerContext controllerContext, ModelBindingContext bindingContext) {
+            return TypeDescriptorHelper.Get(bindingContext.ModelType);
+        }
+
+        // If the user specified a ResourceClassKey try to load the resource they specified.
+        // If the class key is invalid, an exception will be thrown.
+        // If the class key is valid but the resource is not found, it returns null, in which
+        // case it will fall back to the MVC default error message.
+        private static string GetUserResourceString(ControllerContext controllerContext, string resourceName) {
+            string result = null;
+
+            if (!String.IsNullOrEmpty(ResourceClassKey) && (controllerContext != null) && (controllerContext.HttpContext != null)) {
+                result = controllerContext.HttpContext.GetGlobalResourceObject(ResourceClassKey, resourceName, CultureInfo.CurrentUICulture) as string;
+            }
+
+            return result;
+        }
+
+        private static string GetValueInvalidResource(ControllerContext controllerContext) {
+            return GetUserResourceString(controllerContext, "PropertyValueInvalid") ?? MvcResources.DefaultModelBinder_ValueInvalid;
+        }
+
+        private static string GetValueRequiredResource(ControllerContext controllerContext) {
+            return GetUserResourceString(controllerContext, "PropertyValueRequired") ?? MvcResources.DefaultModelBinder_ValueRequired;
+        }
+
+        private static IEnumerable<string> GetZeroBasedIndexes() {
+            for (int i = 0; ; i++) {
+                yield return i.ToString(CultureInfo.InvariantCulture);
+            }
+        }
+
+        protected static bool IsModelValid(ModelBindingContext bindingContext) {
+            if (bindingContext == null) {
+                throw new ArgumentNullException("bindingContext");
+            }
+            if (String.IsNullOrEmpty(bindingContext.ModelName)) {
+                return bindingContext.ModelState.IsValid;
+            }
+            return bindingContext.ModelState.IsValidField(bindingContext.ModelName);
+        }
+
+        protected virtual void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext) {
+            Dictionary<string, bool> startedValid = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
+
+            foreach (ModelValidationResult validationResult in ModelValidator.GetModelValidator(bindingContext.ModelMetadata, controllerContext).Validate(null)) {
+                string subPropertyName = CreateSubPropertyName(bindingContext.ModelName, validationResult.MemberName);
+
+                if (!startedValid.ContainsKey(subPropertyName)) {
+                    startedValid[subPropertyName] = bindingContext.ModelState.IsValidField(subPropertyName);
+                }
+
+                if (startedValid[subPropertyName]) {
+                    bindingContext.ModelState.AddModelError(subPropertyName, validationResult.Message);
+                }
+            }
+        }
+
+        protected virtual bool OnModelUpdating(ControllerContext controllerContext, ModelBindingContext bindingContext) {
+            // default implementation does nothing
+            return true;
+        }
+
+        protected virtual void OnPropertyValidated(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, object value) {
+            // default implementation does nothing
+        }
+
+        protected virtual bool OnPropertyValidating(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, object value) {
+            // default implementation does nothing
+            return true;
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "We're recording this exception so that we can act on it later.")]
+        protected virtual void SetProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, object value) {
+
+            ModelMetadata propertyMetadata = bindingContext.PropertyMetadata[propertyDescriptor.Name];
+            propertyMetadata.Model = value;
+            string modelStateKey = CreateSubPropertyName(bindingContext.ModelName, propertyMetadata.PropertyName);
+
+            // If the value is null, and the validation system can find a Required validator for
+            // us, we'd prefer to run it before we attempt to set the value; otherwise, property
+            // setters which throw on null (f.e., Entity Framework properties which are backed by
+            // non-nullable strings in the DB) will get their error message in ahead of us.
+            //
+            // We are effectively using the special validator -- Required -- as a helper to the
+            // binding system, which is why this code is here instead of in the Validating/Validated
+            // methods, which are really the old-school validation hooks.
+            if (value == null && bindingContext.ModelState.IsValidField(modelStateKey)) {
+                ModelValidator requiredValidator = ModelValidatorProviders.Providers.GetValidators(propertyMetadata, controllerContext).Where(v => v.IsRequired).FirstOrDefault();
+                if (requiredValidator != null) {
+                    foreach (ModelValidationResult validationResult in requiredValidator.Validate(bindingContext.Model)) {
+                        bindingContext.ModelState.AddModelError(modelStateKey, validationResult.Message);
+                    }
+                }
+            }
+
+            bool isNullValueOnNonNullableType =
+                value == null &&
+                !TypeHelpers.TypeAllowsNullValue(propertyDescriptor.PropertyType);
+
+            // Try to set a value into the property unless we know it will fail (read-only
+            // properties and null values with non-nullable types)
+            if (!propertyDescriptor.IsReadOnly && !isNullValueOnNonNullableType) {
+                try {
+                    propertyDescriptor.SetValue(bindingContext.Model, value);
+                }
+                catch (Exception ex) {
+                    // Only add if we're not already invalid
+                    if (bindingContext.ModelState.IsValidField(modelStateKey)) {
+                        bindingContext.ModelState.AddModelError(modelStateKey, ex);
+                    }
+                }
+            }
+
+            // Last chance for an error on null values with non-nullable types, we'll use
+            // the default "A value is required." message.
+            if (isNullValueOnNonNullableType && bindingContext.ModelState.IsValidField(modelStateKey)) {
+                bindingContext.ModelState.AddModelError(modelStateKey, GetValueRequiredResource(controllerContext));
+            }
+        }
+
+        private static bool ShouldPerformRequestValidation(ControllerContext controllerContext, ModelBindingContext bindingContext) {
+            if (controllerContext == null || controllerContext.Controller == null || bindingContext == null || bindingContext.ModelMetadata == null) {
+                // To make unit testing easier, if the caller hasn't specified enough contextual information we just default
+                // to always pulling the data from a collection that goes through request validation.
+                return true;
+            }
+
+            // We should perform request validation only if both the controller and the model ask for it. This is the
+            // default behavior for both. If either the controller (via [ValidateInput(false)]) or the model (via [AllowHtml])
+            // opts out, we don't validate.
+            return (controllerContext.Controller.ValidateRequest && bindingContext.ModelMetadata.RequestValidationEnabled);
+        }
+
+        private static bool ShouldUpdateProperty(PropertyDescriptor property, Predicate<string> propertyFilter) {
+            if (property.IsReadOnly && !CanUpdateReadonlyTypedReference(property.PropertyType)) {
+                return false;
+            }
+
+            // if this property is rejected by the filter, move on
+            if (!propertyFilter(property.Name)) {
+                return false;
+            }
+
+            // otherwise, allow
+            return true;
+        }
+
+        internal object UpdateCollection(ControllerContext controllerContext, ModelBindingContext bindingContext, Type elementType) {
+            bool stopOnIndexNotFound;
+            IEnumerable<string> indexes;
+            GetIndexes(bindingContext, out stopOnIndexNotFound, out indexes);
+            IModelBinder elementBinder = Binders.GetBinder(elementType);
+
+            // build up a list of items from the request
+            List<object> modelList = new List<object>();
+            foreach (string currentIndex in indexes) {
+                string subIndexKey = CreateSubIndexName(bindingContext.ModelName, currentIndex);
+                if (!bindingContext.ValueProvider.ContainsPrefix(subIndexKey)) {
+                    if (stopOnIndexNotFound) {
+                        // we ran out of elements to pull
+                        break;
+                    }
+                    else {
+                        continue;
+                    }
+                }
+
+                ModelBindingContext innerContext = new ModelBindingContext() {
+                    ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, elementType),
+                    ModelName = subIndexKey,
+                    ModelState = bindingContext.ModelState,
+                    PropertyFilter = bindingContext.PropertyFilter,
+                    ValueProvider = bindingContext.ValueProvider
+                };
+                object thisElement = elementBinder.BindModel(controllerContext, innerContext);
+
+                // we need to merge model errors up
+                AddValueRequiredMessageToModelState(controllerContext, bindingContext.ModelState, subIndexKey, elementType, thisElement);
+                modelList.Add(thisElement);
+            }
+
+            // if there weren't any elements at all in the request, just return
+            if (modelList.Count == 0) {
+                return null;
+            }
+
+            // replace the original collection
+            object collection = bindingContext.Model;
+            CollectionHelpers.ReplaceCollection(elementType, collection, modelList);
+            return collection;
+        }
+
+        internal object UpdateDictionary(ControllerContext controllerContext, ModelBindingContext bindingContext, Type keyType, Type valueType) {
+            bool stopOnIndexNotFound;
+            IEnumerable<string> indexes;
+            GetIndexes(bindingContext, out stopOnIndexNotFound, out indexes);
+
+            IModelBinder keyBinder = Binders.GetBinder(keyType);
+            IModelBinder valueBinder = Binders.GetBinder(valueType);
+
+            // build up a list of items from the request
+            List<KeyValuePair<object, object>> modelList = new List<KeyValuePair<object, object>>();
+            foreach (string currentIndex in indexes) {
+                string subIndexKey = CreateSubIndexName(bindingContext.ModelName, currentIndex);
+                string keyFieldKey = CreateSubPropertyName(subIndexKey, "key");
+                string valueFieldKey = CreateSubPropertyName(subIndexKey, "value");
+
+                if (!(bindingContext.ValueProvider.ContainsPrefix(keyFieldKey) && bindingContext.ValueProvider.ContainsPrefix(valueFieldKey))) {
+                    if (stopOnIndexNotFound) {
+                        // we ran out of elements to pull
+                        break;
+                    }
+                    else {
+                        continue;
+                    }
+                }
+
+                // bind the key
+                ModelBindingContext keyBindingContext = new ModelBindingContext() {
+                    ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, keyType),
+                    ModelName = keyFieldKey,
+                    ModelState = bindingContext.ModelState,
+                    ValueProvider = bindingContext.ValueProvider
+                };
+                object thisKey = keyBinder.BindModel(controllerContext, keyBindingContext);
+
+                // we need to merge model errors up
+                AddValueRequiredMessageToModelState(controllerContext, bindingContext.ModelState, keyFieldKey, keyType, thisKey);
+                if (!keyType.IsInstanceOfType(thisKey)) {
+                    // we can't add an invalid key, so just move on
+                    continue;
+                }
+
+                // bind the value
+                ModelBindingContext valueBindingContext = new ModelBindingContext() {
+                    ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, valueType),
+                    ModelName = valueFieldKey,
+                    ModelState = bindingContext.ModelState,
+                    PropertyFilter = bindingContext.PropertyFilter,
+                    ValueProvider = bindingContext.ValueProvider
+                };
+                object thisValue = valueBinder.BindModel(controllerContext, valueBindingContext);
+
+                // we need to merge model errors up
+                AddValueRequiredMessageToModelState(controllerContext, bindingContext.ModelState, valueFieldKey, valueType, thisValue);
+                KeyValuePair<object, object> kvp = new KeyValuePair<object, object>(thisKey, thisValue);
+                modelList.Add(kvp);
+            }
+
+            // if there weren't any elements at all in the request, just return
+            if (modelList.Count == 0) {
+                return null;
+            }
+
+            // replace the original collection
+            object dictionary = bindingContext.Model;
+            CollectionHelpers.ReplaceDictionary(keyType, valueType, dictionary, modelList);
+            return dictionary;
+        }
+
+        // This helper type is used because we're working with strongly-typed collections, but we don't know the Ts
+        // ahead of time. By using the generic methods below, we can consolidate the collection-specific code in a
+        // single helper type rather than having reflection-based calls spread throughout the DefaultModelBinder type.
+        // There is a single point of entry to each of the methods below, so they're fairly simple to maintain.
+
+        private static class CollectionHelpers {
+
+            private static readonly MethodInfo _replaceCollectionMethod = typeof(CollectionHelpers).GetMethod("ReplaceCollectionImpl", BindingFlags.Static | BindingFlags.NonPublic);
+            private static readonly MethodInfo _replaceDictionaryMethod = typeof(CollectionHelpers).GetMethod("ReplaceDictionaryImpl", BindingFlags.Static | BindingFlags.NonPublic);
+
+            [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
+            public static void ReplaceCollection(Type collectionType, object collection, object newContents) {
+                MethodInfo targetMethod = _replaceCollectionMethod.MakeGenericMethod(collectionType);
+                targetMethod.Invoke(null, new object[] { collection, newContents });
+            }
+
+            private static void ReplaceCollectionImpl<T>(ICollection<T> collection, IEnumerable newContents) {
+                collection.Clear();
+                if (newContents != null) {
+                    foreach (object item in newContents) {
+                        // if the item was not a T, some conversion failed. the error message will be propagated,
+                        // but in the meanwhile we need to make a placeholder element in the array.
+                        T castItem = (item is T) ? (T)item : default(T);
+                        collection.Add(castItem);
+                    }
+                }
+            }
+
+            [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
+            public static void ReplaceDictionary(Type keyType, Type valueType, object dictionary, object newContents) {
+                MethodInfo targetMethod = _replaceDictionaryMethod.MakeGenericMethod(keyType, valueType);
+                targetMethod.Invoke(null, new object[] { dictionary, newContents });
+            }
+
+            private static void ReplaceDictionaryImpl<TKey, TValue>(IDictionary<TKey, TValue> dictionary, IEnumerable<KeyValuePair<object, object>> newContents) {
+                dictionary.Clear();
+                foreach (KeyValuePair<object, object> item in newContents) {
+                    // if the item was not a T, some conversion failed. the error message will be propagated,
+                    // but in the meanwhile we need to make a placeholder element in the dictionary.
+                    TKey castKey = (TKey)item.Key; // this cast shouldn't fail
+                    TValue castValue = (item.Value is TValue) ? (TValue)item.Value : default(TValue);
+                    dictionary[castKey] = castValue;
+                }
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/DefaultViewLocationCache.cs b/mcs/class/System.Web.Mvc3/Mvc/DefaultViewLocationCache.cs
new file mode 100644 (file)
index 0000000..2f1232a
--- /dev/null
@@ -0,0 +1,45 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Web.Caching;
+    using System.Web.Mvc.Resources;
+
+    public class DefaultViewLocationCache : IViewLocationCache {
+        private static readonly TimeSpan _defaultTimeSpan = new TimeSpan(0, 15, 0);
+
+        public DefaultViewLocationCache()
+            : this(_defaultTimeSpan) {
+        }
+
+        public DefaultViewLocationCache(TimeSpan timeSpan) {
+            if (timeSpan.Ticks < 0) {
+                throw new InvalidOperationException(MvcResources.DefaultViewLocationCache_NegativeTimeSpan);
+            }
+            TimeSpan = timeSpan;
+        }
+
+        [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "The reference type is immutable. ")]
+        public static readonly IViewLocationCache Null = new NullViewLocationCache();
+
+        public TimeSpan TimeSpan {
+            get;
+            private set;
+        }
+
+        #region IViewLocationCache Members
+        public string GetViewLocation(HttpContextBase httpContext, string key) {
+            if (httpContext == null) {
+                throw new ArgumentNullException("httpContext");
+            }
+            return (string)httpContext.Cache[key];
+        }
+
+        public void InsertViewLocation(HttpContextBase httpContext, string key, string virtualPath) {
+            if (httpContext == null) {
+                throw new ArgumentNullException("httpContext");
+            }
+            httpContext.Cache.Insert(key, virtualPath, null /* dependencies */, Cache.NoAbsoluteExpiration, TimeSpan);
+        }
+        #endregion
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/DependencyResolver.cs b/mcs/class/System.Web.Mvc3/Mvc/DependencyResolver.cs
new file mode 100644 (file)
index 0000000..f61ccf8
--- /dev/null
@@ -0,0 +1,134 @@
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Linq;
+    using System.Reflection;
+    using System.Web.Mvc.Resources;
+
+    public class DependencyResolver {
+        // Static accessors
+
+        private static DependencyResolver _instance = new DependencyResolver();
+
+        public static IDependencyResolver Current {
+            get {
+                return _instance.InnerCurrent;
+            }
+        }
+
+        public static void SetResolver(IDependencyResolver resolver) {
+            _instance.InnerSetResolver(resolver);
+        }
+
+        public static void SetResolver(object commonServiceLocator) {
+            _instance.InnerSetResolver(commonServiceLocator);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types.")]
+        public static void SetResolver(Func<Type, object> getService, Func<Type, IEnumerable<object>> getServices) {
+            _instance.InnerSetResolver(getService, getServices);
+        }
+
+        // Instance implementation (for testing purposes)
+
+        private IDependencyResolver _current = new DefaultDependencyResolver();
+
+        public IDependencyResolver InnerCurrent {
+            get {
+                return _current;
+            }
+        }
+
+        public void InnerSetResolver(IDependencyResolver resolver) {
+            if (resolver == null) {
+                throw new ArgumentNullException("resolver");
+            }
+
+            _current = resolver;
+        }
+
+        public void InnerSetResolver(object commonServiceLocator) {
+            if (commonServiceLocator == null) {
+                throw new ArgumentNullException("commonServiceLocator");
+            }
+
+            Type locatorType = commonServiceLocator.GetType();
+            MethodInfo getInstance = locatorType.GetMethod("GetInstance", new[] { typeof(Type) });
+            MethodInfo getInstances = locatorType.GetMethod("GetAllInstances", new[] { typeof(Type) });
+
+            if (getInstance == null ||
+                getInstance.ReturnType != typeof(object) ||
+                getInstances == null ||
+                getInstances.ReturnType != typeof(IEnumerable<object>)) {
+                throw new ArgumentException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.DependencyResolver_DoesNotImplementICommonServiceLocator,
+                        locatorType.FullName
+                    ),
+                    "commonServiceLocator"
+                );
+            }
+
+            var getService = (Func<Type, object>)Delegate.CreateDelegate(typeof(Func<Type, object>), commonServiceLocator, getInstance);
+            var getServices = (Func<Type, IEnumerable<object>>)Delegate.CreateDelegate(typeof(Func<Type, IEnumerable<object>>), commonServiceLocator, getInstances);
+
+            _current = new DelegateBasedDependencyResolver(getService, getServices);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types.")]
+        public void InnerSetResolver(Func<Type, object> getService, Func<Type, IEnumerable<object>> getServices) {
+            if (getService == null) {
+                throw new ArgumentNullException("getService");
+            }
+            if (getServices == null) {
+                throw new ArgumentNullException("getServices");
+            }
+
+            _current = new DelegateBasedDependencyResolver(getService, getServices);
+        }
+
+        // Helper classes
+
+        private class DelegateBasedDependencyResolver : IDependencyResolver {
+            Func<Type, object> _getService;
+            Func<Type, IEnumerable<object>> _getServices;
+
+            public DelegateBasedDependencyResolver(Func<Type, object> getService, Func<Type, IEnumerable<object>> getServices) {
+                _getService = getService;
+                _getServices = getServices;
+            }
+
+            [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "This method might throw exceptions whose type we cannot strongly link against; namely, ActivationException from common service locator")]
+            public object GetService(Type type) {
+                try {
+                    return _getService.Invoke(type);
+                }
+                catch {
+                    return null;
+                }
+            }
+
+            public IEnumerable<object> GetServices(Type type) {
+                return _getServices(type);
+            }
+        }
+
+        private class DefaultDependencyResolver : IDependencyResolver {
+            [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "This method might throw exceptions whose type we cannot strongly link against; namely, ActivationException from common service locator")]
+            public object GetService(Type serviceType) {
+                try {
+                    return Activator.CreateInstance(serviceType);
+                }
+                catch {
+                    return null;
+                }
+            }
+
+            public IEnumerable<object> GetServices(Type serviceType) {
+                return Enumerable.Empty<object>();
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/DependencyResolverExtensions.cs b/mcs/class/System.Web.Mvc3/Mvc/DependencyResolverExtensions.cs
new file mode 100644 (file)
index 0000000..deaec59
--- /dev/null
@@ -0,0 +1,15 @@
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+    using System.Linq;
+    using System.Runtime.Serialization;
+
+    public static class DependencyResolverExtensions {
+        public static TService GetService<TService>(this IDependencyResolver resolver) {
+            return (TService)resolver.GetService(typeof(TService));
+        }
+
+        public static IEnumerable<TService> GetServices<TService>(this IDependencyResolver resolver) {
+            return resolver.GetServices(typeof(TService)).Cast<TService>();
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/DescriptorUtil.cs b/mcs/class/System.Web.Mvc3/Mvc/DescriptorUtil.cs
new file mode 100644 (file)
index 0000000..e005c45
--- /dev/null
@@ -0,0 +1,65 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Globalization;
+    using System.Linq;
+    using System.Reflection;
+    using System.Text;
+    using System.Threading;
+
+    internal static class DescriptorUtil {
+
+        private static void AppendPartToUniqueIdBuilder(StringBuilder builder, object part) {
+            if (part == null) {
+                builder.Append("[-1]");
+            }
+            else {
+                string partString = Convert.ToString(part, CultureInfo.InvariantCulture);
+                builder.AppendFormat("[{0}]{1}", partString.Length, partString);
+            }
+        }
+
+        public static string CreateUniqueId(params object[] parts) {
+            return CreateUniqueId((IEnumerable<object>)parts);
+        }
+
+        public static string CreateUniqueId(IEnumerable<object> parts) {
+            // returns a unique string made up of the pieces passed in
+            StringBuilder builder = new StringBuilder();
+            foreach (object part in parts) {
+                // We can special-case certain part types
+
+                MemberInfo memberInfo = part as MemberInfo;
+                if (memberInfo != null) {
+                    AppendPartToUniqueIdBuilder(builder, memberInfo.Module.ModuleVersionId);
+                    AppendPartToUniqueIdBuilder(builder, memberInfo.MetadataToken);
+                    continue;
+                }
+
+                IUniquelyIdentifiable uniquelyIdentifiable = part as IUniquelyIdentifiable;
+                if (uniquelyIdentifiable != null) {
+                    AppendPartToUniqueIdBuilder(builder, uniquelyIdentifiable.UniqueId);
+                    continue;
+                }
+
+                AppendPartToUniqueIdBuilder(builder, part);
+            }
+
+            return builder.ToString();
+        }
+
+        public static TDescriptor[] LazilyFetchOrCreateDescriptors<TReflection, TDescriptor>(ref TDescriptor[] cacheLocation, Func<TReflection[]> initializer, Func<TReflection, TDescriptor> converter) {
+            // did we already calculate this once?
+            TDescriptor[] existingCache = Interlocked.CompareExchange(ref cacheLocation, null, null);
+            if (existingCache != null) {
+                return existingCache;
+            }
+
+            TReflection[] memberInfos = initializer();
+            TDescriptor[] descriptors = memberInfos.Select(converter).Where(descriptor => descriptor != null).ToArray();
+            TDescriptor[] updatedCache = Interlocked.CompareExchange(ref cacheLocation, descriptors, null);
+            return updatedCache ?? descriptors;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/DictionaryHelpers.cs b/mcs/class/System.Web.Mvc3/Mvc/DictionaryHelpers.cs
new file mode 100644 (file)
index 0000000..67dadac
--- /dev/null
@@ -0,0 +1,40 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Linq;
+
+    internal static class DictionaryHelpers {
+
+        public static IEnumerable<KeyValuePair<string, TValue>> FindKeysWithPrefix<TValue>(IDictionary<string, TValue> dictionary, string prefix) {
+            TValue exactMatchValue;
+            if (dictionary.TryGetValue(prefix, out exactMatchValue)) {
+                yield return new KeyValuePair<string, TValue>(prefix, exactMatchValue);
+            }
+
+            foreach (var entry in dictionary) {
+                string key = entry.Key;
+
+                if (key.Length <= prefix.Length) {
+                    continue;
+                }
+
+                if (!key.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) {
+                    continue;
+                }
+
+                char charAfterPrefix = key[prefix.Length];
+                switch (charAfterPrefix) {
+                    case '[':
+                    case '.':
+                        yield return entry;
+                        break;
+                }
+            }
+        }
+
+        public static bool DoesAnyKeyHavePrefix<TValue>(IDictionary<string, TValue> dictionary, string prefix) {
+            return FindKeysWithPrefix(dictionary, prefix).Any();
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/DictionaryValueProvider`1.cs b/mcs/class/System.Web.Mvc3/Mvc/DictionaryValueProvider`1.cs
new file mode 100644 (file)
index 0000000..eed1a1c
--- /dev/null
@@ -0,0 +1,52 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Globalization;
+
+    public class DictionaryValueProvider<TValue> : IValueProvider {
+
+        private readonly HashSet<string> _prefixes = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
+        private readonly Dictionary<string, ValueProviderResult> _values = new Dictionary<string, ValueProviderResult>(StringComparer.OrdinalIgnoreCase);
+
+        public DictionaryValueProvider(IDictionary<string, TValue> dictionary, CultureInfo culture) {
+            if (dictionary == null) {
+                throw new ArgumentNullException("dictionary");
+            }
+
+            AddValues(dictionary, culture);
+        }
+
+        private void AddValues(IDictionary<string, TValue> dictionary, CultureInfo culture) {
+            if (dictionary.Count > 0) {
+                _prefixes.Add("");
+            }
+
+            foreach (var entry in dictionary) {
+                _prefixes.UnionWith(ValueProviderUtil.GetPrefixes(entry.Key));
+
+                object rawValue = entry.Value;
+                string attemptedValue = Convert.ToString(rawValue, culture);
+                _values[entry.Key] = new ValueProviderResult(rawValue, attemptedValue, culture);
+            }
+        }
+
+        public virtual bool ContainsPrefix(string prefix) {
+            if (prefix == null) {
+                throw new ArgumentNullException("prefix");
+            }
+
+            return _prefixes.Contains(prefix);
+        }
+
+        public virtual ValueProviderResult GetValue(string key) {
+            if (key == null) {
+                throw new ArgumentNullException("key");
+            }
+
+            ValueProviderResult vpResult;
+            _values.TryGetValue(key, out vpResult);
+            return vpResult;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/DynamicViewDataDictionary.cs b/mcs/class/System.Web.Mvc3/Mvc/DynamicViewDataDictionary.cs
new file mode 100644 (file)
index 0000000..2844e74
--- /dev/null
@@ -0,0 +1,39 @@
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+    using System.Diagnostics;
+    using System.Dynamic;
+
+    internal sealed class DynamicViewDataDictionary : DynamicObject {
+        private readonly Func<ViewDataDictionary> _viewDataThunk;
+
+        public DynamicViewDataDictionary(Func<ViewDataDictionary> viewDataThunk) {
+            _viewDataThunk = viewDataThunk;
+        }
+
+        private ViewDataDictionary ViewData {
+            get {
+                ViewDataDictionary viewData = _viewDataThunk();
+                Debug.Assert(viewData != null);
+                return viewData;
+            }
+        }
+
+        // Implementing this function improves the debugging experience as it provides the debugger with the list of all
+        // the properties currently defined on the object
+        public override IEnumerable<string> GetDynamicMemberNames() {
+            return ViewData.Keys;
+        }
+
+        public override bool TryGetMember(GetMemberBinder binder, out object result) {
+            result = ViewData[binder.Name];
+            // since ViewDataDictionary always returns a result even if the key does not exist, always return true
+            return true;
+        }
+
+        public override bool TrySetMember(SetMemberBinder binder, object value) {
+            ViewData[binder.Name] = value;
+            // you can always set a key in the dictionary so return true
+            return true;
+        }
+    }
+}
\ No newline at end of file
diff --git a/mcs/class/System.Web.Mvc3/Mvc/EmptyModelMetadataProvider.cs b/mcs/class/System.Web.Mvc3/Mvc/EmptyModelMetadataProvider.cs
new file mode 100644 (file)
index 0000000..dfb9a08
--- /dev/null
@@ -0,0 +1,11 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Reflection;
+
+    public class EmptyModelMetadataProvider : AssociatedMetadataProvider {
+        protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName) {
+            return new ModelMetadata(this, containerType, modelAccessor, modelType, propertyName);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/EmptyModelValidatorProvider.cs b/mcs/class/System.Web.Mvc3/Mvc/EmptyModelValidatorProvider.cs
new file mode 100644 (file)
index 0000000..2221881
--- /dev/null
@@ -0,0 +1,10 @@
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+    using System.Linq;
+
+    public class EmptyModelValidatorProvider : ModelValidatorProvider {
+        public override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context) {
+            return Enumerable.Empty<ModelValidator>();
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/EmptyResult.cs b/mcs/class/System.Web.Mvc3/Mvc/EmptyResult.cs
new file mode 100644 (file)
index 0000000..8438282
--- /dev/null
@@ -0,0 +1,17 @@
+namespace System.Web.Mvc {
+
+    // represents a result that doesn't do anything, like a controller action returning null
+    public class EmptyResult : ActionResult {
+
+        private static readonly EmptyResult _singleton = new EmptyResult();
+
+        internal static EmptyResult Instance {
+            get {
+                return _singleton;
+            }
+        }
+
+        public override void ExecuteResult(ControllerContext context) {
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Error.cs b/mcs/class/System.Web.Mvc3/Mvc/Error.cs
new file mode 100644 (file)
index 0000000..642b0e3
--- /dev/null
@@ -0,0 +1,72 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Globalization;
+    using System.Web.Mvc.Async;
+    using System.Web.Mvc.Resources;
+
+    internal static class Error {
+
+        public static InvalidOperationException AsyncActionMethodSelector_CouldNotFindMethod(string methodName, Type controllerType) {
+            string message = String.Format(CultureInfo.CurrentCulture, MvcResources.AsyncActionMethodSelector_CouldNotFindMethod,
+                methodName, controllerType);
+            return new InvalidOperationException(message);
+        }
+
+        public static InvalidOperationException AsyncCommon_AsyncResultAlreadyConsumed() {
+            return new InvalidOperationException(MvcResources.AsyncCommon_AsyncResultAlreadyConsumed);
+        }
+
+        public static InvalidOperationException AsyncCommon_ControllerMustImplementIAsyncManagerContainer(Type actualControllerType) {
+            string message = String.Format(CultureInfo.CurrentCulture, MvcResources.AsyncCommon_ControllerMustImplementIAsyncManagerContainer,
+                actualControllerType);
+            return new InvalidOperationException(message);
+        }
+
+        public static ArgumentException AsyncCommon_InvalidAsyncResult(string parameterName) {
+            return new ArgumentException(MvcResources.AsyncCommon_InvalidAsyncResult, parameterName);
+        }
+
+        public static ArgumentOutOfRangeException AsyncCommon_InvalidTimeout(string parameterName) {
+            return new ArgumentOutOfRangeException(parameterName, MvcResources.AsyncCommon_InvalidTimeout);
+        }
+
+        public static InvalidOperationException ReflectedAsyncActionDescriptor_CannotExecuteSynchronously(string actionName) {
+            string message = String.Format(CultureInfo.CurrentCulture, MvcResources.ReflectedAsyncActionDescriptor_CannotExecuteSynchronously,
+                actionName);
+            return new InvalidOperationException(message);
+        }
+
+        public static InvalidOperationException ChildActionOnlyAttribute_MustBeInChildRequest(ActionDescriptor actionDescriptor) {
+            string message = String.Format(CultureInfo.CurrentCulture, MvcResources.ChildActionOnlyAttribute_MustBeInChildRequest,
+                actionDescriptor.ActionName);
+            return new InvalidOperationException(message);
+        }
+
+        public static ArgumentException ParameterCannotBeNullOrEmpty(string parameterName) {
+            return new ArgumentException(MvcResources.Common_NullOrEmpty, parameterName);
+        }
+
+        public static InvalidOperationException PropertyCannotBeNullOrEmpty(string propertyName) {
+            string message = String.Format(CultureInfo.CurrentCulture, MvcResources.Common_PropertyCannotBeNullOrEmpty,
+                propertyName);
+            return new InvalidOperationException(message);
+        }
+
+        public static SynchronousOperationException SynchronizationContextUtil_ExceptionThrown(Exception innerException) {
+            return new SynchronousOperationException(MvcResources.SynchronizationContextUtil_ExceptionThrown, innerException);
+        }
+
+        public static InvalidOperationException ViewDataDictionary_WrongTModelType(Type valueType, Type modelType) {
+            string message = String.Format(CultureInfo.CurrentCulture, MvcResources.ViewDataDictionary_WrongTModelType,
+                valueType, modelType);
+            return new InvalidOperationException(message);
+        }
+
+        public static InvalidOperationException ViewDataDictionary_ModelCannotBeNull(Type modelType) {
+            string message = String.Format(CultureInfo.CurrentCulture, MvcResources.ViewDataDictionary_ModelCannotBeNull,
+                modelType);
+            return new InvalidOperationException(message);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ExceptionContext.cs b/mcs/class/System.Web.Mvc3/Mvc/ExceptionContext.cs
new file mode 100644 (file)
index 0000000..7fd58ce
--- /dev/null
@@ -0,0 +1,43 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+
+    public class ExceptionContext : ControllerContext {
+
+        private ActionResult _result;
+
+        // parameterless constructor used for mocking
+        public ExceptionContext() {
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", Justification = "The virtual property setters are only to support mocking frameworks, in which case this constructor shouldn't be called anyway.")]
+        public ExceptionContext(ControllerContext controllerContext, Exception exception)
+            : base(controllerContext) {
+            if (exception == null) {
+                throw new ArgumentNullException("exception");
+            }
+
+            Exception = exception;
+        }
+
+        public virtual Exception Exception {
+            get;
+            set;
+        }
+
+        public bool ExceptionHandled {
+            get;
+            set;
+        }
+
+        public ActionResult Result {
+            get {
+                return _result ?? EmptyResult.Instance;
+            }
+            set {
+                _result = value;
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ExpressionHelper.cs b/mcs/class/System.Web.Mvc3/Mvc/ExpressionHelper.cs
new file mode 100644 (file)
index 0000000..3cf5255
--- /dev/null
@@ -0,0 +1,119 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Globalization;
+    using System.Linq;
+    using System.Linq.Expressions;
+    using System.Reflection;
+    using System.Web.Mvc.Resources;
+
+    public static class ExpressionHelper {
+        public static string GetExpressionText(string expression) {
+            return
+                String.Equals(expression, "model", StringComparison.OrdinalIgnoreCase)
+                    ? String.Empty    // If it's exactly "model", then give them an empty string, to replicate the lambda behavior
+                    : expression;
+        }
+
+        public static string GetExpressionText(LambdaExpression expression) {
+            // Split apart the expression string for property/field accessors to create its name
+            Stack<string> nameParts = new Stack<string>();
+            Expression part = expression.Body;
+
+            while (part != null) {
+                if (part.NodeType == ExpressionType.Call) {
+                    MethodCallExpression methodExpression = (MethodCallExpression)part;
+
+                    if (!IsSingleArgumentIndexer(methodExpression)) {
+                        break;
+                    }
+
+                    nameParts.Push(
+                        GetIndexerInvocation(
+                            methodExpression.Arguments.Single(),
+                            expression.Parameters.ToArray()
+                        )
+                    );
+
+                    part = methodExpression.Object;
+                }
+                else if (part.NodeType == ExpressionType.ArrayIndex) {
+                    BinaryExpression binaryExpression = (BinaryExpression)part;
+
+                    nameParts.Push(
+                        GetIndexerInvocation(
+                            binaryExpression.Right,
+                            expression.Parameters.ToArray()
+                        )
+                    );
+
+                    part = binaryExpression.Left;
+                }
+                else if (part.NodeType == ExpressionType.MemberAccess) {
+                    MemberExpression memberExpressionPart = (MemberExpression)part;
+                    nameParts.Push("." + memberExpressionPart.Member.Name);
+                    part = memberExpressionPart.Expression;
+                }
+                else if (part.NodeType == ExpressionType.Parameter) {
+                    // Dev10 Bug #907611
+                    // When the expression is parameter based (m => m.Something...), we'll push an empty
+                    // string onto the stack and stop evaluating. The extra empty string makes sure that
+                    // we don't accidentally cut off too much of m => m.Model.
+                    nameParts.Push(String.Empty);
+                    part = null;
+                }
+                else {
+                    break;
+                }
+            }
+
+            // If it starts with "model", then strip that away
+            if (nameParts.Count > 0 && String.Equals(nameParts.Peek(), ".model", StringComparison.OrdinalIgnoreCase)) {
+                nameParts.Pop();
+            }
+
+            if (nameParts.Count > 0) {
+                return nameParts.Aggregate((left, right) => left + right).TrimStart('.');
+            }
+
+            return String.Empty;
+        }
+
+        private static string GetIndexerInvocation(Expression expression, ParameterExpression[] parameters) {
+            Expression converted = Expression.Convert(expression, typeof(object));
+            ParameterExpression fakeParameter = Expression.Parameter(typeof(object), null);
+            Expression<Func<object, object>> lambda = Expression.Lambda<Func<object, object>>(converted, fakeParameter);
+            Func<object, object> func;
+
+            try {
+                func = ExpressionUtil.CachedExpressionCompiler.Process(lambda);
+            }
+            catch (InvalidOperationException ex) {
+                throw new InvalidOperationException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.ExpressionHelper_InvalidIndexerExpression,
+                        expression,
+                        parameters[0].Name
+                    ),
+                    ex
+                );
+            }
+
+            return "[" + Convert.ToString(func(null), CultureInfo.InvariantCulture) + "]";
+        }
+
+        internal static bool IsSingleArgumentIndexer(Expression expression) {
+            MethodCallExpression methodExpression = expression as MethodCallExpression;
+            if (methodExpression == null || methodExpression.Arguments.Count != 1) {
+                return false;
+            }
+
+            return methodExpression.Method
+                                   .DeclaringType
+                                   .GetDefaultMembers()
+                                   .OfType<PropertyInfo>()
+                                   .Any(p => p.GetGetMethod() == methodExpression.Method);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/BinaryExpressionFingerprint.cs b/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/BinaryExpressionFingerprint.cs
new file mode 100644 (file)
index 0000000..1b44e7e
--- /dev/null
@@ -0,0 +1,40 @@
+#pragma warning disable 659 // overrides AddToHashCodeCombiner instead
+
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq.Expressions;
+    using System.Reflection;
+
+    // BinaryExpression fingerprint class
+    // Useful for things like array[index]
+
+    [SuppressMessage("Microsoft.Usage", "CA2218:OverrideGetHashCodeOnOverridingEquals", Justification = "Overrides AddToHashCodeCombiner() instead.")]
+    internal sealed class BinaryExpressionFingerprint : ExpressionFingerprint {
+
+        public BinaryExpressionFingerprint(ExpressionType nodeType, Type type, MethodInfo method)
+            : base(nodeType, type) {
+
+            // Other properties on BinaryExpression (like IsLifted / IsLiftedToNull) are simply derived
+            // from Type and NodeType, so they're not necessary for inclusion in the fingerprint.
+
+            Method = method;
+        }
+
+        // http://msdn.microsoft.com/en-us/library/system.linq.expressions.binaryexpression.method.aspx
+        public MethodInfo Method { get; private set; }
+
+        public override bool Equals(object obj) {
+            BinaryExpressionFingerprint other = obj as BinaryExpressionFingerprint;
+            return (other != null)
+                && Equals(this.Method, other.Method)
+                && this.Equals(other);
+        }
+
+        internal override void AddToHashCodeCombiner(HashCodeCombiner combiner) {
+            combiner.AddObject(Method);
+            base.AddToHashCodeCombiner(combiner);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/CachedExpressionCompiler.cs b/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/CachedExpressionCompiler.cs
new file mode 100644 (file)
index 0000000..58a62cd
--- /dev/null
@@ -0,0 +1,126 @@
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+    using System.Collections.Concurrent;
+    using System.Collections.Generic;
+    using System.Linq.Expressions;
+    using System.Reflection;
+
+    internal static class CachedExpressionCompiler {
+
+        // This is the entry point to the cached expression compilation system. The system
+        // will try to turn the expression into an actual delegate as quickly as possible,
+        // relying on cache lookups and other techniques to save time if appropriate.
+        // If the provided expression is particularly obscure and the system doesn't know
+        // how to handle it, we'll just compile the expression as normal.
+        public static Func<TModel, TValue> Process<TModel, TValue>(Expression<Func<TModel, TValue>> lambdaExpression) {
+            return Compiler<TModel, TValue>.Compile(lambdaExpression);
+        }
+
+        private static class Compiler<TIn, TOut> {
+            private static Func<TIn, TOut> _identityFunc;
+
+            private static readonly ConcurrentDictionary<MemberInfo, Func<TIn, TOut>> _simpleMemberAccessDict =
+                new ConcurrentDictionary<MemberInfo, Func<TIn, TOut>>();
+
+            private static readonly ConcurrentDictionary<MemberInfo, Func<object, TOut>> _constMemberAccessDict =
+                new ConcurrentDictionary<MemberInfo, Func<object, TOut>>();
+
+            private static readonly ConcurrentDictionary<ExpressionFingerprintChain, Hoisted<TIn, TOut>> _fingerprintedCache =
+                new ConcurrentDictionary<ExpressionFingerprintChain, Hoisted<TIn, TOut>>();
+
+            public static Func<TIn, TOut> Compile(Expression<Func<TIn, TOut>> expr) {
+                return CompileFromIdentityFunc(expr)
+                    ?? CompileFromConstLookup(expr)
+                    ?? CompileFromMemberAccess(expr)
+                    ?? CompileFromFingerprint(expr)
+                    ?? CompileSlow(expr);
+            }
+
+            private static Func<TIn, TOut> CompileFromConstLookup(Expression<Func<TIn, TOut>> expr) {
+                ConstantExpression constExpr = expr.Body as ConstantExpression;
+                if (constExpr != null) {
+                    // model => {const}
+
+                    TOut constantValue = (TOut)constExpr.Value;
+                    return _ => constantValue;
+                }
+
+                return null;
+            }
+
+            private static Func<TIn, TOut> CompileFromIdentityFunc(Expression<Func<TIn, TOut>> expr) {
+                if (expr.Body == expr.Parameters[0]) {
+                    // model => model
+
+                    // don't need to lock, as all identity funcs are identical
+                    if (_identityFunc == null) {
+                        _identityFunc = expr.Compile();
+                    }
+
+                    return _identityFunc;
+                }
+
+                return null;
+            }
+
+            private static Func<TIn, TOut> CompileFromFingerprint(Expression<Func<TIn, TOut>> expr) {
+                List<object> capturedConstants;
+                ExpressionFingerprintChain fingerprint = FingerprintingExpressionVisitor.GetFingerprintChain(expr, out capturedConstants);
+
+                if (fingerprint != null) {
+                    var del = _fingerprintedCache.GetOrAdd(fingerprint, _ => {
+                        // Fingerprinting succeeded, but there was a cache miss. Rewrite the expression
+                        // and add the rewritten expression to the cache.
+
+                        var hoistedExpr = HoistingExpressionVisitor<TIn, TOut>.Hoist(expr);
+                        return hoistedExpr.Compile();
+                    });
+                    return model => del(model, capturedConstants);
+                }
+
+                // couldn't be fingerprinted
+                return null;
+            }
+
+            private static Func<TIn, TOut> CompileFromMemberAccess(Expression<Func<TIn, TOut>> expr) {
+                // Performance tests show that on the x64 platform, special-casing static member and
+                // captured local variable accesses is faster than letting the fingerprinting system
+                // handle them. On the x86 platform, the fingerprinting system is faster, but only
+                // by around one microsecond, so it's not worth it to complicate the logic here with
+                // an architecture check.
+
+                MemberExpression memberExpr = expr.Body as MemberExpression;
+                if (memberExpr != null) {
+                    if (memberExpr.Expression == expr.Parameters[0] || memberExpr.Expression == null) {
+                        // model => model.Member or model => StaticMember
+                        return _simpleMemberAccessDict.GetOrAdd(memberExpr.Member, _ => expr.Compile());
+                    }
+
+                    ConstantExpression constExpr = memberExpr.Expression as ConstantExpression;
+                    if (constExpr != null) {
+                        // model => {const}.Member (captured local variable)
+                        var del = _constMemberAccessDict.GetOrAdd(memberExpr.Member, _ => {
+                            // rewrite as capturedLocal => ((TDeclaringType)capturedLocal).Member
+                            var constParamExpr = Expression.Parameter(typeof(object), "capturedLocal");
+                            var constCastExpr = Expression.Convert(constParamExpr, memberExpr.Member.DeclaringType);
+                            var newMemberAccessExpr = memberExpr.Update(constCastExpr);
+                            var newLambdaExpr = Expression.Lambda<Func<object, TOut>>(newMemberAccessExpr, constParamExpr);
+                            return newLambdaExpr.Compile();
+                        });
+
+                        object capturedLocal = constExpr.Value;
+                        return _ => del(capturedLocal);
+                    }
+                }
+
+                return null;
+            }
+
+            private static Func<TIn, TOut> CompileSlow(Expression<Func<TIn, TOut>> expr) {
+                // fallback compilation system - just compile the expression directly
+                return expr.Compile();
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/ConditionalExpressionFingerprint.cs b/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/ConditionalExpressionFingerprint.cs
new file mode 100644 (file)
index 0000000..ae0b52f
--- /dev/null
@@ -0,0 +1,28 @@
+#pragma warning disable 659 // overrides AddToHashCodeCombiner instead
+
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq.Expressions;
+
+    // ConditionalExpression fingerprint class
+    // Expression of form (test) ? ifTrue : ifFalse
+
+    [SuppressMessage("Microsoft.Usage", "CA2218:OverrideGetHashCodeOnOverridingEquals", Justification = "Overrides AddToHashCodeCombiner() instead.")]
+    internal sealed class ConditionalExpressionFingerprint : ExpressionFingerprint {
+
+        public ConditionalExpressionFingerprint(ExpressionType nodeType, Type type)
+            : base(nodeType, type) {
+
+            // There are no properties on ConditionalExpression that are worth including in
+            // the fingerprint.
+        }
+
+        public override bool Equals(object obj) {
+            ConditionalExpressionFingerprint other = obj as ConditionalExpressionFingerprint;
+            return (other != null)
+                && this.Equals(other);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/ConstantExpressionFingerprint.cs b/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/ConstantExpressionFingerprint.cs
new file mode 100644 (file)
index 0000000..61d9714
--- /dev/null
@@ -0,0 +1,32 @@
+#pragma warning disable 659 // overrides AddToHashCodeCombiner instead
+
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq.Expressions;
+
+    // ConstantExpression fingerprint class
+    //
+    // A ConstantExpression might represent a captured local variable, so we can't compile
+    // the value directly into the cached function. Instead, a placeholder is generated
+    // and the value is hoisted into a local variables array. This placeholder can then
+    // be compiled and cached, and the array lookup happens at runtime.
+
+    [SuppressMessage("Microsoft.Usage", "CA2218:OverrideGetHashCodeOnOverridingEquals", Justification = "Overrides AddToHashCodeCombiner() instead.")]
+    internal sealed class ConstantExpressionFingerprint : ExpressionFingerprint {
+
+        public ConstantExpressionFingerprint(ExpressionType nodeType, Type type)
+            : base(nodeType, type) {
+
+            // There are no properties on ConstantExpression that are worth including in
+            // the fingerprint.
+        }
+
+        public override bool Equals(object obj) {
+            ConstantExpressionFingerprint other = obj as ConstantExpressionFingerprint;
+            return (other != null)
+                && this.Equals(other);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/DefaultExpressionFingerprint.cs b/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/DefaultExpressionFingerprint.cs
new file mode 100644 (file)
index 0000000..abf0ed3
--- /dev/null
@@ -0,0 +1,28 @@
+#pragma warning disable 659 // overrides AddToHashCodeCombiner instead
+
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq.Expressions;
+
+    // DefaultExpression fingerprint class
+    // Expression of form default(T)
+
+    [SuppressMessage("Microsoft.Usage", "CA2218:OverrideGetHashCodeOnOverridingEquals", Justification = "Overrides AddToHashCodeCombiner() instead.")]
+    internal sealed class DefaultExpressionFingerprint : ExpressionFingerprint {
+
+        public DefaultExpressionFingerprint(ExpressionType nodeType, Type type)
+            : base(nodeType, type) {
+
+            // There are no properties on DefaultExpression that are worth including in
+            // the fingerprint.
+        }
+
+        public override bool Equals(object obj) {
+            DefaultExpressionFingerprint other = obj as DefaultExpressionFingerprint;
+            return (other != null)
+                && this.Equals(other);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/ExpressionFingerprint.cs b/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/ExpressionFingerprint.cs
new file mode 100644 (file)
index 0000000..135caf9
--- /dev/null
@@ -0,0 +1,43 @@
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+    using System.Linq.Expressions;
+
+    // Serves as the base class for all expression fingerprints. Provides a default implementation
+    // of GetHashCode().
+
+    internal abstract class ExpressionFingerprint {
+
+        protected ExpressionFingerprint(ExpressionType nodeType, Type type) {
+            NodeType = nodeType;
+            Type = type;
+        }
+
+        // the type of expression node, e.g. OP_ADD, MEMBER_ACCESS, etc.
+        public ExpressionType NodeType { get; private set; }
+
+        // the CLR type resulting from this expression, e.g. int, string, etc.
+        public Type Type { get; private set; }
+
+        internal virtual void AddToHashCodeCombiner(HashCodeCombiner combiner) {
+            combiner.AddInt32((int)NodeType);
+            combiner.AddObject(Type);
+        }
+
+        protected bool Equals(ExpressionFingerprint other) {
+            return (other != null)
+                && (this.NodeType == other.NodeType)
+                && Equals(this.Type, other.Type);
+        }
+
+        public override bool Equals(object obj) {
+            return Equals(obj as ExpressionFingerprint);
+        }
+
+        public override int GetHashCode() {
+            HashCodeCombiner combiner = new HashCodeCombiner();
+            AddToHashCodeCombiner(combiner);
+            return combiner.CombinedHash;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/ExpressionFingerprintChain.cs b/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/ExpressionFingerprintChain.cs
new file mode 100644 (file)
index 0000000..2fc0ffa
--- /dev/null
@@ -0,0 +1,79 @@
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+    using System.Collections.Generic;
+
+    // Expression fingerprint chain class
+    // Contains information used for generalizing, comparing, and recreating Expression instances
+    //
+    // Since Expression objects are immutable and are recreated for every invocation of an expression
+    // helper method, they can't be compared directly. Fingerprinting Expression objects allows
+    // information about them to be abstracted away, and the fingerprints can be directly compared.
+    // Consider the process of fingerprinting that all values (parameters, constants, etc.) are hoisted
+    // and replaced with dummies. What remains can be decomposed into a sequence of operations on specific
+    // types and specific inputs.
+    //
+    // Some sample fingerprints chains:
+    //
+    // 2 + 4 -> OP_ADD, CONST:int, NULL, CONST:int
+    // 2 + 8 -> OP_ADD, CONST:int, NULL, CONST:int
+    // 2.0 + 4.0 -> OP_ADD, CONST:double, NULL, CONST:double
+    //
+    // 2 + 4 and 2 + 8 have the same fingerprint, but 2.0 + 4.0 has a different fingerprint since its
+    // underlying types differ. Note that this looks a bit like prefix notation and is a side effect
+    // of how the ExpressionVisitor class recurses into expressions. (Occasionally there will be a NULL
+    // in the fingerprint chain, which depending on context can denote a static member, a null Conversion
+    // in a BinaryExpression, and so forth.)
+    //
+    // "Hello " + "world" -> OP_ADD, CONST:string, NULL, CONST:string
+    // "Hello " + {model} -> OP_ADD, CONST:string, NULL, PARAM_0:string
+    //
+    // These string concatenations have different fingerprints since the inputs are provided differently:
+    // one is a constant, the other is a parameter.
+    //
+    // ({model} ?? "sample").Length -> MEMBER_ACCESS(String.Length), OP_COALESCE, PARAM_0:string, NULL, CONST:string
+    // ({model} ?? "other sample").Length -> MEMBER_ACCESS(String.Length), OP_COALESCE, PARAM_0:string, NULL, CONST:string
+    //
+    // These expressions have the same fingerprint since all constants of the same underlying type are
+    // treated equally.
+    //
+    // It's also important that the fingerprints don't reference the actual Expression objects that were
+    // used to generate them, as the fingerprints will be cached, and caching a fingerprint that references
+    // an Expression will root the Expression (and any objects it references).
+
+    internal sealed class ExpressionFingerprintChain : IEquatable<ExpressionFingerprintChain> {
+
+        public readonly List<ExpressionFingerprint> Elements = new List<ExpressionFingerprint>();
+
+        public bool Equals(ExpressionFingerprintChain other) {
+            // Two chains are considered equal if two elements appearing in the same index in
+            // each chain are equal (value equality, not referential equality).
+
+            if (other == null) {
+                return false;
+            }
+
+            if (this.Elements.Count != other.Elements.Count) {
+                return false;
+            }
+
+            for (int i = 0; i < this.Elements.Count; i++) {
+                if (!Object.Equals(this.Elements[i], other.Elements[i])) {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        public override bool Equals(object obj) {
+            return Equals(obj as ExpressionFingerprintChain);
+        }
+
+        public override int GetHashCode() {
+            HashCodeCombiner combiner = new HashCodeCombiner();
+            Elements.ForEach(combiner.AddFingerprint);
+            return combiner.CombinedHash;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/FingerprintingExpressionVisitor.cs b/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/FingerprintingExpressionVisitor.cs
new file mode 100644 (file)
index 0000000..daadb68
--- /dev/null
@@ -0,0 +1,220 @@
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+    using System.Collections.Generic;
+    using System.Linq.Expressions;
+
+    // This is a visitor which produces a fingerprint of an expression. It doesn't
+    // rewrite the expression in a form which can be compiled and cached.
+
+    internal sealed class FingerprintingExpressionVisitor : ExpressionVisitor {
+
+        private readonly List<object> _seenConstants = new List<object>();
+        private readonly List<ParameterExpression> _seenParameters = new List<ParameterExpression>();
+        private readonly ExpressionFingerprintChain _currentChain = new ExpressionFingerprintChain();
+        private bool _gaveUp;
+
+        private FingerprintingExpressionVisitor() { }
+
+        private T GiveUp<T>(T node) {
+            // We don't understand this node, so just quit.
+
+            _gaveUp = true;
+            return node;
+        }
+
+        // Returns the fingerprint chain + captured constants list for this expression, or null
+        // if the expression couldn't be fingerprinted.
+        public static ExpressionFingerprintChain GetFingerprintChain(Expression expr, out List<object> capturedConstants) {
+            FingerprintingExpressionVisitor visitor = new FingerprintingExpressionVisitor();
+            visitor.Visit(expr);
+
+            if (visitor._gaveUp) {
+                capturedConstants = null;
+                return null;
+            }
+            else {
+                capturedConstants = visitor._seenConstants;
+                return visitor._currentChain;
+            }
+        }
+
+        public override Expression Visit(Expression node) {
+            if (node == null) {
+                _currentChain.Elements.Add(null);
+                return null;
+            }
+            else {
+                return base.Visit(node);
+            }
+        }
+
+        protected override Expression VisitBinary(BinaryExpression node) {
+            if (_gaveUp) { return node; }
+            _currentChain.Elements.Add(new BinaryExpressionFingerprint(node.NodeType, node.Type, node.Method));
+            return base.VisitBinary(node);
+        }
+
+        protected override Expression VisitBlock(BlockExpression node) {
+            return GiveUp(node);
+        }
+
+        protected override CatchBlock VisitCatchBlock(CatchBlock node) {
+            return GiveUp(node);
+        }
+
+        protected override Expression VisitConditional(ConditionalExpression node) {
+            if (_gaveUp) { return node; }
+            _currentChain.Elements.Add(new ConditionalExpressionFingerprint(node.NodeType, node.Type));
+            return base.VisitConditional(node);
+        }
+
+        protected override Expression VisitConstant(ConstantExpression node) {
+            if (_gaveUp) { return node; }
+
+            _seenConstants.Add(node.Value);
+            _currentChain.Elements.Add(new ConstantExpressionFingerprint(node.NodeType, node.Type));
+            return base.VisitConstant(node);
+        }
+
+        protected override Expression VisitDebugInfo(DebugInfoExpression node) {
+            return GiveUp(node);
+        }
+
+        protected override Expression VisitDefault(DefaultExpression node) {
+            if (_gaveUp) { return node; }
+            _currentChain.Elements.Add(new DefaultExpressionFingerprint(node.NodeType, node.Type));
+            return base.VisitDefault(node);
+        }
+
+        protected override Expression VisitDynamic(DynamicExpression node) {
+            return GiveUp(node);
+        }
+
+        protected override ElementInit VisitElementInit(ElementInit node) {
+            return GiveUp(node);
+        }
+
+        protected override Expression VisitExtension(Expression node) {
+            return GiveUp(node);
+        }
+
+        protected override Expression VisitGoto(GotoExpression node) {
+            return GiveUp(node);
+        }
+
+        protected override Expression VisitIndex(IndexExpression node) {
+            if (_gaveUp) { return node; }
+            _currentChain.Elements.Add(new IndexExpressionFingerprint(node.NodeType, node.Type, node.Indexer));
+            return base.VisitIndex(node);
+        }
+
+        protected override Expression VisitInvocation(InvocationExpression node) {
+            return GiveUp(node);
+        }
+
+        protected override Expression VisitLabel(LabelExpression node) {
+            return GiveUp(node);
+        }
+
+        protected override LabelTarget VisitLabelTarget(LabelTarget node) {
+            return GiveUp(node);
+        }
+
+        protected override Expression VisitLambda<T>(Expression<T> node) {
+            if (_gaveUp) { return node; }
+            _currentChain.Elements.Add(new LambdaExpressionFingerprint(node.NodeType, node.Type));
+            return base.VisitLambda<T>(node);
+        }
+
+        protected override Expression VisitListInit(ListInitExpression node) {
+            return GiveUp(node);
+        }
+
+        protected override Expression VisitLoop(LoopExpression node) {
+            return GiveUp(node);
+        }
+
+        protected override Expression VisitMember(MemberExpression node) {
+            if (_gaveUp) { return node; }
+            _currentChain.Elements.Add(new MemberExpressionFingerprint(node.NodeType, node.Type, node.Member));
+            return base.VisitMember(node);
+        }
+
+        protected override MemberAssignment VisitMemberAssignment(MemberAssignment node) {
+            return GiveUp(node);
+        }
+
+        protected override MemberBinding VisitMemberBinding(MemberBinding node) {
+            return GiveUp(node);
+        }
+
+        protected override Expression VisitMemberInit(MemberInitExpression node) {
+            return GiveUp(node);
+        }
+
+        protected override MemberListBinding VisitMemberListBinding(MemberListBinding node) {
+            return GiveUp(node);
+        }
+
+        protected override MemberMemberBinding VisitMemberMemberBinding(MemberMemberBinding node) {
+            return GiveUp(node);
+        }
+
+        protected override Expression VisitMethodCall(MethodCallExpression node) {
+            if (_gaveUp) { return node; }
+            _currentChain.Elements.Add(new MethodCallExpressionFingerprint(node.NodeType, node.Type, node.Method));
+            return base.VisitMethodCall(node);
+        }
+
+        protected override Expression VisitNew(NewExpression node) {
+            return GiveUp(node);
+        }
+
+        protected override Expression VisitNewArray(NewArrayExpression node) {
+            return GiveUp(node);
+        }
+
+        protected override Expression VisitParameter(ParameterExpression node) {
+            if (_gaveUp) { return node; }
+
+            int parameterIndex = _seenParameters.IndexOf(node);
+            if (parameterIndex < 0) {
+                // first time seeing this parameter
+                parameterIndex = _seenParameters.Count;
+                _seenParameters.Add(node);
+            }
+
+            _currentChain.Elements.Add(new ParameterExpressionFingerprint(node.NodeType, node.Type, parameterIndex));
+            return base.VisitParameter(node);
+        }
+
+        protected override Expression VisitRuntimeVariables(RuntimeVariablesExpression node) {
+            return GiveUp(node);
+        }
+
+        protected override Expression VisitSwitch(SwitchExpression node) {
+            return GiveUp(node);
+        }
+
+        protected override SwitchCase VisitSwitchCase(SwitchCase node) {
+            return GiveUp(node);
+        }
+
+        protected override Expression VisitTry(TryExpression node) {
+            return GiveUp(node);
+        }
+
+        protected override Expression VisitTypeBinary(TypeBinaryExpression node) {
+            if (_gaveUp) { return node; }
+            _currentChain.Elements.Add(new TypeBinaryExpressionFingerprint(node.NodeType, node.Type, node.TypeOperand));
+            return base.VisitTypeBinary(node);
+        }
+
+        protected override Expression VisitUnary(UnaryExpression node) {
+            if (_gaveUp) { return node; }
+            _currentChain.Elements.Add(new UnaryExpressionFingerprint(node.NodeType, node.Type, node.Method));
+            return base.VisitUnary(node);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/HashCodeCombiner.cs b/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/HashCodeCombiner.cs
new file mode 100644 (file)
index 0000000..d981e0c
--- /dev/null
@@ -0,0 +1,49 @@
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+    using System.Collections;
+
+    // based on System.Web.Util.HashCodeCombiner
+    internal class HashCodeCombiner {
+
+        private long _combinedHash64 = 0x1505L;
+
+        public void AddFingerprint(ExpressionFingerprint fingerprint) {
+            if (fingerprint != null) {
+                fingerprint.AddToHashCodeCombiner(this);
+            }
+            else {
+                AddInt32(0);
+            }
+        }
+
+        public void AddEnumerable(IEnumerable e) {
+            if (e == null) {
+                AddInt32(0);
+            }
+            else {
+                int count = 0;
+                foreach (object o in e) {
+                    AddObject(o);
+                    count++;
+                }
+                AddInt32(count);
+            }
+        }
+
+        public void AddInt32(int i) {
+            _combinedHash64 = ((_combinedHash64 << 5) + _combinedHash64) ^ i;
+        }
+
+        public void AddObject(object o) {
+            int oHashCode = (o != null) ? o.GetHashCode() : 0;
+            AddInt32(oHashCode);
+        }
+
+        public int CombinedHash {
+            get {
+                return _combinedHash64.GetHashCode();
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/Hoisted`2.cs b/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/Hoisted`2.cs
new file mode 100644 (file)
index 0000000..2862fd0
--- /dev/null
@@ -0,0 +1,7 @@
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+    using System.Collections.Generic;
+
+    internal delegate TValue Hoisted<TModel, TValue>(TModel model, List<object> capturedConstants);
+
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/HoistingExpressionVisitor.cs b/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/HoistingExpressionVisitor.cs
new file mode 100644 (file)
index 0000000..3388957
--- /dev/null
@@ -0,0 +1,32 @@
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+    using System.Collections.Generic;
+    using System.Linq.Expressions;
+
+    // This is a visitor which rewrites constant expressions as parameter lookups. It's meant
+    // to produce an expression which can be cached safely.
+
+    internal sealed class HoistingExpressionVisitor<TIn, TOut> : ExpressionVisitor {
+
+        private static readonly ParameterExpression _hoistedConstantsParamExpr = Expression.Parameter(typeof(List<object>), "hoistedConstants");
+        private int _numConstantsProcessed;
+
+        // factory will create instance
+        private HoistingExpressionVisitor() { }
+
+        public static Expression<Hoisted<TIn, TOut>> Hoist(Expression<Func<TIn, TOut>> expr) {
+            // rewrite Expression<Func<TIn, TOut>> as Expression<Hoisted<TIn, TOut>>
+
+            var visitor = new HoistingExpressionVisitor<TIn, TOut>();
+            var rewrittenBodyExpr = visitor.Visit(expr.Body);
+            var rewrittenLambdaExpr = Expression.Lambda<Hoisted<TIn, TOut>>(rewrittenBodyExpr, expr.Parameters[0], _hoistedConstantsParamExpr);
+            return rewrittenLambdaExpr;
+        }
+
+        protected override Expression VisitConstant(ConstantExpression node) {
+            // rewrite the constant expression as (TConst)hoistedConstants[i];
+            return Expression.Convert(Expression.Property(_hoistedConstantsParamExpr, "Item", Expression.Constant(_numConstantsProcessed++)), node.Type);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/IndexExpressionFingerprint.cs b/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/IndexExpressionFingerprint.cs
new file mode 100644 (file)
index 0000000..fbd524f
--- /dev/null
@@ -0,0 +1,40 @@
+#pragma warning disable 659 // overrides AddToHashCodeCombiner instead
+
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq.Expressions;
+    using System.Reflection;
+
+    // IndexExpression fingerprint class
+    // Represents certain forms of array access or indexer property access
+
+    [SuppressMessage("Microsoft.Usage", "CA2218:OverrideGetHashCodeOnOverridingEquals", Justification = "Overrides AddToHashCodeCombiner() instead.")]
+    internal sealed class IndexExpressionFingerprint : ExpressionFingerprint {
+
+        public IndexExpressionFingerprint(ExpressionType nodeType, Type type, PropertyInfo indexer)
+            : base(nodeType, type) {
+
+            // Other properties on IndexExpression (like the argument count) are simply derived
+            // from Type and Indexer, so they're not necessary for inclusion in the fingerprint.
+
+            Indexer = indexer;
+        }
+
+        // http://msdn.microsoft.com/en-us/library/system.linq.expressions.indexexpression.indexer.aspx
+        public PropertyInfo Indexer { get; private set; }
+
+        public override bool Equals(object obj) {
+            IndexExpressionFingerprint other = obj as IndexExpressionFingerprint;
+            return (other != null)
+                && Equals(this.Indexer, other.Indexer)
+                && this.Equals(other);
+        }
+
+        internal override void AddToHashCodeCombiner(HashCodeCombiner combiner) {
+            combiner.AddObject(Indexer);
+            base.AddToHashCodeCombiner(combiner);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/LambdaExpressionFingerprint.cs b/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/LambdaExpressionFingerprint.cs
new file mode 100644 (file)
index 0000000..d8e9e38
--- /dev/null
@@ -0,0 +1,28 @@
+#pragma warning disable 659 // overrides AddToHashCodeCombiner instead
+
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq.Expressions;
+
+    // LambdaExpression fingerprint class
+    // Represents a lambda expression (root element in Expression<T>)
+
+    [SuppressMessage("Microsoft.Usage", "CA2218:OverrideGetHashCodeOnOverridingEquals", Justification = "Overrides AddToHashCodeCombiner() instead.")]
+    internal sealed class LambdaExpressionFingerprint : ExpressionFingerprint {
+
+        public LambdaExpressionFingerprint(ExpressionType nodeType, Type type)
+            : base(nodeType, type) {
+
+            // There are no properties on LambdaExpression that are worth including in
+            // the fingerprint.
+        }
+
+        public override bool Equals(object obj) {
+            LambdaExpressionFingerprint other = obj as LambdaExpressionFingerprint;
+            return (other != null)
+                && this.Equals(other);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/MemberExpressionFingerprint.cs b/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/MemberExpressionFingerprint.cs
new file mode 100644 (file)
index 0000000..6143a5c
--- /dev/null
@@ -0,0 +1,37 @@
+#pragma warning disable 659 // overrides AddToHashCodeCombiner instead
+
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq.Expressions;
+    using System.Reflection;
+
+    // MemberExpression fingerprint class
+    // Expression of form xxx.FieldOrProperty
+
+    [SuppressMessage("Microsoft.Usage", "CA2218:OverrideGetHashCodeOnOverridingEquals", Justification = "Overrides AddToHashCodeCombiner() instead.")]
+    internal sealed class MemberExpressionFingerprint : ExpressionFingerprint {
+
+        public MemberExpressionFingerprint(ExpressionType nodeType, Type type, MemberInfo member)
+            : base(nodeType, type) {
+
+            Member = member;
+        }
+
+        // http://msdn.microsoft.com/en-us/library/system.linq.expressions.memberexpression.member.aspx
+        public MemberInfo Member { get; private set; }
+
+        public override bool Equals(object obj) {
+            MemberExpressionFingerprint other = obj as MemberExpressionFingerprint;
+            return (other != null)
+                && Equals(this.Member, other.Member)
+                && this.Equals(other);
+        }
+
+        internal override void AddToHashCodeCombiner(HashCodeCombiner combiner) {
+            combiner.AddObject(Member);
+            base.AddToHashCodeCombiner(combiner);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/MethodCallExpressionFingerprint.cs b/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/MethodCallExpressionFingerprint.cs
new file mode 100644 (file)
index 0000000..4689121
--- /dev/null
@@ -0,0 +1,40 @@
+#pragma warning disable 659 // overrides AddToHashCodeCombiner instead
+
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq.Expressions;
+    using System.Reflection;
+
+    // MethodCallExpression fingerprint class
+    // Expression of form xxx.Foo(...), xxx[...] (get_Item()), etc.
+
+    [SuppressMessage("Microsoft.Usage", "CA2218:OverrideGetHashCodeOnOverridingEquals", Justification = "Overrides AddToHashCodeCombiner() instead.")]
+    internal sealed class MethodCallExpressionFingerprint : ExpressionFingerprint {
+
+        public MethodCallExpressionFingerprint(ExpressionType nodeType, Type type, MethodInfo method)
+            : base(nodeType, type) {
+
+            // Other properties on MethodCallExpression (like the argument count) are simply derived
+            // from Type and Indexer, so they're not necessary for inclusion in the fingerprint.
+
+            Method = method;
+        }
+
+        // http://msdn.microsoft.com/en-us/library/system.linq.expressions.methodcallexpression.method.aspx
+        public MethodInfo Method { get; private set; }
+
+        public override bool Equals(object obj) {
+            MethodCallExpressionFingerprint other = obj as MethodCallExpressionFingerprint;
+            return (other != null)
+                && Equals(this.Method, other.Method)
+                && this.Equals(other);
+        }
+
+        internal override void AddToHashCodeCombiner(HashCodeCombiner combiner) {
+            combiner.AddObject(Method);
+            base.AddToHashCodeCombiner(combiner);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/ParameterExpressionFingerprint.cs b/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/ParameterExpressionFingerprint.cs
new file mode 100644 (file)
index 0000000..9121bce
--- /dev/null
@@ -0,0 +1,36 @@
+#pragma warning disable 659 // overrides AddToHashCodeCombiner instead
+
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq.Expressions;
+
+    // ParameterExpression fingerprint class
+    // Can represent the model parameter or an inner parameter in an open lambda expression
+
+    [SuppressMessage("Microsoft.Usage", "CA2218:OverrideGetHashCodeOnOverridingEquals", Justification = "Overrides AddToHashCodeCombiner() instead.")]
+    internal sealed class ParameterExpressionFingerprint : ExpressionFingerprint {
+
+        public ParameterExpressionFingerprint(ExpressionType nodeType, Type type, int parameterIndex)
+            : base(nodeType, type) {
+
+            ParameterIndex = parameterIndex;
+        }
+
+        // Parameter position within the overall expression, used to maintain alpha equivalence.
+        public int ParameterIndex { get; private set; }
+
+        public override bool Equals(object obj) {
+            ParameterExpressionFingerprint other = obj as ParameterExpressionFingerprint;
+            return (other != null)
+                && (this.ParameterIndex == other.ParameterIndex)
+                && this.Equals(other);
+        }
+
+        internal override void AddToHashCodeCombiner(HashCodeCombiner combiner) {
+            combiner.AddInt32(ParameterIndex);
+            base.AddToHashCodeCombiner(combiner);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/TypeBinaryExpressionFingerprint.cs b/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/TypeBinaryExpressionFingerprint.cs
new file mode 100644 (file)
index 0000000..e8b78c4
--- /dev/null
@@ -0,0 +1,36 @@
+#pragma warning disable 659 // overrides AddToHashCodeCombiner instead
+
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq.Expressions;
+
+    // TypeBinary fingerprint class
+    // Expression of form "obj is T"
+
+    [SuppressMessage("Microsoft.Usage", "CA2218:OverrideGetHashCodeOnOverridingEquals", Justification = "Overrides AddToHashCodeCombiner() instead.")]
+    internal sealed class TypeBinaryExpressionFingerprint : ExpressionFingerprint {
+
+        public TypeBinaryExpressionFingerprint(ExpressionType nodeType, Type type, Type typeOperand)
+            : base(nodeType, type) {
+
+            TypeOperand = typeOperand;
+        }
+
+        // http://msdn.microsoft.com/en-us/library/system.linq.expressions.typebinaryexpression.typeoperand.aspx
+        public Type TypeOperand { get; private set; }
+
+        public override bool Equals(object obj) {
+            TypeBinaryExpressionFingerprint other = obj as TypeBinaryExpressionFingerprint;
+            return (other != null)
+                && Equals(this.TypeOperand, other.TypeOperand)
+                && this.Equals(other);
+        }
+
+        internal override void AddToHashCodeCombiner(HashCodeCombiner combiner) {
+            combiner.AddObject(TypeOperand);
+            base.AddToHashCodeCombiner(combiner);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/UnaryExpressionFingerprint.cs b/mcs/class/System.Web.Mvc3/Mvc/ExpressionUtil/UnaryExpressionFingerprint.cs
new file mode 100644 (file)
index 0000000..d920987
--- /dev/null
@@ -0,0 +1,40 @@
+#pragma warning disable 659 // overrides AddToHashCodeCombiner instead
+
+namespace System.Web.Mvc.ExpressionUtil {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq.Expressions;
+    using System.Reflection;
+
+    // UnaryExpression fingerprint class
+    // The most common appearance of a UnaryExpression is a cast or other conversion operator
+
+    [SuppressMessage("Microsoft.Usage", "CA2218:OverrideGetHashCodeOnOverridingEquals", Justification = "Overrides AddToHashCodeCombiner() instead.")]
+    internal sealed class UnaryExpressionFingerprint : ExpressionFingerprint {
+
+        public UnaryExpressionFingerprint(ExpressionType nodeType, Type type, MethodInfo method)
+            : base(nodeType, type) {
+
+            // Other properties on UnaryExpression (like IsLifted / IsLiftedToNull) are simply derived
+            // from Type and NodeType, so they're not necessary for inclusion in the fingerprint.
+
+            Method = method;
+        }
+
+        // http://msdn.microsoft.com/en-us/library/system.linq.expressions.unaryexpression.method.aspx
+        public MethodInfo Method { get; private set; }
+
+        public override bool Equals(object obj) {
+            UnaryExpressionFingerprint other = obj as UnaryExpressionFingerprint;
+            return (other != null)
+                && Equals(this.Method, other.Method)
+                && this.Equals(other);
+        }
+
+        internal override void AddToHashCodeCombiner(HashCodeCombiner combiner) {
+            combiner.AddObject(Method);
+            base.AddToHashCodeCombiner(combiner);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/FieldValidationMetadata.cs b/mcs/class/System.Web.Mvc3/Mvc/FieldValidationMetadata.cs
new file mode 100644 (file)
index 0000000..c0a512e
--- /dev/null
@@ -0,0 +1,37 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Collections.ObjectModel;
+
+    public class FieldValidationMetadata {
+
+        private string _fieldName;
+        private readonly Collection<ModelClientValidationRule> _validationRules = new Collection<ModelClientValidationRule>();
+
+        public string FieldName {
+            get {
+                return _fieldName ?? String.Empty;
+            }
+            set {
+                _fieldName = value;
+            }
+        }
+
+        public bool ReplaceValidationMessageContents {
+            get;
+            set;
+        }
+
+        public string ValidationMessageId {
+            get;
+            set;
+        }
+
+        public ICollection<ModelClientValidationRule> ValidationRules {
+            get {
+                return _validationRules;
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/FileContentResult.cs b/mcs/class/System.Web.Mvc3/Mvc/FileContentResult.cs
new file mode 100644 (file)
index 0000000..b23921f
--- /dev/null
@@ -0,0 +1,28 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Web;
+
+    public class FileContentResult : FileResult {
+
+        public FileContentResult(byte[] fileContents, string contentType)
+            : base(contentType) {
+            if (fileContents == null) {
+                throw new ArgumentNullException("fileContents");
+            }
+
+            FileContents = fileContents;
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Justification = "There's no reason to tamper-proof this array since it's supplied to the type's constructor.")]
+        public byte[] FileContents {
+            get;
+            private set;
+        }
+
+        protected override void WriteFile(HttpResponseBase response) {
+            response.OutputStream.Write(FileContents, 0, FileContents.Length);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/FilePathResult.cs b/mcs/class/System.Web.Mvc3/Mvc/FilePathResult.cs
new file mode 100644 (file)
index 0000000..e9bc66e
--- /dev/null
@@ -0,0 +1,27 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Web;
+    using System.Web.Mvc.Resources;
+
+    public class FilePathResult : FileResult {
+
+        public FilePathResult(string fileName, string contentType)
+            : base(contentType) {
+            if (String.IsNullOrEmpty(fileName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "fileName");
+            }
+
+            FileName = fileName;
+        }
+
+        public string FileName {
+            get;
+            private set;
+        }
+
+        protected override void WriteFile(HttpResponseBase response) {
+            response.TransmitFile(FileName);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/FileResult.cs b/mcs/class/System.Web.Mvc3/Mvc/FileResult.cs
new file mode 100644 (file)
index 0000000..a44f6c3
--- /dev/null
@@ -0,0 +1,131 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Net.Mime;
+    using System.Text;
+    using System.Web;
+    using System.Web.Mvc.Resources;
+
+    public abstract class FileResult : ActionResult {
+
+        protected FileResult(string contentType) {
+            if (String.IsNullOrEmpty(contentType)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "contentType");
+            }
+
+            ContentType = contentType;
+        }
+
+        private string _fileDownloadName;
+
+        public string ContentType {
+            get;
+            private set;
+        }
+
+        public string FileDownloadName {
+            get {
+                return _fileDownloadName ?? String.Empty;
+            }
+            set {
+                _fileDownloadName = value;
+            }
+        }
+
+        public override void ExecuteResult(ControllerContext context) {
+            if (context == null) {
+                throw new ArgumentNullException("context");
+            }
+
+            HttpResponseBase response = context.HttpContext.Response;
+            response.ContentType = ContentType;
+
+            if (!String.IsNullOrEmpty(FileDownloadName)) {
+                // From RFC 2183, Sec. 2.3:
+                // The sender may want to suggest a filename to be used if the entity is
+                // detached and stored in a separate file. If the receiving MUA writes
+                // the entity to a file, the suggested filename should be used as a
+                // basis for the actual filename, where possible.
+                string headerValue = ContentDispositionUtil.GetHeaderValue(FileDownloadName);
+                context.HttpContext.Response.AddHeader("Content-Disposition", headerValue);
+            }
+
+            WriteFile(response);
+        }
+
+        protected abstract void WriteFile(HttpResponseBase response);
+
+        private static class ContentDispositionUtil {
+            private const string _hexDigits = "0123456789ABCDEF";
+
+            private static void AddByteToStringBuilder(byte b, StringBuilder builder) {
+                builder.Append('%');
+
+                int i = b;
+                AddHexDigitToStringBuilder(i >> 4, builder);
+                AddHexDigitToStringBuilder(i % 16, builder);
+            }
+
+            private static void AddHexDigitToStringBuilder(int digit, StringBuilder builder) {
+                builder.Append(_hexDigits[digit]);
+            }
+
+            private static string CreateRfc2231HeaderValue(string filename) {
+                StringBuilder builder = new StringBuilder("attachment; filename*=UTF-8''");
+
+                byte[] filenameBytes = Encoding.UTF8.GetBytes(filename);
+                foreach (byte b in filenameBytes) {
+                    if (IsByteValidHeaderValueCharacter(b)) {
+                        builder.Append((char)b);
+                    }
+                    else {
+                        AddByteToStringBuilder(b, builder);
+                    }
+                }
+
+                return builder.ToString();
+            }
+
+            public static string GetHeaderValue(string fileName) {
+                try {
+                    // first, try using the .NET built-in generator
+                    ContentDisposition disposition = new ContentDisposition() { FileName = fileName };
+                    return disposition.ToString();
+                }
+                catch (FormatException) {
+                    // otherwise, fall back to RFC 2231 extensions generator
+                    return CreateRfc2231HeaderValue(fileName);
+                }
+            }
+
+            // Application of RFC 2231 Encoding to Hypertext Transfer Protocol (HTTP) Header Fields, sec. 3.2
+            // http://greenbytes.de/tech/webdav/draft-reschke-rfc2231-in-http-latest.html
+            private static bool IsByteValidHeaderValueCharacter(byte b) {
+                if ((byte)'0' <= b && b <= (byte)'9') {
+                    return true; // is digit
+                }
+                if ((byte)'a' <= b && b <= (byte)'z') {
+                    return true; // lowercase letter
+                }
+                if ((byte)'A' <= b && b <= (byte)'Z') {
+                    return true; // uppercase letter
+                }
+
+                switch (b) {
+                    case (byte)'-':
+                    case (byte)'.':
+                    case (byte)'_':
+                    case (byte)'~':
+                    case (byte)':':
+                    case (byte)'!':
+                    case (byte)'$':
+                    case (byte)'&':
+                    case (byte)'+':
+                        return true;
+                }
+
+                return false;
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/FileStreamResult.cs b/mcs/class/System.Web.Mvc3/Mvc/FileStreamResult.cs
new file mode 100644 (file)
index 0000000..992de30
--- /dev/null
@@ -0,0 +1,44 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.IO;
+    using System.Web;
+
+    public class FileStreamResult : FileResult {
+
+        // default buffer size as defined in BufferedStream type
+        private const int _bufferSize = 0x1000;
+
+        public FileStreamResult(Stream fileStream, string contentType)
+            : base(contentType) {
+            if (fileStream == null) {
+                throw new ArgumentNullException("fileStream");
+            }
+
+            FileStream = fileStream;
+        }
+
+        public Stream FileStream {
+            get;
+            private set;
+        }
+
+        protected override void WriteFile(HttpResponseBase response) {
+            // grab chunks of data and write to the output stream
+            Stream outputStream = response.OutputStream;
+            using (FileStream) {
+                byte[] buffer = new byte[_bufferSize];
+
+                while (true) {
+                    int bytesRead = FileStream.Read(buffer, 0, _bufferSize);
+                    if (bytesRead == 0) {
+                        // no more data
+                        break;
+                    }
+
+                    outputStream.Write(buffer, 0, bytesRead);
+                }
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Filter.cs b/mcs/class/System.Web.Mvc3/Mvc/Filter.cs
new file mode 100644 (file)
index 0000000..1d239bc
--- /dev/null
@@ -0,0 +1,39 @@
+namespace System.Web.Mvc {
+    using System.Diagnostics.CodeAnalysis;
+
+    public class Filter {
+        public const int DefaultOrder = -1;
+
+        public Filter(object instance, FilterScope scope, int? order) {
+            if (instance == null) {
+                throw new ArgumentNullException("instance");
+            }
+
+            if (order == null) {
+                IMvcFilter mvcFilter = instance as IMvcFilter;
+                if (mvcFilter != null) {
+                    order = mvcFilter.Order;
+                }
+            }
+
+            Instance = instance;
+            Order = order ?? DefaultOrder;
+            Scope = scope;
+        }
+
+        public object Instance {
+            get;
+            protected set;
+        }
+
+        public int Order {
+            get;
+            protected set;
+        }
+
+        public FilterScope Scope {
+            get;
+            protected set;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/FilterAttribute.cs b/mcs/class/System.Web.Mvc3/Mvc/FilterAttribute.cs
new file mode 100644 (file)
index 0000000..3c210c0
--- /dev/null
@@ -0,0 +1,40 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Concurrent;
+    using System.Linq;
+    using System.Web.Mvc.Resources;
+
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
+    public abstract class FilterAttribute : Attribute, IMvcFilter {
+        private readonly static ConcurrentDictionary<Type, bool> _multiuseAttributeCache = new ConcurrentDictionary<Type, bool>();
+        private int _order = Filter.DefaultOrder;
+
+        private static bool AllowsMultiple(Type attributeType) {
+            return _multiuseAttributeCache.GetOrAdd(
+                attributeType,
+                type => type.GetCustomAttributes(typeof(AttributeUsageAttribute), true)
+                            .Cast<AttributeUsageAttribute>()
+                            .First()
+                            .AllowMultiple
+            );
+        }
+
+        public bool AllowMultiple {
+            get {
+                return AllowsMultiple(GetType());
+            }
+        }
+
+        public int Order {
+            get {
+                return _order;
+            }
+            set {
+                if (value < Filter.DefaultOrder) {
+                    throw new ArgumentOutOfRangeException("value", MvcResources.FilterAttribute_OrderOutOfRange);
+                }
+                _order = value;
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/FilterAttributeFilterProvider.cs b/mcs/class/System.Web.Mvc3/Mvc/FilterAttributeFilterProvider.cs
new file mode 100644 (file)
index 0000000..7c76121
--- /dev/null
@@ -0,0 +1,40 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Linq;
+    using System.Web.Mvc.Async;
+
+    public class FilterAttributeFilterProvider : IFilterProvider {
+        private readonly bool _cacheAttributeInstances;
+
+        public FilterAttributeFilterProvider()
+            : this(true) {
+        }
+
+        public FilterAttributeFilterProvider(bool cacheAttributeInstances) {
+            _cacheAttributeInstances = cacheAttributeInstances;
+        }
+
+        protected virtual IEnumerable<FilterAttribute> GetActionAttributes(ControllerContext controllerContext, ActionDescriptor actionDescriptor) {
+            return actionDescriptor.GetFilterAttributes(_cacheAttributeInstances);
+        }
+
+        protected virtual IEnumerable<FilterAttribute> GetControllerAttributes(ControllerContext controllerContext, ActionDescriptor actionDescriptor) {
+            return actionDescriptor.ControllerDescriptor.GetFilterAttributes(_cacheAttributeInstances);
+        }
+
+        public virtual IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor) {
+            ControllerBase controller = controllerContext.Controller;
+            if (controller == null) {
+                return Enumerable.Empty<Filter>();
+            }
+
+            var typeFilters = GetControllerAttributes(controllerContext, actionDescriptor)
+                             .Select(attr => new Filter(attr, FilterScope.Controller, null));
+            var methodFilters = GetActionAttributes(controllerContext, actionDescriptor)
+                               .Select(attr => new Filter(attr, FilterScope.Action, null));
+
+            return typeFilters.Concat(methodFilters).ToList();
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/FilterInfo.cs b/mcs/class/System.Web.Mvc3/Mvc/FilterInfo.cs
new file mode 100644 (file)
index 0000000..90297d7
--- /dev/null
@@ -0,0 +1,48 @@
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+    using System.Linq;
+
+    public class FilterInfo {
+        private List<IActionFilter> _actionFilters = new List<IActionFilter>();
+        private List<IAuthorizationFilter> _authorizationFilters = new List<IAuthorizationFilter>();
+        private List<IExceptionFilter> _exceptionFilters = new List<IExceptionFilter>();
+        private List<IResultFilter> _resultFilters = new List<IResultFilter>();
+
+        public FilterInfo() {
+        }
+
+        public FilterInfo(IEnumerable<Filter> filters) {
+            // evaluate the 'filters' enumerable only once since the operation can be quite expensive
+            var filterInstances = filters.Select(f => f.Instance).ToList();
+
+            _actionFilters.AddRange(filterInstances.OfType<IActionFilter>());
+            _authorizationFilters.AddRange(filterInstances.OfType<IAuthorizationFilter>());
+            _exceptionFilters.AddRange(filterInstances.OfType<IExceptionFilter>());
+            _resultFilters.AddRange(filterInstances.OfType<IResultFilter>());
+        }
+
+        public IList<IActionFilter> ActionFilters {
+            get {
+                return _actionFilters;
+            }
+        }
+
+        public IList<IAuthorizationFilter> AuthorizationFilters {
+            get {
+                return _authorizationFilters;
+            }
+        }
+
+        public IList<IExceptionFilter> ExceptionFilters {
+            get {
+                return _exceptionFilters;
+            }
+        }
+
+        public IList<IResultFilter> ResultFilters {
+            get {
+                return _resultFilters;
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/FilterProviderCollection.cs b/mcs/class/System.Web.Mvc3/Mvc/FilterProviderCollection.cs
new file mode 100644 (file)
index 0000000..aa71434
--- /dev/null
@@ -0,0 +1,107 @@
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+    using System.Collections.ObjectModel;
+    using System.Linq;
+
+    public class FilterProviderCollection : Collection<IFilterProvider> {
+
+        private static FilterComparer _filterComparer = new FilterComparer();
+        private IResolver<IEnumerable<IFilterProvider>> _serviceResolver;
+
+        public FilterProviderCollection() {
+            _serviceResolver = new MultiServiceResolver<IFilterProvider>(() => Items);
+        }
+
+        public FilterProviderCollection(IList<IFilterProvider> providers)
+            : base(providers) {
+            _serviceResolver = new MultiServiceResolver<IFilterProvider>(() => Items);
+        }
+
+        internal FilterProviderCollection(IResolver<IEnumerable<IFilterProvider>> serviceResolver, params IFilterProvider[] providers)
+            : base(providers) {
+            _serviceResolver = serviceResolver ?? new MultiServiceResolver<IFilterProvider>(
+                    () => Items
+                    );
+        }
+
+        private IEnumerable<IFilterProvider> CombinedItems {
+            get {
+                return _serviceResolver.Current;
+            }
+        }
+
+        private static bool AllowMultiple(object filterInstance) {
+            IMvcFilter mvcFilter = filterInstance as IMvcFilter;
+            if (mvcFilter == null) {
+                return true;
+            }
+
+            return mvcFilter.AllowMultiple;
+        }
+
+        public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+            if (actionDescriptor == null) {
+                throw new ArgumentNullException("actionDescriptor");
+            }
+
+            IEnumerable<Filter> combinedFilters =
+                CombinedItems.SelectMany(fp => fp.GetFilters(controllerContext, actionDescriptor))
+                             .OrderBy(filter => filter, _filterComparer);
+
+            // Remove duplicates from the back forward
+            return RemoveDuplicates(combinedFilters.Reverse()).Reverse();
+        }
+
+        private IEnumerable<Filter> RemoveDuplicates(IEnumerable<Filter> filters) {
+            HashSet<Type> visitedTypes = new HashSet<Type>();
+
+            foreach (Filter filter in filters) {
+                object filterInstance = filter.Instance;
+                Type filterInstanceType = filterInstance.GetType();
+
+                if (!visitedTypes.Contains(filterInstanceType) || AllowMultiple(filterInstance)) {
+                    yield return filter;
+                    visitedTypes.Add(filterInstanceType);
+                }
+            }
+        }
+
+        private class FilterComparer : IComparer<Filter> {
+            public int Compare(Filter x, Filter y) {
+                // Nulls always have to be less than non-nulls
+                if (x == null && y == null) {
+                    return 0;
+                }
+                if (x == null) {
+                    return -1;
+                }
+                if (y == null) {
+                    return 1;
+                }
+
+                // Sort first by order...
+
+                if (x.Order < y.Order) {
+                    return -1;
+                }
+                if (x.Order > y.Order) {
+                    return 1;
+                }
+
+                // ...then by scope
+
+                if (x.Scope < y.Scope) {
+                    return -1;
+                }
+                if (x.Scope > y.Scope) {
+                    return 1;
+                }
+
+                return 0;
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/FilterProviders.cs b/mcs/class/System.Web.Mvc3/Mvc/FilterProviders.cs
new file mode 100644 (file)
index 0000000..09f2b5e
--- /dev/null
@@ -0,0 +1,15 @@
+namespace System.Web.Mvc {
+    public static class FilterProviders {
+        static FilterProviders() {
+            Providers = new FilterProviderCollection();
+            Providers.Add(GlobalFilters.Filters);
+            Providers.Add(new FilterAttributeFilterProvider());
+            Providers.Add(new ControllerInstanceFilterProvider());
+        }
+
+        public static FilterProviderCollection Providers {
+            get;
+            private set;
+        }
+    }
+}
\ No newline at end of file
diff --git a/mcs/class/System.Web.Mvc3/Mvc/FilterScope.cs b/mcs/class/System.Web.Mvc3/Mvc/FilterScope.cs
new file mode 100644 (file)
index 0000000..3be5da3
--- /dev/null
@@ -0,0 +1,9 @@
+namespace System.Web.Mvc {
+    public enum FilterScope {
+        First = 0,
+        Global = 10,
+        Controller = 20,
+        Action = 30,
+        Last = 100,
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/FormCollection.cs b/mcs/class/System.Web.Mvc3/Mvc/FormCollection.cs
new file mode 100644 (file)
index 0000000..279e564
--- /dev/null
@@ -0,0 +1,81 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Specialized;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Web.Helpers;
+
+    [SuppressMessage("Microsoft.Usage", "CA2237:MarkISerializableTypesWithSerializable", Justification = "It is not anticipated that users will need to serialize this type.")]
+    [SuppressMessage("Microsoft.Design", "CA1035:ICollectionImplementationsHaveStronglyTypedMembers", Justification = "It is not anticipated that users will call FormCollection.CopyTo().")]
+    [FormCollectionBinder]
+    public sealed class FormCollection : NameValueCollection, IValueProvider {
+
+        public FormCollection() {
+        }
+
+        public FormCollection(NameValueCollection collection) {
+            if (collection == null) {
+                throw new ArgumentNullException("collection");
+            }
+
+            Add(collection);
+        }
+
+        internal FormCollection(ControllerBase controller, Func<NameValueCollection> validatedValuesThunk, Func<NameValueCollection> unvalidatedValuesThunk) {
+            Add(controller == null || controller.ValidateRequest ? validatedValuesThunk() : unvalidatedValuesThunk());
+        }
+
+        public ValueProviderResult GetValue(string name) {
+            if (name == null) {
+                throw new ArgumentNullException("name");
+            }
+
+            string[] rawValue = GetValues(name);
+            if (rawValue == null) {
+                return null;
+            }
+
+            string attemptedValue = this[name];
+            return new ValueProviderResult(rawValue, attemptedValue, CultureInfo.CurrentCulture);
+        }
+
+        public IValueProvider ToValueProvider() {
+            return this;
+        }
+
+        #region IValueProvider Members
+        bool IValueProvider.ContainsPrefix(string prefix) {
+            return ValueProviderUtil.CollectionContainsPrefix(AllKeys, prefix);
+        }
+
+        ValueProviderResult IValueProvider.GetValue(string key) {
+            return GetValue(key);
+        }
+        #endregion
+
+        private sealed class FormCollectionBinderAttribute : CustomModelBinderAttribute {
+
+            // since the FormCollectionModelBinder.BindModel() method is thread-safe, we only need to keep
+            // a single instance of the binder around
+            private static readonly FormCollectionModelBinder _binder = new FormCollectionModelBinder();
+
+            public override IModelBinder GetBinder() {
+                return _binder;
+            }
+
+            // this class is used for generating a FormCollection object
+            private sealed class FormCollectionModelBinder : IModelBinder {
+                public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {
+                    if (controllerContext == null) {
+                        throw new ArgumentNullException("controllerContext");
+                    }
+
+                    return new FormCollection(controllerContext.Controller,
+                                              () => controllerContext.HttpContext.Request.Form,
+                                              () => controllerContext.HttpContext.Request.Unvalidated().Form);
+                }
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/FormContext.cs b/mcs/class/System.Web.Mvc3/Mvc/FormContext.cs
new file mode 100644 (file)
index 0000000..40f69ff
--- /dev/null
@@ -0,0 +1,80 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Web.Script.Serialization;
+
+    public class FormContext {
+
+        private readonly Dictionary<string, FieldValidationMetadata> _fieldValidators = new Dictionary<string, FieldValidationMetadata>();
+        private readonly Dictionary<string, bool> _renderedFields = new Dictionary<string, bool>();
+
+        public IDictionary<string, FieldValidationMetadata> FieldValidators {
+            get {
+                return _fieldValidators;
+            }
+        }
+
+        public string FormId {
+            get;
+            set;
+        }
+
+        public bool ReplaceValidationSummary {
+            get;
+            set;
+        }
+
+        public string ValidationSummaryId {
+            get;
+            set;
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "Performs a potentially time-consuming conversion.")]
+        public string GetJsonValidationMetadata() {
+            JavaScriptSerializer serializer = new JavaScriptSerializer();
+
+            SortedDictionary<string, object> dict = new SortedDictionary<string, object>() {
+                { "Fields", FieldValidators.Values },
+                { "FormId", FormId }
+            };
+            if (!String.IsNullOrEmpty(ValidationSummaryId)) {
+                dict["ValidationSummaryId"] = ValidationSummaryId;
+            }
+            dict["ReplaceValidationSummary"] = ReplaceValidationSummary;
+
+            return serializer.Serialize(dict);
+        }
+
+        public FieldValidationMetadata GetValidationMetadataForField(string fieldName) {
+            return GetValidationMetadataForField(fieldName, false /* createIfNotFound */);
+        }
+
+        public FieldValidationMetadata GetValidationMetadataForField(string fieldName, bool createIfNotFound) {
+            if (String.IsNullOrEmpty(fieldName)) {
+                throw Error.ParameterCannotBeNullOrEmpty("fieldName");
+            }
+
+            FieldValidationMetadata metadata;
+            if (!FieldValidators.TryGetValue(fieldName, out metadata)) {
+                if (createIfNotFound) {
+                    metadata = new FieldValidationMetadata() {
+                        FieldName = fieldName
+                    };
+                    FieldValidators[fieldName] = metadata;
+                }
+            }
+            return metadata;
+        }
+
+        public bool RenderedField(string fieldName) {
+            bool result;
+            _renderedFields.TryGetValue(fieldName, out result);
+            return result;
+        }
+
+        public void RenderedField(string fieldName, bool value) {
+            _renderedFields[fieldName] = value;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/FormMethod.cs b/mcs/class/System.Web.Mvc3/Mvc/FormMethod.cs
new file mode 100644 (file)
index 0000000..ce94870
--- /dev/null
@@ -0,0 +1,6 @@
+namespace System.Web.Mvc {
+    public enum FormMethod {
+        Get,
+        Post
+    }
+}
\ No newline at end of file
diff --git a/mcs/class/System.Web.Mvc3/Mvc/FormValueProvider.cs b/mcs/class/System.Web.Mvc3/Mvc/FormValueProvider.cs
new file mode 100644 (file)
index 0000000..8da0f67
--- /dev/null
@@ -0,0 +1,18 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Globalization;
+    using System.Web.Helpers;
+
+    public sealed class FormValueProvider : NameValueCollectionValueProvider {
+
+        public FormValueProvider(ControllerContext controllerContext)
+            : this(controllerContext, new UnvalidatedRequestValuesWrapper(controllerContext.HttpContext.Request.Unvalidated())) {
+        }
+
+        // For unit testing
+        internal FormValueProvider(ControllerContext controllerContext, IUnvalidatedRequestValues unvalidatedValues)
+            : base(controllerContext.HttpContext.Request.Form, unvalidatedValues.Form, CultureInfo.CurrentCulture) {
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/FormValueProviderFactory.cs b/mcs/class/System.Web.Mvc3/Mvc/FormValueProviderFactory.cs
new file mode 100644 (file)
index 0000000..7ce0e7c
--- /dev/null
@@ -0,0 +1,28 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Specialized;
+    using System.Web.Helpers;
+
+    public sealed class FormValueProviderFactory : ValueProviderFactory {
+
+        private readonly UnvalidatedRequestValuesAccessor _unvalidatedValuesAccessor;
+
+        public FormValueProviderFactory()
+            : this(null) {
+        }
+
+        // For unit testing
+        internal FormValueProviderFactory(UnvalidatedRequestValuesAccessor unvalidatedValuesAccessor) {
+            _unvalidatedValuesAccessor = unvalidatedValuesAccessor ?? (cc => new UnvalidatedRequestValuesWrapper(cc.HttpContext.Request.Unvalidated()));
+        }
+
+        public override IValueProvider GetValueProvider(ControllerContext controllerContext) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+
+            return new FormValueProvider(controllerContext, _unvalidatedValuesAccessor(controllerContext));
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/GlobalFilterCollection.cs b/mcs/class/System.Web.Mvc3/Mvc/GlobalFilterCollection.cs
new file mode 100644 (file)
index 0000000..de65aaa
--- /dev/null
@@ -0,0 +1,52 @@
+namespace System.Web.Mvc {
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq;
+
+    public sealed class GlobalFilterCollection : IEnumerable<Filter>, IFilterProvider {
+        private List<Filter> _filters = new List<Filter>();
+
+        public int Count {
+            get {
+                return _filters.Count;
+            }
+        }
+
+        public void Add(object filter) {
+            AddInternal(filter, order: null);
+        }
+
+        public void Add(object filter, int order) {
+            AddInternal(filter, order);
+        }
+
+        private void AddInternal(object filter, int? order) {
+            _filters.Add(new Filter(filter, FilterScope.Global, order));
+        }
+
+        public void Clear() {
+            _filters.Clear();
+        }
+
+        public bool Contains(object filter) {
+            return _filters.Any(f => f.Instance == filter);
+        }
+
+        public IEnumerator<Filter> GetEnumerator() {
+            return _filters.GetEnumerator();
+        }
+
+        IEnumerator IEnumerable.GetEnumerator() {
+            return _filters.GetEnumerator();
+        }
+
+        IEnumerable<Filter> IFilterProvider.GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor) {
+            return this;
+        }
+
+        public void Remove(object filter) {
+            _filters.RemoveAll(f => f.Instance == filter);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/GlobalFilters.cs b/mcs/class/System.Web.Mvc3/Mvc/GlobalFilters.cs
new file mode 100644 (file)
index 0000000..abe40f2
--- /dev/null
@@ -0,0 +1,12 @@
+namespace System.Web.Mvc {
+    public static class GlobalFilters {
+        static GlobalFilters() {
+            Filters = new GlobalFilterCollection();
+        }
+
+        public static GlobalFilterCollection Filters {
+            get;
+            private set;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/HandleErrorAttribute.cs b/mcs/class/System.Web.Mvc3/Mvc/HandleErrorAttribute.cs
new file mode 100644 (file)
index 0000000..a20e27b
--- /dev/null
@@ -0,0 +1,106 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Web;
+    using System.Web.Mvc.Resources;
+
+    [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes", Justification = "This attribute is AllowMultiple = true and users might want to override behavior.")]
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
+    public class HandleErrorAttribute : FilterAttribute, IExceptionFilter {
+
+        private const string _defaultView = "Error";
+
+        private readonly object _typeId = new object();
+
+        private Type _exceptionType = typeof(Exception);
+        private string _master;
+        private string _view;
+
+        public Type ExceptionType {
+            get {
+                return _exceptionType;
+            }
+            set {
+                if (value == null) {
+                    throw new ArgumentNullException("value");
+                }
+                if (!typeof(Exception).IsAssignableFrom(value)) {
+                    throw new ArgumentException(String.Format(CultureInfo.CurrentCulture,
+                        MvcResources.ExceptionViewAttribute_NonExceptionType, value.FullName));
+                }
+
+                _exceptionType = value;
+            }
+        }
+
+        public string Master {
+            get {
+                return _master ?? String.Empty;
+            }
+            set {
+                _master = value;
+            }
+        }
+
+        public override object TypeId {
+            get {
+                return _typeId;
+            }
+        }
+
+        public string View {
+            get {
+                return (!String.IsNullOrEmpty(_view)) ? _view : _defaultView;
+            }
+            set {
+                _view = value;
+            }
+        }
+
+        public virtual void OnException(ExceptionContext filterContext) {
+            if (filterContext == null) {
+                throw new ArgumentNullException("filterContext");
+            }
+            if (filterContext.IsChildAction) {
+                return;
+            }
+
+            // If custom errors are disabled, we need to let the normal ASP.NET exception handler
+            // execute so that the user can see useful debugging information.
+            if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled) {
+                return;
+            }
+
+            Exception exception = filterContext.Exception;
+
+            // If this is not an HTTP 500 (for example, if somebody throws an HTTP 404 from an action method),
+            // ignore it.
+            if (new HttpException(null, exception).GetHttpCode() != 500) {
+                return;
+            }
+
+            if (!ExceptionType.IsInstanceOfType(exception)) {
+                return;
+            }
+
+            string controllerName = (string)filterContext.RouteData.Values["controller"];
+            string actionName = (string)filterContext.RouteData.Values["action"];
+            HandleErrorInfo model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
+            filterContext.Result = new ViewResult {
+                ViewName = View,
+                MasterName = Master,
+                ViewData = new ViewDataDictionary<HandleErrorInfo>(model),
+                TempData = filterContext.Controller.TempData
+            };
+            filterContext.ExceptionHandled = true;
+            filterContext.HttpContext.Response.Clear();
+            filterContext.HttpContext.Response.StatusCode = 500;
+
+            // Certain versions of IIS will sometimes use their own error page when
+            // they detect a server error. Setting this property indicates that we
+            // want it to try to render ASP.NET MVC's error page instead.
+            filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
+        }
+    }
+}
\ No newline at end of file
diff --git a/mcs/class/System.Web.Mvc3/Mvc/HandleErrorInfo.cs b/mcs/class/System.Web.Mvc3/Mvc/HandleErrorInfo.cs
new file mode 100644 (file)
index 0000000..b765cbe
--- /dev/null
@@ -0,0 +1,39 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Web.Mvc.Resources;
+
+    public class HandleErrorInfo {
+
+        public HandleErrorInfo(Exception exception, string controllerName, string actionName) {
+            if (exception == null) {
+                throw new ArgumentNullException("exception");
+            }
+            if (String.IsNullOrEmpty(controllerName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "controllerName");
+            }
+            if (string.IsNullOrEmpty(actionName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "actionName");
+            }
+
+            Exception = exception;
+            ControllerName = controllerName;
+            ActionName = actionName;
+        }
+
+        public string ActionName {
+            get;
+            private set;
+        }
+
+        public string ControllerName {
+            get;
+            private set;
+        }
+
+        public Exception Exception {
+            get;
+            private set;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/HiddenInputAttribute.cs b/mcs/class/System.Web.Mvc3/Mvc/HiddenInputAttribute.cs
new file mode 100644 (file)
index 0000000..ed8e0b9
--- /dev/null
@@ -0,0 +1,12 @@
+namespace System.Web.Mvc {
+    using System;
+
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
+    public sealed class HiddenInputAttribute : Attribute {
+        public HiddenInputAttribute() {
+            DisplayValue = true;
+        }
+
+        public bool DisplayValue { get; set; }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Html/ChildActionExtensions.cs b/mcs/class/System.Web.Mvc3/Mvc/Html/ChildActionExtensions.cs
new file mode 100644 (file)
index 0000000..c77224c
--- /dev/null
@@ -0,0 +1,149 @@
+namespace System.Web.Mvc.Html {
+    using System.Collections.Generic;
+    using System.Globalization;
+    using System.IO;
+    using System.Linq;
+    using System.Web.Mvc.Resources;
+    using System.Web.Routing;
+
+    public static class ChildActionExtensions {
+
+        // Action
+
+        public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName) {
+            return Action(htmlHelper, actionName, null /* controllerName */, null /* routeValues */);
+        }
+
+        public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName, object routeValues) {
+            return Action(htmlHelper, actionName, null /* controllerName */, new RouteValueDictionary(routeValues));
+        }
+
+        public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName, RouteValueDictionary routeValues) {
+            return Action(htmlHelper, actionName, null /* controllerName */, routeValues);
+        }
+
+        public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName, string controllerName) {
+            return Action(htmlHelper, actionName, controllerName, null /* routeValues */);
+        }
+
+        public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName, string controllerName, object routeValues) {
+            return Action(htmlHelper, actionName, controllerName, new RouteValueDictionary(routeValues));
+        }
+
+        public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName, string controllerName, RouteValueDictionary routeValues) {
+            using (StringWriter writer = new StringWriter(CultureInfo.CurrentCulture)) {
+                ActionHelper(htmlHelper, actionName, controllerName, routeValues, writer);
+                return MvcHtmlString.Create(writer.ToString());
+            }
+        }
+
+        // RenderAction
+
+        public static void RenderAction(this HtmlHelper htmlHelper, string actionName) {
+            RenderAction(htmlHelper, actionName, null /* controllerName */, null /* routeValues */);
+        }
+
+        public static void RenderAction(this HtmlHelper htmlHelper, string actionName, object routeValues) {
+            RenderAction(htmlHelper, actionName, null /* controllerName */, new RouteValueDictionary(routeValues));
+        }
+
+        public static void RenderAction(this HtmlHelper htmlHelper, string actionName, RouteValueDictionary routeValues) {
+            RenderAction(htmlHelper, actionName, null /* controllerName */, routeValues);
+        }
+
+        public static void RenderAction(this HtmlHelper htmlHelper, string actionName, string controllerName) {
+            RenderAction(htmlHelper, actionName, controllerName, null /* routeValues */);
+        }
+
+        public static void RenderAction(this HtmlHelper htmlHelper, string actionName, string controllerName, object routeValues) {
+            RenderAction(htmlHelper, actionName, controllerName, new RouteValueDictionary(routeValues));
+        }
+
+        public static void RenderAction(this HtmlHelper htmlHelper, string actionName, string controllerName, RouteValueDictionary routeValues) {
+            ActionHelper(htmlHelper, actionName, controllerName, routeValues, htmlHelper.ViewContext.Writer);
+        }
+
+        // Helpers
+
+        internal static void ActionHelper(HtmlHelper htmlHelper, string actionName, string controllerName, RouteValueDictionary routeValues, TextWriter textWriter) {
+            if (htmlHelper == null) {
+                throw new ArgumentNullException("htmlHelper");
+            }
+            if (String.IsNullOrEmpty(actionName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "actionName");
+            }
+
+            RouteValueDictionary additionalRouteValues = routeValues;
+            routeValues = MergeDictionaries(routeValues, htmlHelper.ViewContext.RouteData.Values);
+                     
+            routeValues["action"] = actionName;
+            if (!String.IsNullOrEmpty(controllerName)) {
+                routeValues["controller"] = controllerName;
+            }
+
+            bool usingAreas;
+            VirtualPathData vpd = htmlHelper.RouteCollection.GetVirtualPathForArea(htmlHelper.ViewContext.RequestContext, null /* name */, routeValues, out usingAreas);
+            if (vpd == null) {
+                throw new InvalidOperationException(MvcResources.Common_NoRouteMatched);
+            }
+   
+            if (usingAreas) {
+                routeValues.Remove("area");
+                if (additionalRouteValues != null) {
+                    additionalRouteValues.Remove("area");
+                }
+            }
+
+            if (additionalRouteValues != null) {
+                routeValues[ChildActionValueProvider.ChildActionValuesKey] = new DictionaryValueProvider<object>(additionalRouteValues, CultureInfo.InvariantCulture);
+            }
+
+            RouteData routeData = CreateRouteData(vpd.Route, routeValues, vpd.DataTokens, htmlHelper.ViewContext);
+            HttpContextBase httpContext = htmlHelper.ViewContext.HttpContext;
+            RequestContext requestContext = new RequestContext(httpContext, routeData);
+            ChildActionMvcHandler handler = new ChildActionMvcHandler(requestContext);
+            httpContext.Server.Execute(HttpHandlerUtil.WrapForServerExecute(handler), textWriter, true /* preserveForm */);
+        }
+
+        private static RouteData CreateRouteData(RouteBase route, RouteValueDictionary routeValues, RouteValueDictionary dataTokens, ViewContext parentViewContext) {
+            RouteData routeData = new RouteData();
+
+            foreach (KeyValuePair<string, object> kvp in routeValues) {
+                routeData.Values.Add(kvp.Key, kvp.Value);
+            }
+
+            foreach (KeyValuePair<string, object> kvp in dataTokens) {
+                routeData.DataTokens.Add(kvp.Key, kvp.Value);
+            }
+
+            routeData.Route = route;
+            routeData.DataTokens[ControllerContext.PARENT_ACTION_VIEWCONTEXT] = parentViewContext;
+            return routeData;
+        }
+
+        private static RouteValueDictionary MergeDictionaries(params RouteValueDictionary[] dictionaries) {
+            // Merge existing route values with the user provided values
+            var result = new RouteValueDictionary();
+
+            foreach (RouteValueDictionary dictionary in dictionaries.Where(d => d != null)) {
+                foreach (KeyValuePair<string, object> kvp in dictionary) {
+                    if (!result.ContainsKey(kvp.Key)) {
+                        result.Add(kvp.Key, kvp.Value);
+                    }
+                }
+            }
+
+            return result;
+        }
+
+        internal class ChildActionMvcHandler : MvcHandler {
+            public ChildActionMvcHandler(RequestContext context)
+                : base(context) {
+            }
+
+            protected internal override void AddVersionHeader(HttpContextBase httpContext) {
+                // No version header for child actions
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Html/DefaultDisplayTemplates.cs b/mcs/class/System.Web.Mvc3/Mvc/Html/DefaultDisplayTemplates.cs
new file mode 100644 (file)
index 0000000..5a24792
--- /dev/null
@@ -0,0 +1,194 @@
+namespace System.Web.Mvc.Html {
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Data;
+    using System.Globalization;
+    using System.Linq;
+    using System.Text;
+    using System.Web.Mvc.Resources;
+    using System.Web.UI.WebControls;
+
+    internal static class DefaultDisplayTemplates {
+        internal static string BooleanTemplate(HtmlHelper html) {
+            bool? value = null;
+            if (html.ViewContext.ViewData.Model != null) {
+                value = Convert.ToBoolean(html.ViewContext.ViewData.Model, CultureInfo.InvariantCulture);
+            }
+
+            return html.ViewContext.ViewData.ModelMetadata.IsNullableValueType
+                        ? BooleanTemplateDropDownList(value)
+                        : BooleanTemplateCheckbox(value ?? false);
+        }
+
+        private static string BooleanTemplateCheckbox(bool value) {
+            TagBuilder inputTag = new TagBuilder("input");
+            inputTag.AddCssClass("check-box");
+            inputTag.Attributes["disabled"] = "disabled";
+            inputTag.Attributes["type"] = "checkbox";
+            if (value) {
+                inputTag.Attributes["checked"] = "checked";
+            }
+
+            return inputTag.ToString(TagRenderMode.SelfClosing);
+        }
+
+        private static string BooleanTemplateDropDownList(bool? value) {
+            StringBuilder builder = new StringBuilder();
+
+            TagBuilder selectTag = new TagBuilder("select");
+            selectTag.AddCssClass("list-box");
+            selectTag.AddCssClass("tri-state");
+            selectTag.Attributes["disabled"] = "disabled";
+            builder.Append(selectTag.ToString(TagRenderMode.StartTag));
+
+            foreach (SelectListItem item in DefaultEditorTemplates.TriStateValues(value)) {
+                builder.Append(SelectExtensions.ListItemToOption(item));
+            }
+
+            builder.Append(selectTag.ToString(TagRenderMode.EndTag));
+            return builder.ToString();
+        }
+
+        internal static string CollectionTemplate(HtmlHelper html) {
+            return CollectionTemplate(html, TemplateHelpers.TemplateHelper);
+        }
+
+        internal static string CollectionTemplate(HtmlHelper html, TemplateHelpers.TemplateHelperDelegate templateHelper) {
+            object model = html.ViewContext.ViewData.ModelMetadata.Model;
+            if (model == null) {
+                return String.Empty;
+            }
+
+            IEnumerable collection = model as IEnumerable;
+            if (collection == null) {
+                throw new InvalidOperationException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.Templates_TypeMustImplementIEnumerable,
+                        model.GetType().FullName
+                    )
+                );
+            }
+
+            Type typeInCollection = typeof(string);
+            Type genericEnumerableType = TypeHelpers.ExtractGenericInterface(collection.GetType(), typeof(IEnumerable<>));
+            if (genericEnumerableType != null) {
+                typeInCollection = genericEnumerableType.GetGenericArguments()[0];
+            }
+            bool typeInCollectionIsNullableValueType = TypeHelpers.IsNullableValueType(typeInCollection);
+
+            string oldPrefix = html.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix;
+
+            try {
+                html.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = String.Empty;
+
+                string fieldNameBase = oldPrefix;
+                StringBuilder result = new StringBuilder();
+                int index = 0;
+
+                foreach (object item in collection) {
+                    Type itemType = typeInCollection;
+                    if (item != null && !typeInCollectionIsNullableValueType) {
+                        itemType = item.GetType();
+                    }
+                    ModelMetadata metadata = ModelMetadataProviders.Current.GetMetadataForType(() => item, itemType);
+                    string fieldName = String.Format(CultureInfo.InvariantCulture, "{0}[{1}]", fieldNameBase, index++);
+                    string output = templateHelper(html, metadata, fieldName, null /* templateName */, DataBoundControlMode.ReadOnly, null /* additionalViewData */);
+                    result.Append(output);
+                }
+
+                return result.ToString();
+            }
+            finally {
+                html.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = oldPrefix;
+            }
+        }
+
+        internal static string DecimalTemplate(HtmlHelper html) {
+            if (html.ViewContext.ViewData.TemplateInfo.FormattedModelValue == html.ViewContext.ViewData.ModelMetadata.Model) {
+                html.ViewContext.ViewData.TemplateInfo.FormattedModelValue = String.Format(CultureInfo.CurrentCulture, "{0:0.00}", html.ViewContext.ViewData.ModelMetadata.Model);
+            }
+
+            return StringTemplate(html);
+        }
+
+        internal static string EmailAddressTemplate(HtmlHelper html) {
+            return String.Format(CultureInfo.InvariantCulture,
+                                 "<a href=\"mailto:{0}\">{1}</a>",
+                                 html.AttributeEncode(html.ViewContext.ViewData.Model),
+                                 html.Encode(html.ViewContext.ViewData.TemplateInfo.FormattedModelValue));
+        }
+
+        internal static string HiddenInputTemplate(HtmlHelper html) {
+            if (html.ViewContext.ViewData.ModelMetadata.HideSurroundingHtml) {
+                return String.Empty;
+            }
+            return StringTemplate(html);
+        }
+
+        internal static string HtmlTemplate(HtmlHelper html) {
+            return html.ViewContext.ViewData.TemplateInfo.FormattedModelValue.ToString();
+        }
+
+        internal static string ObjectTemplate(HtmlHelper html) {
+            return ObjectTemplate(html, TemplateHelpers.TemplateHelper);
+        }
+
+        internal static string ObjectTemplate(HtmlHelper html, TemplateHelpers.TemplateHelperDelegate templateHelper) {
+            ViewDataDictionary viewData = html.ViewContext.ViewData;
+            TemplateInfo templateInfo = viewData.TemplateInfo;
+            ModelMetadata modelMetadata = viewData.ModelMetadata;
+            StringBuilder builder = new StringBuilder();
+
+            if (modelMetadata.Model == null) {    // DDB #225237
+                return modelMetadata.NullDisplayText;
+            }
+
+            if (templateInfo.TemplateDepth > 1) {    // DDB #224751
+                return modelMetadata.SimpleDisplayText;
+            }
+
+            foreach (ModelMetadata propertyMetadata in modelMetadata.Properties.Where(pm => ShouldShow(pm, templateInfo))) {
+                if (!propertyMetadata.HideSurroundingHtml) {
+                    string label = propertyMetadata.GetDisplayName();
+                    if (!String.IsNullOrEmpty(label)) {
+                        builder.AppendFormat(CultureInfo.InvariantCulture, "<div class=\"display-label\">{0}</div>", label);
+                        builder.AppendLine();
+                    }
+
+                    builder.Append("<div class=\"display-field\">");
+                }
+
+                builder.Append(templateHelper(html, propertyMetadata, propertyMetadata.PropertyName, null /* templateName */, DataBoundControlMode.ReadOnly, null /* additionalViewData */));
+
+                if (!propertyMetadata.HideSurroundingHtml) {
+                    builder.AppendLine("</div>");
+                }
+            }
+
+            return builder.ToString();
+        }
+
+        private static bool ShouldShow(ModelMetadata metadata, TemplateInfo templateInfo) {
+            return
+                metadata.ShowForDisplay
+#if !MONO
+                && metadata.ModelType != typeof(EntityState)
+#endif
+                && !metadata.IsComplexType
+                && !templateInfo.Visited(metadata);
+        }
+
+        internal static string StringTemplate(HtmlHelper html) {
+            return html.Encode(html.ViewContext.ViewData.TemplateInfo.FormattedModelValue);
+        }
+
+        internal static string UrlTemplate(HtmlHelper html) {
+            return String.Format(CultureInfo.InvariantCulture,
+                                 "<a href=\"{0}\">{1}</a>",
+                                 html.AttributeEncode(html.ViewContext.ViewData.Model),
+                                 html.Encode(html.ViewContext.ViewData.TemplateInfo.FormattedModelValue));
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Html/DefaultEditorTemplates.cs b/mcs/class/System.Web.Mvc3/Mvc/Html/DefaultEditorTemplates.cs
new file mode 100644 (file)
index 0000000..2db72c9
--- /dev/null
@@ -0,0 +1,203 @@
+namespace System.Web.Mvc.Html {
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Data;
+    using System.Data.Linq;
+    using System.Globalization;
+    using System.Linq;
+    using System.Text;
+    using System.Web.Mvc.Resources;
+    using System.Web.UI.WebControls;
+
+    internal static class DefaultEditorTemplates {
+        internal static string BooleanTemplate(HtmlHelper html) {
+            bool? value = null;
+            if (html.ViewContext.ViewData.Model != null) {
+                value = Convert.ToBoolean(html.ViewContext.ViewData.Model, CultureInfo.InvariantCulture);
+            }
+
+            return html.ViewContext.ViewData.ModelMetadata.IsNullableValueType
+                        ? BooleanTemplateDropDownList(html, value)
+                        : BooleanTemplateCheckbox(html, value ?? false);
+        }
+
+        private static string BooleanTemplateCheckbox(HtmlHelper html, bool value) {
+            return html.CheckBox(String.Empty, value, CreateHtmlAttributes("check-box")).ToHtmlString();
+        }
+
+        private static string BooleanTemplateDropDownList(HtmlHelper html, bool? value) {
+            return html.DropDownList(String.Empty, TriStateValues(value), CreateHtmlAttributes("list-box tri-state")).ToHtmlString();
+
+        }
+
+        internal static string CollectionTemplate(HtmlHelper html) {
+            return CollectionTemplate(html, TemplateHelpers.TemplateHelper);
+        }
+
+        internal static string CollectionTemplate(HtmlHelper html, TemplateHelpers.TemplateHelperDelegate templateHelper) {
+            object model = html.ViewContext.ViewData.ModelMetadata.Model;
+            if (model == null) {
+                return String.Empty;
+            }
+
+            IEnumerable collection = model as IEnumerable;
+            if (collection == null) {
+                throw new InvalidOperationException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.Templates_TypeMustImplementIEnumerable,
+                        model.GetType().FullName
+                    )
+                );
+            }
+
+            Type typeInCollection = typeof(string);
+            Type genericEnumerableType = TypeHelpers.ExtractGenericInterface(collection.GetType(), typeof(IEnumerable<>));
+            if (genericEnumerableType != null) {
+                typeInCollection = genericEnumerableType.GetGenericArguments()[0];
+            }
+            bool typeInCollectionIsNullableValueType = TypeHelpers.IsNullableValueType(typeInCollection);
+
+            string oldPrefix = html.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix;
+
+            try {
+                html.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = String.Empty;
+
+                string fieldNameBase = oldPrefix;
+                StringBuilder result = new StringBuilder();
+                int index = 0;
+
+                foreach (object item in collection) {
+                    Type itemType = typeInCollection;
+                    if (item != null && !typeInCollectionIsNullableValueType) {
+                        itemType = item.GetType();
+                    }
+                    ModelMetadata metadata = ModelMetadataProviders.Current.GetMetadataForType(() => item, itemType);
+                    string fieldName = String.Format(CultureInfo.InvariantCulture, "{0}[{1}]", fieldNameBase, index++);
+                    string output = templateHelper(html, metadata, fieldName, null /* templateName */, DataBoundControlMode.Edit, null /* additionalViewData */);
+                    result.Append(output);
+                }
+
+                return result.ToString();
+            }
+            finally {
+                html.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = oldPrefix;
+            }
+        }
+
+        internal static string DecimalTemplate(HtmlHelper html) {
+            if (html.ViewContext.ViewData.TemplateInfo.FormattedModelValue == html.ViewContext.ViewData.ModelMetadata.Model) {
+                html.ViewContext.ViewData.TemplateInfo.FormattedModelValue = String.Format(CultureInfo.CurrentCulture, "{0:0.00}", html.ViewContext.ViewData.ModelMetadata.Model);
+            }
+
+            return StringTemplate(html);
+        }
+
+        internal static string HiddenInputTemplate(HtmlHelper html) {
+            string result;
+
+            if (html.ViewContext.ViewData.ModelMetadata.HideSurroundingHtml) {
+                result = String.Empty;
+            }
+            else {
+                result = DefaultDisplayTemplates.StringTemplate(html);
+            }
+
+            object model = html.ViewContext.ViewData.Model;
+
+            Binary modelAsBinary = model as Binary;
+            if (modelAsBinary != null) {
+                model = Convert.ToBase64String(modelAsBinary.ToArray());
+            }
+            else {
+                byte[] modelAsByteArray = model as byte[];
+                if (modelAsByteArray != null) {
+                    model = Convert.ToBase64String(modelAsByteArray);
+                }
+            }
+
+            result += html.Hidden(String.Empty, model).ToHtmlString();
+            return result;
+        }
+
+        internal static string MultilineTextTemplate(HtmlHelper html) {
+            return html.TextArea(String.Empty,
+                                 html.ViewContext.ViewData.TemplateInfo.FormattedModelValue.ToString(),
+                                 0 /* rows */, 0 /* columns */,
+                                 CreateHtmlAttributes("text-box multi-line")).ToHtmlString();
+        }
+
+        private static IDictionary<string, object> CreateHtmlAttributes(string className) {
+            return new Dictionary<string, object>() {
+                { "class", className }
+            };
+        }
+
+        internal static string ObjectTemplate(HtmlHelper html) {
+            return ObjectTemplate(html, TemplateHelpers.TemplateHelper);
+        }
+
+        internal static string ObjectTemplate(HtmlHelper html, TemplateHelpers.TemplateHelperDelegate templateHelper) {
+            ViewDataDictionary viewData = html.ViewContext.ViewData;
+            TemplateInfo templateInfo = viewData.TemplateInfo;
+            ModelMetadata modelMetadata = viewData.ModelMetadata;
+            StringBuilder builder = new StringBuilder();
+
+            if (templateInfo.TemplateDepth > 1) {    // DDB #224751
+                return modelMetadata.Model == null ? modelMetadata.NullDisplayText : modelMetadata.SimpleDisplayText;
+            }
+
+            foreach (ModelMetadata propertyMetadata in modelMetadata.Properties.Where(pm => ShouldShow(pm, templateInfo))) {
+                if (!propertyMetadata.HideSurroundingHtml) {
+                    string label = LabelExtensions.LabelHelper(html, propertyMetadata, propertyMetadata.PropertyName).ToHtmlString();
+                    if (!String.IsNullOrEmpty(label)) {
+                        builder.AppendFormat(CultureInfo.InvariantCulture, "<div class=\"editor-label\">{0}</div>\r\n", label);
+                    }
+
+                    builder.Append("<div class=\"editor-field\">");
+                }
+
+                builder.Append(templateHelper(html, propertyMetadata, propertyMetadata.PropertyName, null /* templateName */, DataBoundControlMode.Edit, null /* additionalViewData */));
+
+                if (!propertyMetadata.HideSurroundingHtml) {
+                    builder.Append(" ");
+                    builder.Append(html.ValidationMessage(propertyMetadata.PropertyName));
+                    builder.Append("</div>\r\n");
+                }
+            }
+
+            return builder.ToString();
+        }
+
+        internal static string PasswordTemplate(HtmlHelper html) {
+            return html.Password(String.Empty,
+                                 html.ViewContext.ViewData.TemplateInfo.FormattedModelValue,
+                                 CreateHtmlAttributes("text-box single-line password")).ToHtmlString();
+        }
+
+        private static bool ShouldShow(ModelMetadata metadata, TemplateInfo templateInfo) {
+            return
+                metadata.ShowForEdit
+#if !MONO
+                && metadata.ModelType != typeof(EntityState)
+#endif
+                && !metadata.IsComplexType
+                && !templateInfo.Visited(metadata);
+        }
+
+        internal static string StringTemplate(HtmlHelper html) {
+            return html.TextBox(String.Empty,
+                                html.ViewContext.ViewData.TemplateInfo.FormattedModelValue,
+                                CreateHtmlAttributes("text-box single-line")).ToHtmlString();
+        }
+
+        internal static List<SelectListItem> TriStateValues(bool? value) {
+            return new List<SelectListItem> {
+                new SelectListItem { Text = MvcResources.Common_TriState_NotSet, Value = String.Empty, Selected = !value.HasValue },
+                new SelectListItem { Text = MvcResources.Common_TriState_True, Value = "true", Selected = value.HasValue && value.Value },
+                new SelectListItem { Text = MvcResources.Common_TriState_False, Value = "false", Selected = value.HasValue && !value.Value },
+            };
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Html/DisplayExtensions.cs b/mcs/class/System.Web.Mvc3/Mvc/Html/DisplayExtensions.cs
new file mode 100644 (file)
index 0000000..73312e9
--- /dev/null
@@ -0,0 +1,85 @@
+namespace System.Web.Mvc.Html {
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq.Expressions;
+    using System.Web.UI.WebControls;
+
+    public static class DisplayExtensions {
+        public static MvcHtmlString Display(this HtmlHelper html, string expression) {
+            return TemplateHelpers.Template(html, expression, null /* templateName */, null /* htmlFieldName */, DataBoundControlMode.ReadOnly, null /* additionalViewData */);
+        }
+
+        public static MvcHtmlString Display(this HtmlHelper html, string expression, object additionalViewData) {
+            return TemplateHelpers.Template(html, expression, null /* templateName */, null /* htmlFieldName */, DataBoundControlMode.ReadOnly, additionalViewData);
+        }
+
+        public static MvcHtmlString Display(this HtmlHelper html, string expression, string templateName) {
+            return TemplateHelpers.Template(html, expression, templateName, null /* htmlFieldName */, DataBoundControlMode.ReadOnly, null /* additionalViewData */);
+        }
+
+        public static MvcHtmlString Display(this HtmlHelper html, string expression, string templateName, object additionalViewData) {
+            return TemplateHelpers.Template(html, expression, templateName, null /* htmlFieldName */, DataBoundControlMode.ReadOnly, additionalViewData);
+        }
+
+        public static MvcHtmlString Display(this HtmlHelper html, string expression, string templateName, string htmlFieldName) {
+            return TemplateHelpers.Template(html, expression, templateName, htmlFieldName, DataBoundControlMode.ReadOnly, null /* additionalViewData */);
+        }
+
+        public static MvcHtmlString Display(this HtmlHelper html, string expression, string templateName, string htmlFieldName, object additionalViewData) {
+            return TemplateHelpers.Template(html, expression, templateName, htmlFieldName, DataBoundControlMode.ReadOnly, additionalViewData);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString DisplayFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression) {
+            return TemplateHelpers.TemplateFor(html, expression, null /* templateName */, null /* htmlFieldName */, DataBoundControlMode.ReadOnly, null /* additionalViewData */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString DisplayFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object additionalViewData) {
+            return TemplateHelpers.TemplateFor(html, expression, null /* templateName */, null /* htmlFieldName */, DataBoundControlMode.ReadOnly, additionalViewData);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString DisplayFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, string templateName) {
+            return TemplateHelpers.TemplateFor(html, expression, templateName, null /* htmlFieldName */, DataBoundControlMode.ReadOnly, null /* additionalViewData */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString DisplayFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, string templateName, object additionalViewData) {
+            return TemplateHelpers.TemplateFor(html, expression, templateName, null /* htmlFieldName */, DataBoundControlMode.ReadOnly, additionalViewData);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString DisplayFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, string templateName, string htmlFieldName) {
+            return TemplateHelpers.TemplateFor(html, expression, templateName, htmlFieldName, DataBoundControlMode.ReadOnly, null /* additionalViewData */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString DisplayFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, string templateName, string htmlFieldName, object additionalViewData) {
+            return TemplateHelpers.TemplateFor(html, expression, templateName, htmlFieldName, DataBoundControlMode.ReadOnly, additionalViewData);
+        }
+
+        public static MvcHtmlString DisplayForModel(this HtmlHelper html) {
+            return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, String.Empty, null /* templateName */, DataBoundControlMode.ReadOnly, null /* additionalViewData */));
+        }
+
+        public static MvcHtmlString DisplayForModel(this HtmlHelper html, object additionalViewData) {
+            return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, String.Empty, null /* templateName */, DataBoundControlMode.ReadOnly, additionalViewData));
+        }
+
+        public static MvcHtmlString DisplayForModel(this HtmlHelper html, string templateName) {
+            return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, String.Empty, templateName, DataBoundControlMode.ReadOnly, null /* additionalViewData */));
+        }
+
+        public static MvcHtmlString DisplayForModel(this HtmlHelper html, string templateName, object additionalViewData) {
+            return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, String.Empty, templateName, DataBoundControlMode.ReadOnly, additionalViewData));
+        }
+
+        public static MvcHtmlString DisplayForModel(this HtmlHelper html, string templateName, string htmlFieldName) {
+            return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, htmlFieldName, templateName, DataBoundControlMode.ReadOnly, null /* additionalViewData */));
+        }
+
+        public static MvcHtmlString DisplayForModel(this HtmlHelper html, string templateName, string htmlFieldName, object additionalViewData) {
+            return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, htmlFieldName, templateName, DataBoundControlMode.ReadOnly, additionalViewData));
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Html/DisplayTextExtensions.cs b/mcs/class/System.Web.Mvc3/Mvc/Html/DisplayTextExtensions.cs
new file mode 100644 (file)
index 0000000..9d31896
--- /dev/null
@@ -0,0 +1,20 @@
+namespace System.Web.Mvc.Html {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq.Expressions;
+
+    public static class DisplayTextExtensions {
+        public static MvcHtmlString DisplayText(this HtmlHelper html, string name) {
+            return DisplayTextHelper(ModelMetadata.FromStringExpression(name, html.ViewContext.ViewData));
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString DisplayTextFor<TModel, TResult>(this HtmlHelper<TModel> html, Expression<Func<TModel, TResult>> expression) {
+            return DisplayTextHelper(ModelMetadata.FromLambdaExpression(expression, html.ViewData));
+        }
+
+        private static MvcHtmlString DisplayTextHelper(ModelMetadata metadata) {
+            return MvcHtmlString.Create(metadata.SimpleDisplayText);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Html/EditorExtensions.cs b/mcs/class/System.Web.Mvc3/Mvc/Html/EditorExtensions.cs
new file mode 100644 (file)
index 0000000..d3f4354
--- /dev/null
@@ -0,0 +1,86 @@
+namespace System.Web.Mvc.Html {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq.Expressions;
+    using System.Web.UI.WebControls;
+
+    public static class EditorExtensions {
+        public static MvcHtmlString Editor(this HtmlHelper html, string expression) {
+            return TemplateHelpers.Template(html, expression, null /* templateName */, null /* htmlFieldName */, DataBoundControlMode.Edit, null /* additionalViewData */);
+        }
+
+        public static MvcHtmlString Editor(this HtmlHelper html, string expression, object additionalViewData) {
+            return TemplateHelpers.Template(html, expression, null /* templateName */, null /* htmlFieldName */, DataBoundControlMode.Edit, additionalViewData);
+        }
+
+        public static MvcHtmlString Editor(this HtmlHelper html, string expression, string templateName) {
+            return TemplateHelpers.Template(html, expression, templateName, null /* htmlFieldName */, DataBoundControlMode.Edit, null /* additionalViewData */);
+        }
+
+        public static MvcHtmlString Editor(this HtmlHelper html, string expression, string templateName, object additionalViewData) {
+            return TemplateHelpers.Template(html, expression, templateName, null /* htmlFieldName */, DataBoundControlMode.Edit, additionalViewData);
+        }
+
+        public static MvcHtmlString Editor(this HtmlHelper html, string expression, string templateName, string htmlFieldName) {
+            return TemplateHelpers.Template(html, expression, templateName, htmlFieldName, DataBoundControlMode.Edit, null /* additionalViewData */);
+        }
+
+        public static MvcHtmlString Editor(this HtmlHelper html, string expression, string templateName, string htmlFieldName, object additionalViewData) {
+            return TemplateHelpers.Template(html, expression, templateName, htmlFieldName, DataBoundControlMode.Edit, additionalViewData);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString EditorFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression) {
+            return TemplateHelpers.TemplateFor(html, expression, null /* templateName */, null /* htmlFieldName */, DataBoundControlMode.Edit, null /* additionalViewData */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString EditorFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object additionalViewData) {
+            return TemplateHelpers.TemplateFor(html, expression, null /* templateName */, null /* htmlFieldName */, DataBoundControlMode.Edit, additionalViewData);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString EditorFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, string templateName) {
+            return TemplateHelpers.TemplateFor(html, expression, templateName, null /* htmlFieldName */, DataBoundControlMode.Edit, null /* additionalViewData */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString EditorFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, string templateName, object additionalViewData) {
+            return TemplateHelpers.TemplateFor(html, expression, templateName, null /* htmlFieldName */, DataBoundControlMode.Edit, additionalViewData);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString EditorFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, string templateName, string htmlFieldName) {
+            return TemplateHelpers.TemplateFor(html, expression, templateName, htmlFieldName, DataBoundControlMode.Edit, null /* additionalViewData */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString EditorFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, string templateName, string htmlFieldName, object additionalViewData) {
+            return TemplateHelpers.TemplateFor(html, expression, templateName, htmlFieldName, DataBoundControlMode.Edit, additionalViewData);
+        }
+
+        public static MvcHtmlString EditorForModel(this HtmlHelper html) {
+            return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, String.Empty, null /* templateName */, DataBoundControlMode.Edit, null /* additionalViewData */));
+        }
+
+        public static MvcHtmlString EditorForModel(this HtmlHelper html, object additionalViewData) {
+            return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, String.Empty, null /* templateName */, DataBoundControlMode.Edit, additionalViewData));
+        }
+
+        public static MvcHtmlString EditorForModel(this HtmlHelper html, string templateName) {
+            return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, String.Empty, templateName, DataBoundControlMode.Edit, null /* additionalViewData */));
+        }
+
+        public static MvcHtmlString EditorForModel(this HtmlHelper html, string templateName, object additionalViewData) {
+            return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, String.Empty, templateName, DataBoundControlMode.Edit, additionalViewData));
+        }
+
+        public static MvcHtmlString EditorForModel(this HtmlHelper html, string templateName, string htmlFieldName) {
+            return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, htmlFieldName, templateName, DataBoundControlMode.Edit, null /* additionalViewData */));
+        }
+
+        public static MvcHtmlString EditorForModel(this HtmlHelper html, string templateName, string htmlFieldName, object additionalViewData) {
+            return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, htmlFieldName, templateName, DataBoundControlMode.Edit, additionalViewData));
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Html/FormExtensions.cs b/mcs/class/System.Web.Mvc3/Mvc/Html/FormExtensions.cs
new file mode 100644 (file)
index 0000000..5bd7791
--- /dev/null
@@ -0,0 +1,143 @@
+namespace System.Web.Mvc.Html {
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Web.Routing;
+
+    public static class FormExtensions {
+        public static MvcForm BeginForm(this HtmlHelper htmlHelper) {
+            // generates <form action="{current url}" method="post">...</form>
+            string formAction = htmlHelper.ViewContext.HttpContext.Request.RawUrl;
+            return FormHelper(htmlHelper, formAction, FormMethod.Post, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginForm(this HtmlHelper htmlHelper, object routeValues) {
+            return BeginForm(htmlHelper, null, null, new RouteValueDictionary(routeValues), FormMethod.Post, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginForm(this HtmlHelper htmlHelper, RouteValueDictionary routeValues) {
+            return BeginForm(htmlHelper, null, null, routeValues, FormMethod.Post, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName) {
+            return BeginForm(htmlHelper, actionName, controllerName, new RouteValueDictionary(), FormMethod.Post, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, object routeValues) {
+            return BeginForm(htmlHelper, actionName, controllerName, new RouteValueDictionary(routeValues), FormMethod.Post, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, RouteValueDictionary routeValues) {
+            return BeginForm(htmlHelper, actionName, controllerName, routeValues, FormMethod.Post, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, FormMethod method) {
+            return BeginForm(htmlHelper, actionName, controllerName, new RouteValueDictionary(), method, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, object routeValues, FormMethod method) {
+            return BeginForm(htmlHelper, actionName, controllerName, new RouteValueDictionary(routeValues), method, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, RouteValueDictionary routeValues, FormMethod method) {
+            return BeginForm(htmlHelper, actionName, controllerName, routeValues, method, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, FormMethod method, object htmlAttributes) {
+            return BeginForm(htmlHelper, actionName, controllerName, new RouteValueDictionary(), method, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, FormMethod method, IDictionary<string, object> htmlAttributes) {
+            return BeginForm(htmlHelper, actionName, controllerName, new RouteValueDictionary(), method, htmlAttributes);
+        }
+
+        public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, object routeValues, FormMethod method, object htmlAttributes) {
+            return BeginForm(htmlHelper, actionName, controllerName, new RouteValueDictionary(routeValues), method, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, RouteValueDictionary routeValues, FormMethod method, IDictionary<string, object> htmlAttributes) {
+            string formAction = UrlHelper.GenerateUrl(null /* routeName */, actionName, controllerName, routeValues, htmlHelper.RouteCollection, htmlHelper.ViewContext.RequestContext, true /* includeImplicitMvcValues */);
+            return FormHelper(htmlHelper, formAction, method, htmlAttributes);
+        }
+
+        public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, object routeValues) {
+            return BeginRouteForm(htmlHelper, null /* routeName */, new RouteValueDictionary(routeValues), FormMethod.Post, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, RouteValueDictionary routeValues) {
+            return BeginRouteForm(htmlHelper, null /* routeName */, routeValues, FormMethod.Post, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, string routeName) {
+            return BeginRouteForm(htmlHelper, routeName, new RouteValueDictionary(), FormMethod.Post, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, string routeName, object routeValues) {
+            return BeginRouteForm(htmlHelper, routeName, new RouteValueDictionary(routeValues), FormMethod.Post, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, string routeName, RouteValueDictionary routeValues) {
+            return BeginRouteForm(htmlHelper, routeName, routeValues, FormMethod.Post, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, string routeName, FormMethod method) {
+            return BeginRouteForm(htmlHelper, routeName, new RouteValueDictionary(), method, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, string routeName, object routeValues, FormMethod method) {
+            return BeginRouteForm(htmlHelper, routeName, new RouteValueDictionary(routeValues), method, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, string routeName, RouteValueDictionary routeValues, FormMethod method) {
+            return BeginRouteForm(htmlHelper, routeName, routeValues, method, new RouteValueDictionary());
+        }
+
+        public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, string routeName, FormMethod method, object htmlAttributes) {
+            return BeginRouteForm(htmlHelper, routeName, new RouteValueDictionary(), method, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, string routeName, FormMethod method, IDictionary<string, object> htmlAttributes) {
+            return BeginRouteForm(htmlHelper, routeName, new RouteValueDictionary(), method, htmlAttributes);
+        }
+
+        public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, string routeName, object routeValues, FormMethod method, object htmlAttributes) {
+            return BeginRouteForm(htmlHelper, routeName, new RouteValueDictionary(routeValues), method, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, string routeName, RouteValueDictionary routeValues, FormMethod method, IDictionary<string, object> htmlAttributes) {
+            string formAction = UrlHelper.GenerateUrl(routeName, null, null, routeValues, htmlHelper.RouteCollection, htmlHelper.ViewContext.RequestContext, false /* includeImplicitMvcValues */);
+            return FormHelper(htmlHelper, formAction, method, htmlAttributes);
+        }
+
+        public static void EndForm(this HtmlHelper htmlHelper) {
+            htmlHelper.ViewContext.Writer.Write("</form>");
+            htmlHelper.ViewContext.OutputClientValidation();
+        }
+
+        [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Because disposing the object would write to the response stream, you don't want to prematurely dispose of this object.")]
+        private static MvcForm FormHelper(this HtmlHelper htmlHelper, string formAction, FormMethod method, IDictionary<string, object> htmlAttributes) {
+            TagBuilder tagBuilder = new TagBuilder("form");
+            tagBuilder.MergeAttributes(htmlAttributes);
+            // action is implicitly generated, so htmlAttributes take precedence.
+            tagBuilder.MergeAttribute("action", formAction);
+            // method is an explicit parameter, so it takes precedence over the htmlAttributes.
+            tagBuilder.MergeAttribute("method", HtmlHelper.GetFormMethodString(method), true);
+
+            bool traditionalJavascriptEnabled = htmlHelper.ViewContext.ClientValidationEnabled
+                                            && !htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled;
+
+            if (traditionalJavascriptEnabled) {
+                // forms must have an ID for client validation
+                tagBuilder.GenerateId(htmlHelper.ViewContext.FormIdGenerator());
+            }
+
+            htmlHelper.ViewContext.Writer.Write(tagBuilder.ToString(TagRenderMode.StartTag));
+            MvcForm theForm = new MvcForm(htmlHelper.ViewContext);
+
+            if (traditionalJavascriptEnabled) {
+                htmlHelper.ViewContext.FormContext.FormId = tagBuilder.Attributes["id"];
+            }
+
+            return theForm;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Html/InputExtensions.cs b/mcs/class/System.Web.Mvc3/Mvc/Html/InputExtensions.cs
new file mode 100644 (file)
index 0000000..7c7aa6b
--- /dev/null
@@ -0,0 +1,396 @@
+namespace System.Web.Mvc.Html {
+    using System;
+    using System.Collections.Generic;
+    using System.Data.Linq;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Linq.Expressions;
+    using System.Text;
+    using System.Web.Mvc.Resources;
+    using System.Web.Routing;
+
+    public static class InputExtensions {
+        // CheckBox
+
+        public static MvcHtmlString CheckBox(this HtmlHelper htmlHelper, string name) {
+            return CheckBox(htmlHelper, name, (object)null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString CheckBox(this HtmlHelper htmlHelper, string name, bool isChecked) {
+            return CheckBox(htmlHelper, name, isChecked, (object)null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString CheckBox(this HtmlHelper htmlHelper, string name, bool isChecked, object htmlAttributes) {
+            return CheckBox(htmlHelper, name, isChecked, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        public static MvcHtmlString CheckBox(this HtmlHelper htmlHelper, string name, object htmlAttributes) {
+            return CheckBox(htmlHelper, name, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        public static MvcHtmlString CheckBox(this HtmlHelper htmlHelper, string name, IDictionary<string, object> htmlAttributes) {
+            return CheckBoxHelper(htmlHelper, null, name, null /* isChecked */, htmlAttributes);
+        }
+
+        public static MvcHtmlString CheckBox(this HtmlHelper htmlHelper, string name, bool isChecked, IDictionary<string, object> htmlAttributes) {
+            return CheckBoxHelper(htmlHelper, null, name, isChecked, htmlAttributes);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString CheckBoxFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, bool>> expression) {
+            return CheckBoxFor(htmlHelper, expression, null /* htmlAttributes */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString CheckBoxFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, bool>> expression, object htmlAttributes) {
+            return CheckBoxFor(htmlHelper, expression, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString CheckBoxFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, bool>> expression, IDictionary<string, object> htmlAttributes) {
+            if (expression == null) {
+                throw new ArgumentNullException("expression");
+            }
+
+            ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
+            bool? isChecked = null;
+            if (metadata.Model != null) {
+                bool modelChecked;
+                if (Boolean.TryParse(metadata.Model.ToString(), out modelChecked)) {
+                    isChecked = modelChecked;
+                }
+            }
+
+            return CheckBoxHelper(htmlHelper, metadata, ExpressionHelper.GetExpressionText(expression), isChecked, htmlAttributes);
+        }
+
+        private static MvcHtmlString CheckBoxHelper(HtmlHelper htmlHelper, ModelMetadata metadata, string name, bool? isChecked, IDictionary<string, object> htmlAttributes) {
+            RouteValueDictionary attributes = ToRouteValueDictionary(htmlAttributes);
+
+            bool explicitValue = isChecked.HasValue;
+            if (explicitValue) {
+                attributes.Remove("checked");    // Explicit value must override dictionary
+            }
+
+            return InputHelper(htmlHelper, InputType.CheckBox, metadata, name, "true", !explicitValue /* useViewData */, isChecked ?? false, true /* setId */, false /* isExplicitValue */, attributes);
+        }
+
+        // Hidden
+
+        public static MvcHtmlString Hidden(this HtmlHelper htmlHelper, string name) {
+            return Hidden(htmlHelper, name, null /* value */, null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString Hidden(this HtmlHelper htmlHelper, string name, object value) {
+            return Hidden(htmlHelper, name, value, null /* hmtlAttributes */);
+        }
+
+        public static MvcHtmlString Hidden(this HtmlHelper htmlHelper, string name, object value, object htmlAttributes) {
+            return Hidden(htmlHelper, name, value, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        public static MvcHtmlString Hidden(this HtmlHelper htmlHelper, string name, object value, IDictionary<string, object> htmlAttributes) {
+            return HiddenHelper(htmlHelper,
+                                null,
+                                value,
+                                value == null /* useViewData */,
+                                name,
+                                htmlAttributes);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString HiddenFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) {
+            return HiddenFor(htmlHelper, expression, (IDictionary<string, object>)null);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString HiddenFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes) {
+            return HiddenFor(htmlHelper, expression, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString HiddenFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes) {
+            ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
+            return HiddenHelper(htmlHelper,
+                                metadata,
+                                metadata.Model,
+                                false,
+                                ExpressionHelper.GetExpressionText(expression),
+                                htmlAttributes);
+        }
+
+        private static MvcHtmlString HiddenHelper(HtmlHelper htmlHelper, ModelMetadata metadata, object value, bool useViewData, string expression, IDictionary<string, object> htmlAttributes) {
+            Binary binaryValue = value as Binary;
+            if (binaryValue != null) {
+                value = binaryValue.ToArray();
+            }
+
+            byte[] byteArrayValue = value as byte[];
+            if (byteArrayValue != null) {
+                value = Convert.ToBase64String(byteArrayValue);
+            }
+
+            return InputHelper(htmlHelper, InputType.Hidden, metadata, expression, value, useViewData, false /* isChecked */, true /* setId */, true /* isExplicitValue */, htmlAttributes);
+        }
+
+        // Password
+
+        public static MvcHtmlString Password(this HtmlHelper htmlHelper, string name) {
+            return Password(htmlHelper, name, null /* value */);
+        }
+
+        public static MvcHtmlString Password(this HtmlHelper htmlHelper, string name, object value) {
+            return Password(htmlHelper, name, value, null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString Password(this HtmlHelper htmlHelper, string name, object value, object htmlAttributes) {
+            return Password(htmlHelper, name, value, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        public static MvcHtmlString Password(this HtmlHelper htmlHelper, string name, object value, IDictionary<string, object> htmlAttributes) {
+            return PasswordHelper(htmlHelper, null /* metadata */, name, value, htmlAttributes);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString PasswordFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) {
+            return PasswordFor(htmlHelper, expression, null /* htmlAttributes */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString PasswordFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes) {
+            return PasswordFor(htmlHelper, expression, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Users cannot use anonymous methods with the LambdaExpression type")]
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString PasswordFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes) {
+            if (expression == null) {
+                throw new ArgumentNullException("expression");
+            }
+
+            return PasswordHelper(htmlHelper,
+                                  ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData),
+                                  ExpressionHelper.GetExpressionText(expression),
+                                  null /* value */,
+                                  htmlAttributes);
+        }
+
+        private static MvcHtmlString PasswordHelper(HtmlHelper htmlHelper, ModelMetadata metadata, string name, object value, IDictionary<string, object> htmlAttributes) {
+            return InputHelper(htmlHelper, InputType.Password, metadata, name, value, false /* useViewData */, false /* isChecked */, true /* setId */, true /* isExplicitValue */, htmlAttributes);
+        }
+
+        // RadioButton
+
+        public static MvcHtmlString RadioButton(this HtmlHelper htmlHelper, string name, object value) {
+            return RadioButton(htmlHelper, name, value, (object)null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString RadioButton(this HtmlHelper htmlHelper, string name, object value, object htmlAttributes) {
+            return RadioButton(htmlHelper, name, value, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        public static MvcHtmlString RadioButton(this HtmlHelper htmlHelper, string name, object value, IDictionary<string, object> htmlAttributes) {
+            // Determine whether or not to render the checked attribute based on the contents of ViewData.
+            string valueString = Convert.ToString(value, CultureInfo.CurrentCulture);
+            bool isChecked = (!String.IsNullOrEmpty(name)) && (String.Equals(htmlHelper.EvalString(name), valueString, StringComparison.OrdinalIgnoreCase));
+            // checked attributes is implicit, so we need to ensure that the dictionary takes precedence.
+            RouteValueDictionary attributes = ToRouteValueDictionary(htmlAttributes);
+            if (attributes.ContainsKey("checked")) {
+                return InputHelper(htmlHelper, InputType.Radio, null, name, value, false, false, true, true /* isExplicitValue */, attributes);
+            }
+
+            return RadioButton(htmlHelper, name, value, isChecked, htmlAttributes);
+        }
+
+        public static MvcHtmlString RadioButton(this HtmlHelper htmlHelper, string name, object value, bool isChecked) {
+            return RadioButton(htmlHelper, name, value, isChecked, (object)null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString RadioButton(this HtmlHelper htmlHelper, string name, object value, bool isChecked, object htmlAttributes) {
+            return RadioButton(htmlHelper, name, value, isChecked, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        public static MvcHtmlString RadioButton(this HtmlHelper htmlHelper, string name, object value, bool isChecked, IDictionary<string, object> htmlAttributes) {
+            if (value == null) {
+                throw new ArgumentNullException("value");
+            }
+            // checked attribute is an explicit parameter so it takes precedence.
+            RouteValueDictionary attributes = ToRouteValueDictionary(htmlAttributes);
+            attributes.Remove("checked");
+            return InputHelper(htmlHelper, InputType.Radio, null, name, value, false, isChecked, true, true /* isExplicitValue */, attributes);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString RadioButtonFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object value) {
+            return RadioButtonFor(htmlHelper, expression, value, null /* htmlAttributes */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString RadioButtonFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object value, object htmlAttributes) {
+            return RadioButtonFor(htmlHelper, expression, value, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString RadioButtonFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object value, IDictionary<string, object> htmlAttributes) {
+            ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
+            return RadioButtonHelper(htmlHelper,
+                                     metadata,
+                                     metadata.Model,
+                                     ExpressionHelper.GetExpressionText(expression),
+                                     value,
+                                     null /* isChecked */,
+                                     htmlAttributes);
+        }
+
+        private static MvcHtmlString RadioButtonHelper(HtmlHelper htmlHelper, ModelMetadata metadata, object model, string name, object value, bool? isChecked, IDictionary<string, object> htmlAttributes) {
+            if (value == null) {
+                throw new ArgumentNullException("value");
+            }
+
+            RouteValueDictionary attributes = ToRouteValueDictionary(htmlAttributes);
+
+            bool explicitValue = isChecked.HasValue;
+            if (explicitValue) {
+                attributes.Remove("checked");    // Explicit value must override dictionary
+            }
+            else {
+                string valueString = Convert.ToString(value, CultureInfo.CurrentCulture);
+                isChecked = model != null &&
+                            !String.IsNullOrEmpty(name) &&
+                            String.Equals(model.ToString(), valueString, StringComparison.OrdinalIgnoreCase);
+            }
+
+            return InputHelper(htmlHelper, InputType.Radio, metadata, name, value, false /* useViewData */, isChecked ?? false, true /* setId */, true /* isExplicitValue */, attributes);
+        }
+
+        // TextBox
+
+        public static MvcHtmlString TextBox(this HtmlHelper htmlHelper, string name) {
+            return TextBox(htmlHelper, name, null /* value */);
+        }
+
+        public static MvcHtmlString TextBox(this HtmlHelper htmlHelper, string name, object value) {
+            return TextBox(htmlHelper, name, value, (object)null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString TextBox(this HtmlHelper htmlHelper, string name, object value, object htmlAttributes) {
+            return TextBox(htmlHelper, name, value, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        public static MvcHtmlString TextBox(this HtmlHelper htmlHelper, string name, object value, IDictionary<string, object> htmlAttributes) {
+            return InputHelper(htmlHelper, InputType.Text, null, name, value, (value == null) /* useViewData */, false /* isChecked */, true /* setId */, true /* isExplicitValue */, htmlAttributes);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString TextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) {
+            return htmlHelper.TextBoxFor(expression, (IDictionary<string, object>)null);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString TextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes) {
+            return htmlHelper.TextBoxFor(expression, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString TextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes) {
+            ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
+            return TextBoxHelper(htmlHelper,
+                                 metadata,
+                                 metadata.Model,
+                                 ExpressionHelper.GetExpressionText(expression),
+                                 htmlAttributes);
+        }
+
+        private static MvcHtmlString TextBoxHelper(this HtmlHelper htmlHelper, ModelMetadata metadata, object model, string expression, IDictionary<string, object> htmlAttributes) {
+            return InputHelper(htmlHelper, InputType.Text, metadata, expression, model, false /* useViewData */, false /* isChecked */, true /* setId */, true /* isExplicitValue */, htmlAttributes);
+        }
+
+        // Helper methods
+
+        private static MvcHtmlString InputHelper(HtmlHelper htmlHelper, InputType inputType, ModelMetadata metadata, string name, object value, bool useViewData, bool isChecked, bool setId, bool isExplicitValue, IDictionary<string, object> htmlAttributes) {
+            string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
+            if (String.IsNullOrEmpty(fullName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "name");
+            }
+
+            TagBuilder tagBuilder = new TagBuilder("input");
+            tagBuilder.MergeAttributes(htmlAttributes);
+            tagBuilder.MergeAttribute("type", HtmlHelper.GetInputTypeString(inputType));
+            tagBuilder.MergeAttribute("name", fullName, true);
+
+            string valueParameter = Convert.ToString(value, CultureInfo.CurrentCulture);
+            bool usedModelState = false;
+
+            switch (inputType) {
+                case InputType.CheckBox:
+                    bool? modelStateWasChecked = htmlHelper.GetModelStateValue(fullName, typeof(bool)) as bool?;
+                    if (modelStateWasChecked.HasValue) {
+                        isChecked = modelStateWasChecked.Value;
+                        usedModelState = true;
+                    }
+                    goto case InputType.Radio;
+                case InputType.Radio:
+                    if (!usedModelState) {
+                        string modelStateValue = htmlHelper.GetModelStateValue(fullName, typeof(string)) as string;
+                        if (modelStateValue != null) {
+                            isChecked = String.Equals(modelStateValue, valueParameter, StringComparison.Ordinal);
+                            usedModelState = true;
+                        }
+                    }
+                    if (!usedModelState && useViewData) {
+                        isChecked = htmlHelper.EvalBoolean(fullName);
+                    }
+                    if (isChecked) {
+                        tagBuilder.MergeAttribute("checked", "checked");
+                    }
+                    tagBuilder.MergeAttribute("value", valueParameter, isExplicitValue);
+                    break;
+                case InputType.Password:
+                    if (value != null) {
+                        tagBuilder.MergeAttribute("value", valueParameter, isExplicitValue);
+                    }
+                    break;
+                default:
+                    string attemptedValue = (string)htmlHelper.GetModelStateValue(fullName, typeof(string));
+                    tagBuilder.MergeAttribute("value", attemptedValue ?? ((useViewData) ? htmlHelper.EvalString(fullName) : valueParameter), isExplicitValue);
+                    break;
+            }
+
+            if (setId) {
+                tagBuilder.GenerateId(fullName);
+            }
+
+            // If there are any errors for a named field, we add the css attribute.
+            ModelState modelState;
+            if (htmlHelper.ViewData.ModelState.TryGetValue(fullName, out modelState)) {
+                if (modelState.Errors.Count > 0) {
+                    tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName);
+                }
+            }
+
+            tagBuilder.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(name, metadata));
+
+            if (inputType == InputType.CheckBox) {
+                // Render an additional <input type="hidden".../> for checkboxes. This
+                // addresses scenarios where unchecked checkboxes are not sent in the request.
+                // Sending a hidden input makes it possible to know that the checkbox was present
+                // on the page when the request was submitted.
+                StringBuilder inputItemBuilder = new StringBuilder();
+                inputItemBuilder.Append(tagBuilder.ToString(TagRenderMode.SelfClosing));
+
+                TagBuilder hiddenInput = new TagBuilder("input");
+                hiddenInput.MergeAttribute("type", HtmlHelper.GetInputTypeString(InputType.Hidden));
+                hiddenInput.MergeAttribute("name", fullName);
+                hiddenInput.MergeAttribute("value", "false");
+                inputItemBuilder.Append(hiddenInput.ToString(TagRenderMode.SelfClosing));
+                return MvcHtmlString.Create(inputItemBuilder.ToString());
+            }
+
+            return tagBuilder.ToMvcHtmlString(TagRenderMode.SelfClosing);
+        }
+
+        private static RouteValueDictionary ToRouteValueDictionary(IDictionary<string, object> dictionary) {
+            return dictionary == null ? new RouteValueDictionary() : new RouteValueDictionary(dictionary);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Html/LabelExtensions.cs b/mcs/class/System.Web.Mvc3/Mvc/Html/LabelExtensions.cs
new file mode 100644 (file)
index 0000000..95dc3c5
--- /dev/null
@@ -0,0 +1,54 @@
+namespace System.Web.Mvc.Html {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq;
+    using System.Linq.Expressions;
+
+    public static class LabelExtensions {
+        public static MvcHtmlString Label(this HtmlHelper html, string expression) {
+            return Label(html,
+                         expression,
+                         null);
+        }
+
+        public static MvcHtmlString Label(this HtmlHelper html, string expression, string labelText) {
+            return LabelHelper(html,
+                               ModelMetadata.FromStringExpression(expression, html.ViewData),
+                               expression,
+                               labelText);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression) {
+            return LabelFor<TModel, TValue>(html, expression, null);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, string labelText) {
+            return LabelHelper(html,
+                               ModelMetadata.FromLambdaExpression(expression, html.ViewData),
+                               ExpressionHelper.GetExpressionText(expression),
+                               labelText);
+        }
+
+        public static MvcHtmlString LabelForModel(this HtmlHelper html) {
+            return LabelForModel(html, null);
+        }
+
+        public static MvcHtmlString LabelForModel(this HtmlHelper html, string labelText) {
+            return LabelHelper(html, html.ViewData.ModelMetadata, String.Empty, labelText);
+        }
+
+        internal static MvcHtmlString LabelHelper(HtmlHelper html, ModelMetadata metadata, string htmlFieldName, string labelText = null) {
+            string resolvedLabelText = labelText ?? metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last();
+            if (String.IsNullOrEmpty(resolvedLabelText)) {
+                return MvcHtmlString.Empty;
+            }
+
+            TagBuilder tag = new TagBuilder("label");
+            tag.Attributes.Add("for", TagBuilder.CreateSanitizedId(html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(htmlFieldName)));
+            tag.SetInnerText(resolvedLabelText);
+            return tag.ToMvcHtmlString(TagRenderMode.Normal);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Html/LinkExtensions.cs b/mcs/class/System.Web.Mvc3/Mvc/Html/LinkExtensions.cs
new file mode 100644 (file)
index 0000000..42bfb00
--- /dev/null
@@ -0,0 +1,104 @@
+namespace System.Web.Mvc.Html {
+    using System;
+    using System.Collections.Generic;
+    using System.Web.Mvc.Resources;
+    using System.Web.Routing;
+
+    public static class LinkExtensions {
+        public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName) {
+            return ActionLink(htmlHelper, linkText, actionName, null /* controllerName */, new RouteValueDictionary(), new RouteValueDictionary());
+        }
+
+        public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, object routeValues) {
+            return ActionLink(htmlHelper, linkText, actionName, null /* controllerName */, new RouteValueDictionary(routeValues), new RouteValueDictionary());
+        }
+
+        public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, object routeValues, object htmlAttributes) {
+            return ActionLink(htmlHelper, linkText, actionName, null /* controllerName */, new RouteValueDictionary(routeValues), HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, RouteValueDictionary routeValues) {
+            return ActionLink(htmlHelper, linkText, actionName, null /* controllerName */, routeValues, new RouteValueDictionary());
+        }
+
+        public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes) {
+            return ActionLink(htmlHelper, linkText, actionName, null /* controllerName */, routeValues, htmlAttributes);
+        }
+
+        public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName) {
+            return ActionLink(htmlHelper, linkText, actionName, controllerName, new RouteValueDictionary(), new RouteValueDictionary());
+        }
+
+        public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, object routeValues, object htmlAttributes) {
+            return ActionLink(htmlHelper, linkText, actionName, controllerName, new RouteValueDictionary(routeValues), HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes) {
+            if (String.IsNullOrEmpty(linkText)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText");
+            }
+            return MvcHtmlString.Create(HtmlHelper.GenerateLink(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection, linkText, null/* routeName */, actionName, controllerName, routeValues, htmlAttributes));
+        }
+
+        public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, string protocol, string hostName, string fragment, object routeValues, object htmlAttributes) {
+            return ActionLink(htmlHelper, linkText, actionName, controllerName, protocol, hostName, fragment, new RouteValueDictionary(routeValues), HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, string protocol, string hostName, string fragment, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes) {
+            if (String.IsNullOrEmpty(linkText)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText");
+            }
+            return MvcHtmlString.Create(HtmlHelper.GenerateLink(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection, linkText, null /* routeName */, actionName, controllerName, protocol, hostName, fragment, routeValues, htmlAttributes));
+        }
+
+        public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, object routeValues) {
+            return RouteLink(htmlHelper, linkText, new RouteValueDictionary(routeValues));
+        }
+
+        public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, RouteValueDictionary routeValues) {
+            return RouteLink(htmlHelper, linkText, routeValues, new RouteValueDictionary());
+        }
+
+        public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, string routeName) {
+            return RouteLink(htmlHelper, linkText, routeName, (object)null /* routeValues */ );
+        }
+
+        public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, string routeName, object routeValues) {
+            return RouteLink(htmlHelper, linkText, routeName, new RouteValueDictionary(routeValues));
+        }
+
+        public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, string routeName, RouteValueDictionary routeValues) {
+            return RouteLink(htmlHelper, linkText, routeName, routeValues, new RouteValueDictionary());
+        }
+
+        public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, object routeValues, object htmlAttributes) {
+            return RouteLink(htmlHelper, linkText, new RouteValueDictionary(routeValues), HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes) {
+            return RouteLink(htmlHelper, linkText, null /* routeName */, routeValues, htmlAttributes);
+        }
+
+        public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, string routeName, object routeValues, object htmlAttributes) {
+            return RouteLink(htmlHelper, linkText, routeName, new RouteValueDictionary(routeValues), HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, string routeName, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes) {
+            if (String.IsNullOrEmpty(linkText)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText");
+            }
+            return MvcHtmlString.Create(HtmlHelper.GenerateRouteLink(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection, linkText, routeName, routeValues, htmlAttributes));
+        }
+
+        public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, string routeName, string protocol, string hostName, string fragment, object routeValues, object htmlAttributes) {
+            return RouteLink(htmlHelper, linkText, routeName, protocol, hostName, fragment, new RouteValueDictionary(routeValues), HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, string routeName, string protocol, string hostName, string fragment, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes) {
+            if (String.IsNullOrEmpty(linkText)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText");
+            }
+            return MvcHtmlString.Create(HtmlHelper.GenerateRouteLink(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection, linkText, routeName, protocol, hostName, fragment, routeValues, htmlAttributes));
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Html/MvcForm.cs b/mcs/class/System.Web.Mvc3/Mvc/Html/MvcForm.cs
new file mode 100644 (file)
index 0000000..0059904
--- /dev/null
@@ -0,0 +1,57 @@
+namespace System.Web.Mvc.Html {
+    using System;
+    using System.IO;
+
+    public class MvcForm : IDisposable {
+
+        private bool _disposed;
+        private readonly FormContext _originalFormContext;
+        private readonly ViewContext _viewContext;
+        private readonly TextWriter _writer;
+
+        [Obsolete("The recommended alternative is the constructor MvcForm(ViewContext viewContext).", true /* error */)]
+        public MvcForm(HttpResponseBase httpResponse) {
+            if (httpResponse == null) {
+                throw new ArgumentNullException("httpResponse");
+            }
+
+            _writer = httpResponse.Output;
+        }
+
+        public MvcForm(ViewContext viewContext) {
+            if (viewContext == null) {
+                throw new ArgumentNullException("viewContext");
+            }
+
+            _viewContext = viewContext;
+            _writer = viewContext.Writer;
+
+            // push the new FormContext
+            _originalFormContext = viewContext.FormContext;
+            viewContext.FormContext = new FormContext();
+        }
+
+        public void Dispose() {
+            Dispose(true /* disposing */);
+            GC.SuppressFinalize(this);
+        }
+
+        protected virtual void Dispose(bool disposing) {
+            if (!_disposed) {
+                _disposed = true;
+                _writer.Write("</form>");
+
+                // output client validation and restore the original form context
+                if (_viewContext != null) {
+                    _viewContext.OutputClientValidation();
+                    _viewContext.FormContext = _originalFormContext;
+                }
+            }
+        }
+
+        public void EndForm() {
+            Dispose(true);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Html/PartialExtensions.cs b/mcs/class/System.Web.Mvc3/Mvc/Html/PartialExtensions.cs
new file mode 100644 (file)
index 0000000..36d5d5a
--- /dev/null
@@ -0,0 +1,25 @@
+namespace System.Web.Mvc.Html {
+    using System.Globalization;
+    using System.IO;
+
+    public static class PartialExtensions {
+        public static MvcHtmlString Partial(this HtmlHelper htmlHelper, string partialViewName) {
+            return Partial(htmlHelper, partialViewName, null /* model */, htmlHelper.ViewData);
+        }
+
+        public static MvcHtmlString Partial(this HtmlHelper htmlHelper, string partialViewName, ViewDataDictionary viewData) {
+            return Partial(htmlHelper, partialViewName, null /* model */, viewData);
+        }
+
+        public static MvcHtmlString Partial(this HtmlHelper htmlHelper, string partialViewName, object model) {
+            return Partial(htmlHelper, partialViewName, model, htmlHelper.ViewData);
+        }
+
+        public static MvcHtmlString Partial(this HtmlHelper htmlHelper, string partialViewName, object model, ViewDataDictionary viewData) {
+            using (StringWriter writer = new StringWriter(CultureInfo.CurrentCulture)) {
+                htmlHelper.RenderPartialInternal(partialViewName, viewData, model, writer, ViewEngines.Engines);
+                return MvcHtmlString.Create(writer.ToString());
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Html/RenderPartialExtensions.cs b/mcs/class/System.Web.Mvc3/Mvc/Html/RenderPartialExtensions.cs
new file mode 100644 (file)
index 0000000..e0149f8
--- /dev/null
@@ -0,0 +1,23 @@
+namespace System.Web.Mvc.Html {
+    public static class RenderPartialExtensions {
+        // Renders the partial view with the parent's view data and model
+        public static void RenderPartial(this HtmlHelper htmlHelper, string partialViewName) {
+            htmlHelper.RenderPartialInternal(partialViewName, htmlHelper.ViewData, null /* model */, htmlHelper.ViewContext.Writer, ViewEngines.Engines);
+        }
+
+        // Renders the partial view with the given view data and, implicitly, the given view data's model
+        public static void RenderPartial(this HtmlHelper htmlHelper, string partialViewName, ViewDataDictionary viewData) {
+            htmlHelper.RenderPartialInternal(partialViewName, viewData, null /* model */, htmlHelper.ViewContext.Writer, ViewEngines.Engines);
+        }
+
+        // Renders the partial view with an empty view data and the given model
+        public static void RenderPartial(this HtmlHelper htmlHelper, string partialViewName, object model) {
+            htmlHelper.RenderPartialInternal(partialViewName, htmlHelper.ViewData, model, htmlHelper.ViewContext.Writer, ViewEngines.Engines);
+        }
+
+        // Renders the partial view with a copy of the given view data plus the given model
+        public static void RenderPartial(this HtmlHelper htmlHelper, string partialViewName, object model, ViewDataDictionary viewData) {
+            htmlHelper.RenderPartialInternal(partialViewName, viewData, model, htmlHelper.ViewContext.Writer, ViewEngines.Engines);
+        }
+    }
+}
\ No newline at end of file
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Html/SelectExtensions.cs b/mcs/class/System.Web.Mvc3/Mvc/Html/SelectExtensions.cs
new file mode 100644 (file)
index 0000000..0b460bb
--- /dev/null
@@ -0,0 +1,245 @@
+namespace System.Web.Mvc.Html {
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Linq;
+    using System.Linq.Expressions;
+    using System.Text;
+    using System.Web;
+    using System.Web.Mvc.Resources;
+
+    public static class SelectExtensions {
+
+        // DropDownList
+
+        public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name) {
+            return DropDownList(htmlHelper, name, null /* selectList */, null /* optionLabel */, null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, string optionLabel) {
+            return DropDownList(htmlHelper, name, null /* selectList */, optionLabel, null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList) {
+            return DropDownList(htmlHelper, name, selectList, null /* optionLabel */, null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, object htmlAttributes) {
+            return DropDownList(htmlHelper, name, selectList, null /* optionLabel */, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, IDictionary<string, object> htmlAttributes) {
+            return DropDownList(htmlHelper, name, selectList, null /* optionLabel */, htmlAttributes);
+        }
+
+        public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, string optionLabel) {
+            return DropDownList(htmlHelper, name, selectList, optionLabel, null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, string optionLabel, object htmlAttributes) {
+            return DropDownList(htmlHelper, name, selectList, optionLabel, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, string optionLabel, IDictionary<string, object> htmlAttributes) {
+            return DropDownListHelper(htmlHelper, name, selectList, optionLabel, htmlAttributes);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList) {
+            return DropDownListFor(htmlHelper, expression, selectList, null /* optionLabel */, null /* htmlAttributes */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, object htmlAttributes) {
+            return DropDownListFor(htmlHelper, expression, selectList, null /* optionLabel */, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, IDictionary<string, object> htmlAttributes) {
+            return DropDownListFor(htmlHelper, expression, selectList, null /* optionLabel */, htmlAttributes);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, string optionLabel) {
+            return DropDownListFor(htmlHelper, expression, selectList, optionLabel, null /* htmlAttributes */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, string optionLabel, object htmlAttributes) {
+            return DropDownListFor(htmlHelper, expression, selectList, optionLabel, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Users cannot use anonymous methods with the LambdaExpression type")]
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, string optionLabel, IDictionary<string, object> htmlAttributes) {
+            if (expression == null) {
+                throw new ArgumentNullException("expression");
+            }
+
+            return DropDownListHelper(htmlHelper, ExpressionHelper.GetExpressionText(expression), selectList, optionLabel, htmlAttributes);
+        }
+
+        private static MvcHtmlString DropDownListHelper(HtmlHelper htmlHelper, string expression, IEnumerable<SelectListItem> selectList, string optionLabel, IDictionary<string, object> htmlAttributes) {
+            return SelectInternal(htmlHelper, optionLabel, expression, selectList, false /* allowMultiple */, htmlAttributes);
+        }
+
+        // ListBox
+
+        public static MvcHtmlString ListBox(this HtmlHelper htmlHelper, string name) {
+            return ListBox(htmlHelper, name, null /* selectList */, null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString ListBox(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList) {
+            return ListBox(htmlHelper, name, selectList, (IDictionary<string, object>)null);
+        }
+
+        public static MvcHtmlString ListBox(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, object htmlAttributes) {
+            return ListBox(htmlHelper, name, selectList, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        public static MvcHtmlString ListBox(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, IDictionary<string, object> htmlAttributes) {
+            return ListBoxHelper(htmlHelper, name, selectList, htmlAttributes);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString ListBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList) {
+            return ListBoxFor(htmlHelper, expression, selectList, null /* htmlAttributes */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString ListBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, object htmlAttributes) {
+            return ListBoxFor(htmlHelper, expression, selectList, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Users cannot use anonymous methods with the LambdaExpression type")]
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString ListBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, IDictionary<string, object> htmlAttributes) {
+            if (expression == null) {
+                throw new ArgumentNullException("expression");
+            }
+
+            return ListBoxHelper(htmlHelper,
+                                 ExpressionHelper.GetExpressionText(expression),
+                                 selectList,
+                                 htmlAttributes);
+        }
+
+        private static MvcHtmlString ListBoxHelper(HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, IDictionary<string, object> htmlAttributes) {
+            return SelectInternal(htmlHelper, null /* optionLabel */, name, selectList, true /* allowMultiple */, htmlAttributes);
+        }
+
+        // Helper methods
+
+        private static IEnumerable<SelectListItem> GetSelectData(this HtmlHelper htmlHelper, string name) {
+            object o = null;
+            if (htmlHelper.ViewData != null) {
+                o = htmlHelper.ViewData.Eval(name);
+            }
+            if (o == null) {
+                throw new InvalidOperationException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.HtmlHelper_MissingSelectData,
+                        name,
+                        "IEnumerable<SelectListItem>"));
+            }
+            IEnumerable<SelectListItem> selectList = o as IEnumerable<SelectListItem>;
+            if (selectList == null) {
+                throw new InvalidOperationException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.HtmlHelper_WrongSelectDataType,
+                        name,
+                        o.GetType().FullName,
+                        "IEnumerable<SelectListItem>"));
+            }
+            return selectList;
+        }
+
+        internal static string ListItemToOption(SelectListItem item) {
+            TagBuilder builder = new TagBuilder("option") {
+                InnerHtml = HttpUtility.HtmlEncode(item.Text)
+            };
+            if (item.Value != null) {
+                builder.Attributes["value"] = item.Value;
+            }
+            if (item.Selected) {
+                builder.Attributes["selected"] = "selected";
+            }
+            return builder.ToString(TagRenderMode.Normal);
+        }
+
+        private static MvcHtmlString SelectInternal(this HtmlHelper htmlHelper, string optionLabel, string name, IEnumerable<SelectListItem> selectList, bool allowMultiple, IDictionary<string, object> htmlAttributes) {
+            string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
+            if (String.IsNullOrEmpty(fullName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "name");
+            }
+
+            bool usedViewData = false;
+
+            // If we got a null selectList, try to use ViewData to get the list of items.
+            if (selectList == null) {
+                selectList = htmlHelper.GetSelectData(fullName);
+                usedViewData = true;
+            }
+
+            object defaultValue = (allowMultiple) ? htmlHelper.GetModelStateValue(fullName, typeof(string[])) : htmlHelper.GetModelStateValue(fullName, typeof(string));
+
+            // If we haven't already used ViewData to get the entire list of items then we need to
+            // use the ViewData-supplied value before using the parameter-supplied value.
+            if (!usedViewData) {
+                if (defaultValue == null) {
+                    defaultValue = htmlHelper.ViewData.Eval(fullName);
+                }
+            }
+
+            if (defaultValue != null) {
+                IEnumerable defaultValues = (allowMultiple) ? defaultValue as IEnumerable : new[] { defaultValue };
+                IEnumerable<string> values = from object value in defaultValues select Convert.ToString(value, CultureInfo.CurrentCulture);
+                HashSet<string> selectedValues = new HashSet<string>(values, StringComparer.OrdinalIgnoreCase);
+                List<SelectListItem> newSelectList = new List<SelectListItem>();
+
+                foreach (SelectListItem item in selectList) {
+                    item.Selected = (item.Value != null) ? selectedValues.Contains(item.Value) : selectedValues.Contains(item.Text);
+                    newSelectList.Add(item);
+                }
+                selectList = newSelectList;
+            }
+
+            // Convert each ListItem to an <option> tag
+            StringBuilder listItemBuilder = new StringBuilder();
+
+            // Make optionLabel the first item that gets rendered.
+            if (optionLabel != null) {
+                listItemBuilder.AppendLine(ListItemToOption(new SelectListItem() { Text = optionLabel, Value = String.Empty, Selected = false }));
+            }
+
+            foreach (SelectListItem item in selectList) {
+                listItemBuilder.AppendLine(ListItemToOption(item));
+            }
+
+            TagBuilder tagBuilder = new TagBuilder("select") {
+                InnerHtml = listItemBuilder.ToString()
+            };
+            tagBuilder.MergeAttributes(htmlAttributes);
+            tagBuilder.MergeAttribute("name", fullName, true /* replaceExisting */);
+            tagBuilder.GenerateId(fullName);
+            if (allowMultiple) {
+                tagBuilder.MergeAttribute("multiple", "multiple");
+            }
+
+            // If there are any errors for a named field, we add the css attribute.
+            ModelState modelState;
+            if (htmlHelper.ViewData.ModelState.TryGetValue(fullName, out modelState)) {
+                if (modelState.Errors.Count > 0) {
+                    tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName);
+                }
+            }
+
+            tagBuilder.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(name));
+
+            return tagBuilder.ToMvcHtmlString(TagRenderMode.Normal);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Html/TemplateHelpers.cs b/mcs/class/System.Web.Mvc3/Mvc/Html/TemplateHelpers.cs
new file mode 100644 (file)
index 0000000..0ae3379
--- /dev/null
@@ -0,0 +1,283 @@
+namespace System.Web.Mvc.Html {
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Globalization;
+    using System.IO;
+    using System.Linq;
+    using System.Linq.Expressions;
+    using System.Web.Mvc.Resources;
+    using System.Web.Routing;
+    using System.Web.UI.WebControls;
+
+    internal static class TemplateHelpers {
+        static readonly Dictionary<DataBoundControlMode, string> modeViewPaths =
+            new Dictionary<DataBoundControlMode, string> {
+                { DataBoundControlMode.ReadOnly, "DisplayTemplates" },
+                { DataBoundControlMode.Edit,     "EditorTemplates" }
+            };
+
+        static readonly Dictionary<string, Func<HtmlHelper, string>> defaultDisplayActions =
+            new Dictionary<string, Func<HtmlHelper, string>>(StringComparer.OrdinalIgnoreCase) {
+                { "EmailAddress",       DefaultDisplayTemplates.EmailAddressTemplate },
+                { "HiddenInput",        DefaultDisplayTemplates.HiddenInputTemplate },
+                { "Html",               DefaultDisplayTemplates.HtmlTemplate },
+                { "Text",               DefaultDisplayTemplates.StringTemplate },
+                { "Url",                DefaultDisplayTemplates.UrlTemplate },
+                { "Collection",         DefaultDisplayTemplates.CollectionTemplate },
+                { typeof(bool).Name,    DefaultDisplayTemplates.BooleanTemplate },
+                { typeof(decimal).Name, DefaultDisplayTemplates.DecimalTemplate },
+                { typeof(string).Name,  DefaultDisplayTemplates.StringTemplate },
+                { typeof(object).Name,  DefaultDisplayTemplates.ObjectTemplate },
+            };
+
+        static readonly Dictionary<string, Func<HtmlHelper, string>> defaultEditorActions =
+            new Dictionary<string, Func<HtmlHelper, string>>(StringComparer.OrdinalIgnoreCase) {
+                { "HiddenInput",        DefaultEditorTemplates.HiddenInputTemplate },
+                { "MultilineText",      DefaultEditorTemplates.MultilineTextTemplate },
+                { "Password",           DefaultEditorTemplates.PasswordTemplate },
+                { "Text",               DefaultEditorTemplates.StringTemplate },
+                { "Collection",         DefaultEditorTemplates.CollectionTemplate },
+                { typeof(bool).Name,    DefaultEditorTemplates.BooleanTemplate },
+                { typeof(decimal).Name, DefaultEditorTemplates.DecimalTemplate },
+                { typeof(string).Name,  DefaultEditorTemplates.StringTemplate },
+                { typeof(object).Name,  DefaultEditorTemplates.ObjectTemplate },
+            };
+
+        internal static string cacheItemId = Guid.NewGuid().ToString();
+
+        internal delegate string ExecuteTemplateDelegate(HtmlHelper html, ViewDataDictionary viewData, string templateName, DataBoundControlMode mode, GetViewNamesDelegate getViewNames, GetDefaultActionsDelegate getDefaultActions);
+
+        internal static string ExecuteTemplate(HtmlHelper html, ViewDataDictionary viewData, string templateName, DataBoundControlMode mode, GetViewNamesDelegate getViewNames, GetDefaultActionsDelegate getDefaultActions) {
+            Dictionary<string, ActionCacheItem> actionCache = GetActionCache(html);
+            Dictionary<string, Func<HtmlHelper, string>> defaultActions = getDefaultActions(mode);
+            string modeViewPath = modeViewPaths[mode];
+
+            foreach (string viewName in getViewNames(viewData.ModelMetadata, templateName, viewData.ModelMetadata.TemplateHint, viewData.ModelMetadata.DataTypeName)) {
+                string fullViewName = modeViewPath + "/" + viewName;
+                ActionCacheItem cacheItem;
+
+                if (actionCache.TryGetValue(fullViewName, out cacheItem)) {
+                    if (cacheItem != null) {
+                        return cacheItem.Execute(html, viewData);
+                    }
+                }
+                else {
+                    ViewEngineResult viewEngineResult = ViewEngines.Engines.FindPartialView(html.ViewContext, fullViewName);
+                    if (viewEngineResult.View != null) {
+                        actionCache[fullViewName] = new ActionCacheViewItem { ViewName = fullViewName };
+
+                        using (StringWriter writer = new StringWriter(CultureInfo.InvariantCulture)) {
+                            viewEngineResult.View.Render(new ViewContext(html.ViewContext, viewEngineResult.View, viewData, html.ViewContext.TempData, writer), writer);
+                            return writer.ToString();
+                        }
+                    }
+
+                    Func<HtmlHelper, string> defaultAction;
+                    if (defaultActions.TryGetValue(viewName, out defaultAction)) {
+                        actionCache[fullViewName] = new ActionCacheCodeItem { Action = defaultAction };
+                        return defaultAction(MakeHtmlHelper(html, viewData));
+                    }
+
+                    actionCache[fullViewName] = null;
+                }
+            }
+
+            throw new InvalidOperationException(
+                String.Format(
+                    CultureInfo.CurrentCulture,
+                    MvcResources.TemplateHelpers_NoTemplate,
+                    viewData.ModelMetadata.RealModelType.FullName
+                )
+            );
+        }
+
+        internal static Dictionary<string, ActionCacheItem> GetActionCache(HtmlHelper html) {
+            HttpContextBase context = html.ViewContext.HttpContext;
+            Dictionary<string, ActionCacheItem> result;
+
+            if (!context.Items.Contains(cacheItemId)) {
+                result = new Dictionary<string, ActionCacheItem>();
+                context.Items[cacheItemId] = result;
+            }
+            else {
+                result = (Dictionary<string, ActionCacheItem>)context.Items[cacheItemId];
+            }
+
+            return result;
+        }
+
+        internal delegate Dictionary<string, Func<HtmlHelper, string>> GetDefaultActionsDelegate(DataBoundControlMode mode);
+
+        internal static Dictionary<string, Func<HtmlHelper, string>> GetDefaultActions(DataBoundControlMode mode) {
+            return mode == DataBoundControlMode.ReadOnly ? defaultDisplayActions : defaultEditorActions;
+        }
+
+        internal delegate IEnumerable<string> GetViewNamesDelegate(ModelMetadata metadata, params string[] templateHints);
+
+        internal static IEnumerable<string> GetViewNames(ModelMetadata metadata, params string[] templateHints) {
+            foreach (string templateHint in templateHints.Where(s => !String.IsNullOrEmpty(s))) {
+                yield return templateHint;
+            }
+
+            // We don't want to search for Nullable<T>, we want to search for T (which should handle both T and Nullable<T>)
+            Type fieldType = Nullable.GetUnderlyingType(metadata.RealModelType) ?? metadata.RealModelType;
+
+            // TODO: Make better string names for generic types
+            yield return fieldType.Name;
+
+            if (!metadata.IsComplexType) {
+                yield return "String";
+            }
+            else if (fieldType.IsInterface) {
+                if (typeof(IEnumerable).IsAssignableFrom(fieldType)) {
+                    yield return "Collection";
+                }
+
+                yield return "Object";
+            }
+            else {
+                bool isEnumerable = typeof(IEnumerable).IsAssignableFrom(fieldType);
+
+                while (true) {
+                    fieldType = fieldType.BaseType;
+                    if (fieldType == null)
+                        break;
+
+                    if (isEnumerable && fieldType == typeof(Object)) {
+                        yield return "Collection";
+                    }
+
+                    yield return fieldType.Name;
+                }
+            }
+        }
+
+        internal static MvcHtmlString Template(HtmlHelper html, string expression, string templateName, string htmlFieldName, DataBoundControlMode mode, object additionalViewData) {
+            return MvcHtmlString.Create(Template(html, expression, templateName, htmlFieldName, mode, additionalViewData, TemplateHelper));
+        }
+
+        // Unit testing version
+        internal static string Template(HtmlHelper html, string expression, string templateName, string htmlFieldName,
+                                        DataBoundControlMode mode, object additionalViewData, TemplateHelperDelegate templateHelper) {
+            return templateHelper(html,
+                                  ModelMetadata.FromStringExpression(expression, html.ViewData),
+                                  htmlFieldName ?? ExpressionHelper.GetExpressionText(expression),
+                                  templateName,
+                                  mode,
+                                  additionalViewData);
+        }
+
+        internal static MvcHtmlString TemplateFor<TContainer, TValue>(this HtmlHelper<TContainer> html, Expression<Func<TContainer, TValue>> expression,
+                                                                      string templateName, string htmlFieldName, DataBoundControlMode mode,
+                                                                      object additionalViewData) {
+            return MvcHtmlString.Create(TemplateFor(html, expression, templateName, htmlFieldName, mode, additionalViewData, TemplateHelper));
+        }
+
+        // Unit testing version
+        internal static string TemplateFor<TContainer, TValue>(this HtmlHelper<TContainer> html, Expression<Func<TContainer, TValue>> expression,
+                                                               string templateName, string htmlFieldName, DataBoundControlMode mode,
+                                                               object additionalViewData, TemplateHelperDelegate templateHelper) {
+            return templateHelper(html,
+                                  ModelMetadata.FromLambdaExpression(expression, html.ViewData),
+                                  htmlFieldName ?? ExpressionHelper.GetExpressionText(expression),
+                                  templateName,
+                                  mode,
+                                  additionalViewData);
+        }
+
+        internal delegate string TemplateHelperDelegate(HtmlHelper html, ModelMetadata metadata, string htmlFieldName, string templateName, DataBoundControlMode mode, object additionalViewData);
+
+        internal static string TemplateHelper(HtmlHelper html, ModelMetadata metadata, string htmlFieldName, string templateName, DataBoundControlMode mode, object additionalViewData) {
+            return TemplateHelper(html, metadata, htmlFieldName, templateName, mode, additionalViewData, ExecuteTemplate);
+        }
+
+        internal static string TemplateHelper(HtmlHelper html, ModelMetadata metadata, string htmlFieldName, string templateName, DataBoundControlMode mode, object additionalViewData, ExecuteTemplateDelegate executeTemplate) {
+            // TODO: Convert Editor into Display if model.IsReadOnly is true? Need to be careful about this because
+            // the Model property on the ViewPage/ViewUserControl is get-only, so the type descriptor automatically
+            // decorates it with a [ReadOnly] attribute...
+
+            if (metadata.ConvertEmptyStringToNull && String.Empty.Equals(metadata.Model)) {
+                metadata.Model = null;
+            }
+
+            object formattedModelValue = metadata.Model;
+            if (metadata.Model == null && mode == DataBoundControlMode.ReadOnly) {
+                formattedModelValue = metadata.NullDisplayText;
+            }
+
+            string formatString = mode == DataBoundControlMode.ReadOnly ? metadata.DisplayFormatString : metadata.EditFormatString;
+            if (metadata.Model != null && !String.IsNullOrEmpty(formatString)) {
+                formattedModelValue = String.Format(CultureInfo.CurrentCulture, formatString, metadata.Model);
+            }
+
+            // Normally this shouldn't happen, unless someone writes their own custom Object templates which
+            // don't check to make sure that the object hasn't already been displayed
+            object visitedObjectsKey = metadata.Model ?? metadata.RealModelType;
+            if (html.ViewDataContainer.ViewData.TemplateInfo.VisitedObjects.Contains(visitedObjectsKey)) {    // DDB #224750
+                return String.Empty;
+            }
+
+            ViewDataDictionary viewData = new ViewDataDictionary(html.ViewDataContainer.ViewData) {
+                Model = metadata.Model,
+                ModelMetadata = metadata,
+                TemplateInfo = new TemplateInfo {
+                    FormattedModelValue = formattedModelValue,
+                    HtmlFieldPrefix = html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(htmlFieldName),
+                    VisitedObjects = new HashSet<object>(html.ViewContext.ViewData.TemplateInfo.VisitedObjects),    // DDB #224750
+                }
+            };
+
+            if (additionalViewData != null) {
+                foreach (KeyValuePair<string, object> kvp in new RouteValueDictionary(additionalViewData)) {
+                    viewData[kvp.Key] = kvp.Value;
+                }
+            }
+
+            viewData.TemplateInfo.VisitedObjects.Add(visitedObjectsKey);    // DDB #224750
+
+            return executeTemplate(html, viewData, templateName, mode, GetViewNames, GetDefaultActions);
+        }
+
+        // Helpers
+
+        private static HtmlHelper MakeHtmlHelper(HtmlHelper html, ViewDataDictionary viewData) {
+            return new HtmlHelper(
+                new ViewContext(html.ViewContext, html.ViewContext.View, viewData, html.ViewContext.TempData, html.ViewContext.Writer),
+                new ViewDataContainer(viewData)
+            );
+        }
+
+        internal abstract class ActionCacheItem {
+            public abstract string Execute(HtmlHelper html, ViewDataDictionary viewData);
+        }
+
+        internal class ActionCacheCodeItem : ActionCacheItem {
+            public Func<HtmlHelper, string> Action { get; set; }
+
+            public override string Execute(HtmlHelper html, ViewDataDictionary viewData) {
+                return Action(MakeHtmlHelper(html, viewData));
+            }
+        }
+
+        internal class ActionCacheViewItem : ActionCacheItem {
+            public string ViewName { get; set; }
+
+            public override string Execute(HtmlHelper html, ViewDataDictionary viewData) {
+                ViewEngineResult viewEngineResult = ViewEngines.Engines.FindPartialView(html.ViewContext, ViewName);
+                using (StringWriter writer = new StringWriter(CultureInfo.InvariantCulture)) {
+                    viewEngineResult.View.Render(new ViewContext(html.ViewContext, viewEngineResult.View, viewData, html.ViewContext.TempData, writer), writer);
+                    return writer.ToString();
+                }
+            }
+        }
+
+        private class ViewDataContainer : IViewDataContainer {
+            public ViewDataContainer(ViewDataDictionary viewData) {
+                ViewData = viewData;
+            }
+
+            public ViewDataDictionary ViewData { get; set; }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Html/TextAreaExtensions.cs b/mcs/class/System.Web.Mvc3/Mvc/Html/TextAreaExtensions.cs
new file mode 100644 (file)
index 0000000..5dbbd38
--- /dev/null
@@ -0,0 +1,161 @@
+namespace System.Web.Mvc.Html {
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Linq.Expressions;
+    using System.Web.Mvc.Resources;
+
+    public static class TextAreaExtensions {
+        // These values are similar to the defaults used by WebForms
+        // when using <asp:TextBox TextMode="MultiLine"> without specifying
+        // the Rows and Columns attributes.
+        private const int TextAreaRows = 2;
+        private const int TextAreaColumns = 20;
+        private static Dictionary<string, object> implicitRowsAndColumns = new Dictionary<string, object> {
+            { "rows", TextAreaRows.ToString(CultureInfo.InvariantCulture) },
+            { "cols", TextAreaColumns.ToString(CultureInfo.InvariantCulture) },
+        };
+
+        private static Dictionary<string, object> GetRowsAndColumnsDictionary(int rows, int columns) {
+            if (rows < 0) {
+                throw new ArgumentOutOfRangeException("rows", MvcResources.HtmlHelper_TextAreaParameterOutOfRange);
+            }
+            if (columns < 0) {
+                throw new ArgumentOutOfRangeException("columns", MvcResources.HtmlHelper_TextAreaParameterOutOfRange);
+            }
+
+            Dictionary<string, object> result = new Dictionary<string, object>();
+            if (rows > 0) {
+                result.Add("rows", rows.ToString(CultureInfo.InvariantCulture));
+            }
+            if (columns > 0) {
+                result.Add("cols", columns.ToString(CultureInfo.InvariantCulture));
+            }
+
+            return result;
+        }
+
+        public static MvcHtmlString TextArea(this HtmlHelper htmlHelper, string name) {
+            return TextArea(htmlHelper, name, null /* value */, null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString TextArea(this HtmlHelper htmlHelper, string name, object htmlAttributes) {
+            return TextArea(htmlHelper, name, null /* value */, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        public static MvcHtmlString TextArea(this HtmlHelper htmlHelper, string name, IDictionary<string, object> htmlAttributes) {
+            return TextArea(htmlHelper, name, null /* value */, htmlAttributes);
+        }
+
+        public static MvcHtmlString TextArea(this HtmlHelper htmlHelper, string name, string value) {
+            return TextArea(htmlHelper, name, value, null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString TextArea(this HtmlHelper htmlHelper, string name, string value, object htmlAttributes) {
+            return TextArea(htmlHelper, name, value, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        public static MvcHtmlString TextArea(this HtmlHelper htmlHelper, string name, string value, IDictionary<string, object> htmlAttributes) {
+            ModelMetadata metadata = ModelMetadata.FromStringExpression(name, htmlHelper.ViewContext.ViewData);
+            if (value != null) {
+                metadata.Model = value;
+            }
+
+            return TextAreaHelper(htmlHelper, metadata, name, implicitRowsAndColumns, htmlAttributes);
+        }
+
+        public static MvcHtmlString TextArea(this HtmlHelper htmlHelper, string name, string value, int rows, int columns, object htmlAttributes) {
+            return TextArea(htmlHelper, name, value, rows, columns, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        public static MvcHtmlString TextArea(this HtmlHelper htmlHelper, string name, string value, int rows, int columns, IDictionary<string, object> htmlAttributes) {
+            ModelMetadata metadata = ModelMetadata.FromStringExpression(name, htmlHelper.ViewContext.ViewData);
+            if (value != null) {
+                metadata.Model = value;
+            }
+
+            return TextAreaHelper(htmlHelper, metadata, name, GetRowsAndColumnsDictionary(rows, columns), htmlAttributes);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString TextAreaFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) {
+            return TextAreaFor(htmlHelper, expression, (IDictionary<string, object>)null);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString TextAreaFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes) {
+            return TextAreaFor(htmlHelper, expression, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString TextAreaFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes) {
+            if (expression == null) {
+                throw new ArgumentNullException("expression");
+            }
+
+            return TextAreaHelper(htmlHelper,
+                                  ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData),
+                                  ExpressionHelper.GetExpressionText(expression),
+                                  implicitRowsAndColumns,
+                                  htmlAttributes);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString TextAreaFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, int rows, int columns, object htmlAttributes) {
+            return TextAreaFor(htmlHelper, expression, rows, columns, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString TextAreaFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, int rows, int columns, IDictionary<string, object> htmlAttributes) {
+            if (expression == null) {
+                throw new ArgumentNullException("expression");
+            }
+
+            return TextAreaHelper(htmlHelper,
+                                  ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData),
+                                  ExpressionHelper.GetExpressionText(expression),
+                                  GetRowsAndColumnsDictionary(rows, columns),
+                                  htmlAttributes);
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly", Justification = "If this fails, it is because the string-based version had an empty 'name' parameter")]
+        private static MvcHtmlString TextAreaHelper(HtmlHelper htmlHelper, ModelMetadata modelMetadata, string name, IDictionary<string, object> rowsAndColumns, IDictionary<string, object> htmlAttributes) {
+            string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
+            if (String.IsNullOrEmpty(fullName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "name");
+            }
+
+            TagBuilder tagBuilder = new TagBuilder("textarea");
+            tagBuilder.GenerateId(fullName);
+            tagBuilder.MergeAttributes(htmlAttributes, true);
+            tagBuilder.MergeAttributes(rowsAndColumns, rowsAndColumns != implicitRowsAndColumns);  // Only force explicit rows/cols
+            tagBuilder.MergeAttribute("name", fullName, true);
+
+            // If there are any errors for a named field, we add the CSS attribute.
+            ModelState modelState;
+            if (htmlHelper.ViewData.ModelState.TryGetValue(fullName, out modelState) && modelState.Errors.Count > 0) {
+                tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName);
+            }
+
+            tagBuilder.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(name));
+
+            string value;
+            if (modelState != null && modelState.Value != null) {
+                value = modelState.Value.AttemptedValue;
+            }
+            else if (modelMetadata.Model != null) {
+                value = modelMetadata.Model.ToString();
+            }
+            else {
+                value = String.Empty;
+            }
+
+            // The first newline is always trimmed when a TextArea is rendered, so we add an extra one
+            // in case the value being rendered is something like "\r\nHello".
+            tagBuilder.SetInnerText(Environment.NewLine + value);
+
+            return tagBuilder.ToMvcHtmlString(TagRenderMode.Normal);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Html/ValidationExtensions.cs b/mcs/class/System.Web.Mvc3/Mvc/Html/ValidationExtensions.cs
new file mode 100644 (file)
index 0000000..a8b1cb9
--- /dev/null
@@ -0,0 +1,314 @@
+namespace System.Web.Mvc.Html {
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Linq;
+    using System.Linq.Expressions;
+    using System.Text;
+    using System.Web.Mvc.Resources;
+    using System.Web.Routing;
+
+    public static class ValidationExtensions {
+
+        private const string _hiddenListItem = @"<li style=""display:none""></li>";
+        private static string _resourceClassKey;
+
+        public static string ResourceClassKey {
+            get {
+                return _resourceClassKey ?? String.Empty;
+            }
+            set {
+                _resourceClassKey = value;
+            }
+        }
+
+        private static FieldValidationMetadata ApplyFieldValidationMetadata(HtmlHelper htmlHelper, ModelMetadata modelMetadata, string modelName) {
+            FormContext formContext = htmlHelper.ViewContext.FormContext;
+            FieldValidationMetadata fieldMetadata = formContext.GetValidationMetadataForField(modelName, true /* createIfNotFound */);
+
+            // write rules to context object
+            IEnumerable<ModelValidator> validators = ModelValidatorProviders.Providers.GetValidators(modelMetadata, htmlHelper.ViewContext);
+            foreach (ModelClientValidationRule rule in validators.SelectMany(v => v.GetClientValidationRules())) {
+                fieldMetadata.ValidationRules.Add(rule);
+            }
+
+            return fieldMetadata;
+        }
+
+        private static string GetInvalidPropertyValueResource(HttpContextBase httpContext) {
+            string resourceValue = null;
+            if (!String.IsNullOrEmpty(ResourceClassKey) && (httpContext != null)) {
+                // If the user specified a ResourceClassKey try to load the resource they specified.
+                // If the class key is invalid, an exception will be thrown.
+                // If the class key is valid but the resource is not found, it returns null, in which
+                // case it will fall back to the MVC default error message.
+                resourceValue = httpContext.GetGlobalResourceObject(ResourceClassKey, "InvalidPropertyValue", CultureInfo.CurrentUICulture) as string;
+            }
+            return resourceValue ?? MvcResources.Common_ValueNotValidForProperty;
+        }
+
+        private static string GetUserErrorMessageOrDefault(HttpContextBase httpContext, ModelError error, ModelState modelState) {
+            if (!String.IsNullOrEmpty(error.ErrorMessage)) {
+                return error.ErrorMessage;
+            }
+            if (modelState == null) {
+                return null;
+            }
+
+            string attemptedValue = (modelState.Value != null) ? modelState.Value.AttemptedValue : null;
+            return String.Format(CultureInfo.CurrentCulture, GetInvalidPropertyValueResource(httpContext), attemptedValue);
+        }
+
+        // Validate
+
+        public static void Validate(this HtmlHelper htmlHelper, string modelName) {
+            if (modelName == null) {
+                throw new ArgumentNullException("modelName");
+            }
+
+            ValidateHelper(htmlHelper,
+                ModelMetadata.FromStringExpression(modelName, htmlHelper.ViewContext.ViewData),
+                modelName);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static void ValidateFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) {
+            ValidateHelper(htmlHelper,
+                ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData),
+                ExpressionHelper.GetExpressionText(expression));
+        }
+
+        private static void ValidateHelper(HtmlHelper htmlHelper, ModelMetadata modelMetadata, string expression) {
+            FormContext formContext = htmlHelper.ViewContext.GetFormContextForClientValidation();
+            if (formContext == null || htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled) {
+                return; // nothing to do
+            }
+
+            string modelName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(expression);
+            ApplyFieldValidationMetadata(htmlHelper, modelMetadata, modelName);
+        }
+
+        // ValidationMessage
+
+        public static MvcHtmlString ValidationMessage(this HtmlHelper htmlHelper, string modelName) {
+            return ValidationMessage(htmlHelper, modelName, null /* validationMessage */, new RouteValueDictionary());
+        }
+
+        public static MvcHtmlString ValidationMessage(this HtmlHelper htmlHelper, string modelName, object htmlAttributes) {
+            return ValidationMessage(htmlHelper, modelName, null /* validationMessage */, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        [SuppressMessage("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", Justification = "'validationMessage' refers to the message that will be rendered by the ValidationMessage helper.")]
+        public static MvcHtmlString ValidationMessage(this HtmlHelper htmlHelper, string modelName, string validationMessage) {
+            return ValidationMessage(htmlHelper, modelName, validationMessage, new RouteValueDictionary());
+        }
+
+        [SuppressMessage("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", Justification = "'validationMessage' refers to the message that will be rendered by the ValidationMessage helper.")]
+        public static MvcHtmlString ValidationMessage(this HtmlHelper htmlHelper, string modelName, string validationMessage, object htmlAttributes) {
+            return ValidationMessage(htmlHelper, modelName, validationMessage, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        public static MvcHtmlString ValidationMessage(this HtmlHelper htmlHelper, string modelName, IDictionary<string, object> htmlAttributes) {
+            return ValidationMessage(htmlHelper, modelName, null /* validationMessage */, htmlAttributes);
+        }
+
+        [SuppressMessage("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", Justification = "'validationMessage' refers to the message that will be rendered by the ValidationMessage helper.")]
+        public static MvcHtmlString ValidationMessage(this HtmlHelper htmlHelper, string modelName, string validationMessage, IDictionary<string, object> htmlAttributes) {
+            if (modelName == null) {
+                throw new ArgumentNullException("modelName");
+            }
+
+            return ValidationMessageHelper(htmlHelper,
+                                           ModelMetadata.FromStringExpression(modelName, htmlHelper.ViewContext.ViewData),
+                                           modelName,
+                                           validationMessage,
+                                           htmlAttributes);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString ValidationMessageFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) {
+            return ValidationMessageFor(htmlHelper, expression, null /* validationMessage */, new RouteValueDictionary());
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString ValidationMessageFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string validationMessage) {
+            return ValidationMessageFor(htmlHelper, expression, validationMessage, new RouteValueDictionary());
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString ValidationMessageFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string validationMessage, object htmlAttributes) {
+            return ValidationMessageFor(htmlHelper, expression, validationMessage, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static MvcHtmlString ValidationMessageFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string validationMessage, IDictionary<string, object> htmlAttributes) {
+            return ValidationMessageHelper(htmlHelper,
+                                           ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData),
+                                           ExpressionHelper.GetExpressionText(expression),
+                                           validationMessage,
+                                           htmlAttributes);
+        }
+
+        [SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Justification = "Normalization to lowercase is a common requirement for JavaScript and HTML values")]
+        private static MvcHtmlString ValidationMessageHelper(this HtmlHelper htmlHelper, ModelMetadata modelMetadata, string expression, string validationMessage, IDictionary<string, object> htmlAttributes) {
+            string modelName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(expression);
+            FormContext formContext = htmlHelper.ViewContext.GetFormContextForClientValidation();
+
+            if (!htmlHelper.ViewData.ModelState.ContainsKey(modelName) && formContext == null) {
+                return null;
+            }
+
+            ModelState modelState = htmlHelper.ViewData.ModelState[modelName];
+            ModelErrorCollection modelErrors = (modelState == null) ? null : modelState.Errors;
+            ModelError modelError = (((modelErrors == null) || (modelErrors.Count == 0)) ? null : modelErrors.FirstOrDefault(m => !String.IsNullOrEmpty(m.ErrorMessage)) ?? modelErrors[0]);
+
+            if (modelError == null && formContext == null) {
+                return null;
+            }
+
+            TagBuilder builder = new TagBuilder("span");
+            builder.MergeAttributes(htmlAttributes);
+            builder.AddCssClass((modelError != null) ? HtmlHelper.ValidationMessageCssClassName : HtmlHelper.ValidationMessageValidCssClassName);
+
+            if (!String.IsNullOrEmpty(validationMessage)) {
+                builder.SetInnerText(validationMessage);
+            }
+            else if (modelError != null) {
+                builder.SetInnerText(GetUserErrorMessageOrDefault(htmlHelper.ViewContext.HttpContext, modelError, modelState));
+            }
+
+            if (formContext != null) {
+                bool replaceValidationMessageContents = String.IsNullOrEmpty(validationMessage);
+
+                if (htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled) {
+                    builder.MergeAttribute("data-valmsg-for", modelName);
+                    builder.MergeAttribute("data-valmsg-replace", replaceValidationMessageContents.ToString().ToLowerInvariant());
+                }
+                else {
+                    FieldValidationMetadata fieldMetadata = ApplyFieldValidationMetadata(htmlHelper, modelMetadata, modelName);
+                    // rules will already have been written to the metadata object
+                    fieldMetadata.ReplaceValidationMessageContents = replaceValidationMessageContents; // only replace contents if no explicit message was specified
+
+                    // client validation always requires an ID
+                    builder.GenerateId(modelName + "_validationMessage");
+                    fieldMetadata.ValidationMessageId = builder.Attributes["id"];
+                }
+            }
+
+            return builder.ToMvcHtmlString(TagRenderMode.Normal);
+        }
+
+        // ValidationSummary
+
+        public static MvcHtmlString ValidationSummary(this HtmlHelper htmlHelper) {
+            return ValidationSummary(htmlHelper, false /* excludePropertyErrors */ );
+        }
+
+        public static MvcHtmlString ValidationSummary(this HtmlHelper htmlHelper, bool excludePropertyErrors) {
+            return ValidationSummary(htmlHelper, excludePropertyErrors, null /* message */);
+        }
+
+        public static MvcHtmlString ValidationSummary(this HtmlHelper htmlHelper, string message) {
+            return ValidationSummary(htmlHelper, false /* excludePropertyErrors */, message, (object)null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString ValidationSummary(this HtmlHelper htmlHelper, bool excludePropertyErrors, string message) {
+            return ValidationSummary(htmlHelper, excludePropertyErrors, message, (object)null /* htmlAttributes */);
+        }
+
+        public static MvcHtmlString ValidationSummary(this HtmlHelper htmlHelper, string message, object htmlAttributes) {
+            return ValidationSummary(htmlHelper, false /* excludePropertyErrors */, message, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        public static MvcHtmlString ValidationSummary(this HtmlHelper htmlHelper, bool excludePropertyErrors, string message, object htmlAttributes) {
+            return ValidationSummary(htmlHelper, excludePropertyErrors, message, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
+        }
+
+        public static MvcHtmlString ValidationSummary(this HtmlHelper htmlHelper, string message, IDictionary<string, object> htmlAttributes) {
+            return ValidationSummary(htmlHelper, false /* excludePropertyErrors */, message, htmlAttributes);
+        }
+
+        public static MvcHtmlString ValidationSummary(this HtmlHelper htmlHelper, bool excludePropertyErrors, string message, IDictionary<string, object> htmlAttributes) {
+            if (htmlHelper == null) {
+                throw new ArgumentNullException("htmlHelper");
+            }
+
+            FormContext formContext = htmlHelper.ViewContext.GetFormContextForClientValidation();
+            if (htmlHelper.ViewData.ModelState.IsValid) {
+                if (formContext == null) {  // No client side validation
+                    return null;
+                }
+                // TODO: This isn't really about unobtrusive; can we fix up non-unobtrusive to get rid of this, too?
+                if (htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled && excludePropertyErrors) {  // No client-side updates
+                    return null;
+                }
+            }
+
+            string messageSpan;
+            if (!String.IsNullOrEmpty(message)) {
+                TagBuilder spanTag = new TagBuilder("span");
+                spanTag.SetInnerText(message);
+                messageSpan = spanTag.ToString(TagRenderMode.Normal) + Environment.NewLine;
+            }
+            else {
+                messageSpan = null;
+            }
+
+            StringBuilder htmlSummary = new StringBuilder();
+            TagBuilder unorderedList = new TagBuilder("ul");
+
+            IEnumerable<ModelState> modelStates = null;
+            if (excludePropertyErrors) {
+                ModelState ms;
+                htmlHelper.ViewData.ModelState.TryGetValue(htmlHelper.ViewData.TemplateInfo.HtmlFieldPrefix, out ms);
+                if (ms != null) {
+                    modelStates = new ModelState[] { ms };
+                }
+            }
+            else {
+                modelStates = htmlHelper.ViewData.ModelState.Values;
+            }
+
+            if (modelStates != null) {
+                foreach (ModelState modelState in modelStates) {
+                    foreach (ModelError modelError in modelState.Errors) {
+                        string errorText = GetUserErrorMessageOrDefault(htmlHelper.ViewContext.HttpContext, modelError, null /* modelState */);
+                        if (!String.IsNullOrEmpty(errorText)) {
+                            TagBuilder listItem = new TagBuilder("li");
+                            listItem.SetInnerText(errorText);
+                            htmlSummary.AppendLine(listItem.ToString(TagRenderMode.Normal));
+                        }
+                    }
+                }
+            }
+
+            if (htmlSummary.Length == 0) {
+                htmlSummary.AppendLine(_hiddenListItem);
+            }
+
+            unorderedList.InnerHtml = htmlSummary.ToString();
+
+            TagBuilder divBuilder = new TagBuilder("div");
+            divBuilder.MergeAttributes(htmlAttributes);
+            divBuilder.AddCssClass((htmlHelper.ViewData.ModelState.IsValid) ? HtmlHelper.ValidationSummaryValidCssClassName : HtmlHelper.ValidationSummaryCssClassName);
+            divBuilder.InnerHtml = messageSpan + unorderedList.ToString(TagRenderMode.Normal);
+
+            if (formContext != null) {
+                if (htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled) {
+                    if (!excludePropertyErrors) {  // Only put errors in the validation summary if they're supposed to be included there
+                        divBuilder.MergeAttribute("data-valmsg-summary", "true");
+                    }
+                }
+                else {
+                    // client val summaries need an ID
+                    divBuilder.GenerateId("validationSummary");
+                    formContext.ValidationSummaryId = divBuilder.Attributes["id"];
+                    formContext.ReplaceValidationSummary = !excludePropertyErrors;
+                }
+            }
+            return divBuilder.ToMvcHtmlString(TagRenderMode.Normal);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/HtmlHelper.cs b/mcs/class/System.Web.Mvc3/Mvc/HtmlHelper.cs
new file mode 100644 (file)
index 0000000..63e6218
--- /dev/null
@@ -0,0 +1,449 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.ComponentModel;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.IO;
+    using System.Linq;
+    using System.Text;
+    using System.Web;
+    using System.Web.Helpers;
+    using System.Web.Mvc.Resources;
+    using System.Web.Routing;
+
+    public class HtmlHelper {
+        public static readonly string ValidationInputCssClassName = "input-validation-error";
+        public static readonly string ValidationInputValidCssClassName = "input-validation-valid";
+        public static readonly string ValidationMessageCssClassName = "field-validation-error";
+        public static readonly string ValidationMessageValidCssClassName = "field-validation-valid";
+        public static readonly string ValidationSummaryCssClassName = "validation-summary-errors";
+        public static readonly string ValidationSummaryValidCssClassName = "validation-summary-valid";
+
+        public HtmlHelper(ViewContext viewContext, IViewDataContainer viewDataContainer)
+            : this(viewContext, viewDataContainer, RouteTable.Routes) {
+        }
+
+        public HtmlHelper(ViewContext viewContext, IViewDataContainer viewDataContainer, RouteCollection routeCollection) {
+            if (viewContext == null) {
+                throw new ArgumentNullException("viewContext");
+            }
+            if (viewDataContainer == null) {
+                throw new ArgumentNullException("viewDataContainer");
+            }
+            if (routeCollection == null) {
+                throw new ArgumentNullException("routeCollection");
+            }
+
+            ViewContext = viewContext;
+            ViewDataContainer = viewDataContainer;
+            RouteCollection = routeCollection;
+            ClientValidationRuleFactory = (name, metadata) => ModelValidatorProviders.Providers.GetValidators(metadata ?? ModelMetadata.FromStringExpression(name, ViewData), ViewContext).SelectMany(v => v.GetClientValidationRules());
+        }
+
+        public static bool ClientValidationEnabled {
+            get {
+                return ViewContext.GetClientValidationEnabled();
+            }
+            set {
+                ViewContext.SetClientValidationEnabled(value);
+            }
+        }
+
+        public static string IdAttributeDotReplacement {
+            get {
+                return System.Web.WebPages.Html.HtmlHelper.IdAttributeDotReplacement;
+            }
+            set {
+                System.Web.WebPages.Html.HtmlHelper.IdAttributeDotReplacement = value;
+            }
+        }
+
+        internal Func<string, ModelMetadata, IEnumerable<ModelClientValidationRule>> ClientValidationRuleFactory {
+            get;
+            set;
+        }
+
+        public RouteCollection RouteCollection {
+            get;
+            private set;
+        }
+
+        public static bool UnobtrusiveJavaScriptEnabled {
+            get {
+                return ViewContext.GetUnobtrusiveJavaScriptEnabled();
+            }
+            set {
+                ViewContext.SetUnobtrusiveJavaScriptEnabled(value);
+            }
+        }
+
+        public ViewContext ViewContext {
+            get;
+            private set;
+        }
+
+        public ViewDataDictionary ViewData {
+            get {
+                return ViewDataContainer.ViewData;
+            }
+        }
+
+        public IViewDataContainer ViewDataContainer {
+            get;
+            private set;
+        }
+
+        public static RouteValueDictionary AnonymousObjectToHtmlAttributes(object htmlAttributes) {
+            RouteValueDictionary result = new RouteValueDictionary();
+
+            if (htmlAttributes != null) {
+                foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(htmlAttributes)) {
+                    result.Add(property.Name.Replace('_', '-'), property.GetValue(htmlAttributes));
+                }
+            }
+
+            return result;
+        }
+
+        public MvcHtmlString AntiForgeryToken() {
+            return AntiForgeryToken(salt: null);
+        }
+
+        public MvcHtmlString AntiForgeryToken(string salt) {
+            return AntiForgeryToken(salt, domain: null, path: null);
+        }
+
+        public MvcHtmlString AntiForgeryToken(string salt, string domain, string path) {
+            return new MvcHtmlString(AntiForgery.GetHtml(ViewContext.HttpContext, salt, domain, path).ToString());
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "For consistency, all helpers are instance methods.")]
+        public string AttributeEncode(string value) {
+            return (!String.IsNullOrEmpty(value)) ? HttpUtility.HtmlAttributeEncode(value) : String.Empty;
+        }
+
+        public string AttributeEncode(object value) {
+            return AttributeEncode(Convert.ToString(value, CultureInfo.InvariantCulture));
+        }
+
+        public void EnableClientValidation() {
+            EnableClientValidation(enabled: true);
+        }
+
+        public void EnableClientValidation(bool enabled) {
+            ViewContext.ClientValidationEnabled = enabled;
+        }
+
+        public void EnableUnobtrusiveJavaScript() {
+            EnableUnobtrusiveJavaScript(enabled: true);
+        }
+
+        public void EnableUnobtrusiveJavaScript(bool enabled) {
+            ViewContext.UnobtrusiveJavaScriptEnabled = enabled;
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "For consistency, all helpers are instance methods.")]
+        public string Encode(string value) {
+            return (!String.IsNullOrEmpty(value)) ? HttpUtility.HtmlEncode(value) : String.Empty;
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "For consistency, all helpers are instance methods.")]
+        public string Encode(object value) {
+            return value != null ? HttpUtility.HtmlEncode(value) : String.Empty;
+        }
+
+        internal string EvalString(string key) {
+            return Convert.ToString(ViewData.Eval(key), CultureInfo.CurrentCulture);
+        }
+
+        internal bool EvalBoolean(string key) {
+            return Convert.ToBoolean(ViewData.Eval(key), CultureInfo.InvariantCulture);
+        }
+
+        internal static IView FindPartialView(ViewContext viewContext, string partialViewName, ViewEngineCollection viewEngineCollection) {
+            ViewEngineResult result = viewEngineCollection.FindPartialView(viewContext, partialViewName);
+            if (result.View != null) {
+                return result.View;
+            }
+
+            StringBuilder locationsText = new StringBuilder();
+            foreach (string location in result.SearchedLocations) {
+                locationsText.AppendLine();
+                locationsText.Append(location);
+            }
+
+            throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
+                MvcResources.Common_PartialViewNotFound, partialViewName, locationsText));
+        }
+
+        public static string GenerateIdFromName(string name) {
+            return GenerateIdFromName(name, IdAttributeDotReplacement);
+        }
+
+        public static string GenerateIdFromName(string name, string idAttributeDotReplacement) {
+            if (name == null) {
+                throw new ArgumentNullException("name");
+            }
+
+            if (idAttributeDotReplacement == null) {
+                throw new ArgumentNullException("idAttributeDotReplacement");
+            }
+
+            // TagBuilder.CreateSanitizedId returns null for empty strings, return String.Empty instead to avoid breaking change
+            if (name.Length == 0) {
+                return String.Empty;
+            }
+
+            return TagBuilder.CreateSanitizedId(name, idAttributeDotReplacement);
+        }
+
+        public static string GenerateLink(RequestContext requestContext, RouteCollection routeCollection, string linkText, string routeName, string actionName, string controllerName, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes) {
+            return GenerateLink(requestContext, routeCollection, linkText, routeName, actionName, controllerName, null/* protocol */, null/* hostName */, null/* fragment */, routeValues, htmlAttributes);
+        }
+
+        public static string GenerateLink(RequestContext requestContext, RouteCollection routeCollection, string linkText, string routeName, string actionName, string controllerName, string protocol, string hostName, string fragment, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes) {
+            return GenerateLinkInternal(requestContext, routeCollection, linkText, routeName, actionName, controllerName, protocol, hostName, fragment, routeValues, htmlAttributes, true /* includeImplicitMvcValues */);
+        }
+
+        private static string GenerateLinkInternal(RequestContext requestContext, RouteCollection routeCollection, string linkText, string routeName, string actionName, string controllerName, string protocol, string hostName, string fragment, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes, bool includeImplicitMvcValues) {
+            string url = UrlHelper.GenerateUrl(routeName, actionName, controllerName, protocol, hostName, fragment, routeValues, routeCollection, requestContext, includeImplicitMvcValues);
+            TagBuilder tagBuilder = new TagBuilder("a") {
+                InnerHtml = (!String.IsNullOrEmpty(linkText)) ? HttpUtility.HtmlEncode(linkText) : String.Empty
+            };
+            tagBuilder.MergeAttributes(htmlAttributes);
+            tagBuilder.MergeAttribute("href", url);
+            return tagBuilder.ToString(TagRenderMode.Normal);
+        }
+
+        public static string GenerateRouteLink(RequestContext requestContext, RouteCollection routeCollection, string linkText, string routeName, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes) {
+            return GenerateRouteLink(requestContext, routeCollection, linkText, routeName, null/* protocol */, null/* hostName */, null/* fragment */, routeValues, htmlAttributes);
+        }
+
+        public static string GenerateRouteLink(RequestContext requestContext, RouteCollection routeCollection, string linkText, string routeName, string protocol, string hostName, string fragment, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes) {
+            return GenerateLinkInternal(requestContext, routeCollection, linkText, routeName, null /* actionName */, null /* controllerName */, protocol, hostName, fragment, routeValues, htmlAttributes, false /* includeImplicitMvcValues */);
+        }
+
+        public static string GetFormMethodString(FormMethod method) {
+            switch (method) {
+                case FormMethod.Get:
+                    return "get";
+                case FormMethod.Post:
+                    return "post";
+                default:
+                    return "post";
+            }
+        }
+
+        public static string GetInputTypeString(InputType inputType) {
+            switch (inputType) {
+                case InputType.CheckBox:
+                    return "checkbox";
+                case InputType.Hidden:
+                    return "hidden";
+                case InputType.Password:
+                    return "password";
+                case InputType.Radio:
+                    return "radio";
+                case InputType.Text:
+                    return "text";
+                default:
+                    return "text";
+            }
+        }
+
+        internal object GetModelStateValue(string key, Type destinationType) {
+            ModelState modelState;
+            if (ViewData.ModelState.TryGetValue(key, out modelState)) {
+                if (modelState.Value != null) {
+                    return modelState.Value.ConvertTo(destinationType, null /* culture */);
+                }
+            }
+            return null;
+        }
+
+        public IDictionary<string, object> GetUnobtrusiveValidationAttributes(string name) {
+            return GetUnobtrusiveValidationAttributes(name, metadata: null);
+        }
+
+        // Only render attributes if unobtrusive client-side validation is enabled, and then only if we've
+        // never rendered validation for a field with this name in this form. Also, if there's no form context,
+        // then we can't render the attributes (we'd have no <form> to attach them to).
+        public IDictionary<string, object> GetUnobtrusiveValidationAttributes(string name, ModelMetadata metadata) {
+            Dictionary<string, object> results = new Dictionary<string, object>();
+
+            // The ordering of these 3 checks (and the early exits) is for performance reasons.
+            if (!ViewContext.UnobtrusiveJavaScriptEnabled) {
+                return results;
+            }
+
+            FormContext formContext = ViewContext.GetFormContextForClientValidation();
+            if (formContext == null) {
+                return results;
+            }
+
+            string fullName = ViewData.TemplateInfo.GetFullHtmlFieldName(name);
+            if (formContext.RenderedField(fullName)) {
+                return results;
+            }
+
+            formContext.RenderedField(fullName, true);
+
+            IEnumerable<ModelClientValidationRule> clientRules = ClientValidationRuleFactory(name, metadata);
+            bool renderedRules = false;
+
+            foreach (ModelClientValidationRule rule in clientRules) {
+                renderedRules = true;
+                string ruleName = "data-val-" + rule.ValidationType;
+
+                ValidateUnobtrusiveValidationRule(rule, results, ruleName);
+
+                results.Add(ruleName, HttpUtility.HtmlEncode(rule.ErrorMessage ?? String.Empty));
+                ruleName += "-";
+
+                foreach (var kvp in rule.ValidationParameters) {
+                    results.Add(ruleName + kvp.Key, kvp.Value ?? String.Empty);
+                }
+            }
+
+            if (renderedRules) {
+                results.Add("data-val", "true");
+            }
+
+            return results;
+        }
+
+        public MvcHtmlString HttpMethodOverride(HttpVerbs httpVerb) {
+            string httpMethod;
+            switch (httpVerb) {
+                case HttpVerbs.Delete:
+                    httpMethod = "DELETE";
+                    break;
+                case HttpVerbs.Head:
+                    httpMethod = "HEAD";
+                    break;
+                case HttpVerbs.Put:
+                    httpMethod = "PUT";
+                    break;
+                default:
+                    throw new ArgumentException(MvcResources.HtmlHelper_InvalidHttpVerb, "httpVerb");
+            }
+
+            return HttpMethodOverride(httpMethod);
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "For consistency, all helpers are instance methods.")]
+        public MvcHtmlString HttpMethodOverride(string httpMethod) {
+            if (String.IsNullOrEmpty(httpMethod)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "httpMethod");
+            }
+            if (String.Equals(httpMethod, "GET", StringComparison.OrdinalIgnoreCase) ||
+                String.Equals(httpMethod, "POST", StringComparison.OrdinalIgnoreCase)) {
+                throw new ArgumentException(MvcResources.HtmlHelper_InvalidHttpMethod, "httpMethod");
+            }
+
+            TagBuilder tagBuilder = new TagBuilder("input");
+            tagBuilder.Attributes["type"] = "hidden";
+            tagBuilder.Attributes["name"] = HttpRequestExtensions.XHttpMethodOverrideKey;
+            tagBuilder.Attributes["value"] = httpMethod;
+
+            return tagBuilder.ToMvcHtmlString(TagRenderMode.SelfClosing);
+        }
+
+        /// <summary>
+        /// Wraps HTML markup in an IHtmlString, which will enable HTML markup to be
+        /// rendered to the output without getting HTML encoded.
+        /// </summary>
+        /// <param name="value">HTML markup string.</param>
+        /// <returns>An IHtmlString that represents HTML markup.</returns>
+        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "For consistency, all helpers are instance methods.")]
+        public IHtmlString Raw(string value) {
+            return new HtmlString(value);
+        }
+
+        internal virtual void RenderPartialInternal(string partialViewName, ViewDataDictionary viewData, object model, TextWriter writer, ViewEngineCollection viewEngineCollection) {
+            if (String.IsNullOrEmpty(partialViewName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "partialViewName");
+            }
+
+            ViewDataDictionary newViewData = null;
+
+            if (model == null) {
+                if (viewData == null) {
+                    newViewData = new ViewDataDictionary(ViewData);
+                }
+                else {
+                    newViewData = new ViewDataDictionary(viewData);
+                }
+            }
+            else {
+                if (viewData == null) {
+                    newViewData = new ViewDataDictionary(model);
+                }
+                else {
+                    newViewData = new ViewDataDictionary(viewData) { Model = model };
+                }
+            }
+
+            ViewContext newViewContext = new ViewContext(ViewContext, ViewContext.View, newViewData, ViewContext.TempData, writer);
+            IView view = FindPartialView(newViewContext, partialViewName, viewEngineCollection);
+            view.Render(newViewContext, writer);
+        }
+
+        private static void ValidateUnobtrusiveValidationRule(ModelClientValidationRule rule, Dictionary<string, object> resultsDictionary, string dictionaryKey) {
+            if (String.IsNullOrWhiteSpace(rule.ValidationType)) {
+                throw new InvalidOperationException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.HtmlHelper_ValidationTypeCannotBeEmpty,
+                        rule.GetType().FullName
+                    )
+                );
+            }
+
+            if (resultsDictionary.ContainsKey(dictionaryKey)) {
+                throw new InvalidOperationException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.HtmlHelper_ValidationTypeMustBeUnique,
+                        rule.ValidationType
+                    )
+                );
+            }
+
+            if (rule.ValidationType.Any(c => !Char.IsLower(c))) {
+                throw new InvalidOperationException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.HtmlHelper_ValidationTypeMustBeLegal,
+                        rule.ValidationType,
+                        rule.GetType().FullName
+                    )
+                );
+            }
+
+            foreach (var key in rule.ValidationParameters.Keys) {
+                if (String.IsNullOrWhiteSpace(key)) {
+                    throw new InvalidOperationException(
+                        String.Format(
+                            CultureInfo.CurrentCulture,
+                            MvcResources.HtmlHelper_ValidationParameterCannotBeEmpty,
+                            rule.GetType().FullName
+                        )
+                    );
+                }
+
+                if (!Char.IsLower(key.First()) || key.Any(c => !Char.IsLower(c) && !Char.IsDigit(c))) {
+                    throw new InvalidOperationException(
+                        String.Format(
+                            CultureInfo.CurrentCulture,
+                            MvcResources.HtmlHelper_ValidationParameterMustBeLegal,
+                            key,
+                            rule.GetType().FullName
+                        )
+                    );
+                }
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/HtmlHelper`1.cs b/mcs/class/System.Web.Mvc3/Mvc/HtmlHelper`1.cs
new file mode 100644 (file)
index 0000000..c4886d7
--- /dev/null
@@ -0,0 +1,23 @@
+namespace System.Web.Mvc {
+    using System.Web.Routing;
+
+    public class HtmlHelper<TModel> : HtmlHelper {
+        private ViewDataDictionary<TModel> _viewData;
+
+        public HtmlHelper(ViewContext viewContext, IViewDataContainer viewDataContainer)
+            : this(viewContext, viewDataContainer, RouteTable.Routes) {
+        }
+
+        public HtmlHelper(ViewContext viewContext, IViewDataContainer viewDataContainer, RouteCollection routeCollection)
+            : base(viewContext, viewDataContainer, routeCollection) {
+
+            _viewData = new ViewDataDictionary<TModel>(viewDataContainer.ViewData);
+        }
+
+        public new ViewDataDictionary<TModel> ViewData {
+            get {
+                return _viewData;
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/HttpDeleteAttribute.cs b/mcs/class/System.Web.Mvc3/Mvc/HttpDeleteAttribute.cs
new file mode 100644 (file)
index 0000000..5f770da
--- /dev/null
@@ -0,0 +1,15 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Reflection;
+    using System.Web;
+
+    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
+    public sealed class HttpDeleteAttribute : ActionMethodSelectorAttribute {
+
+        private static readonly AcceptVerbsAttribute _innerAttribute = new AcceptVerbsAttribute(HttpVerbs.Delete);
+
+        public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) {
+            return _innerAttribute.IsValidForRequest(controllerContext, methodInfo);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/HttpFileCollectionValueProvider.cs b/mcs/class/System.Web.Mvc3/Mvc/HttpFileCollectionValueProvider.cs
new file mode 100644 (file)
index 0000000..214e65c
--- /dev/null
@@ -0,0 +1,40 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Globalization;
+    using System.Linq;
+
+    public sealed class HttpFileCollectionValueProvider : DictionaryValueProvider<HttpPostedFileBase[]> {
+
+        private static readonly Dictionary<string, HttpPostedFileBase[]> _emptyDictionary = new Dictionary<string, HttpPostedFileBase[]>();
+
+        public HttpFileCollectionValueProvider(ControllerContext controllerContext)
+            : base(GetHttpPostedFileDictionary(controllerContext), CultureInfo.InvariantCulture) {
+        }
+
+        private static Dictionary<string, HttpPostedFileBase[]> GetHttpPostedFileDictionary(ControllerContext controllerContext) {
+            HttpFileCollectionBase files = controllerContext.HttpContext.Request.Files;
+
+            // fast-track common case of no files
+            if (files.Count == 0) {
+                return _emptyDictionary;
+            }
+
+            // build up the 1:many file mapping
+            List<KeyValuePair<string, HttpPostedFileBase>> mapping = new List<KeyValuePair<string, HttpPostedFileBase>>();
+            string[] allKeys = files.AllKeys;
+            for (int i = 0; i < files.Count; i++) {
+                string key = allKeys[i];
+                if (key != null) {
+                    HttpPostedFileBase file = HttpPostedFileBaseModelBinder.ChooseFileOrNull(files[i]);
+                    mapping.Add(new KeyValuePair<string, HttpPostedFileBase>(key, file));
+                }
+            }
+
+            // turn the mapping into a 1:many dictionary
+            var grouped = mapping.GroupBy(el => el.Key, el => el.Value, StringComparer.OrdinalIgnoreCase);
+            return grouped.ToDictionary(g => g.Key, g => g.ToArray(), StringComparer.OrdinalIgnoreCase);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/HttpFileCollectionValueProviderFactory.cs b/mcs/class/System.Web.Mvc3/Mvc/HttpFileCollectionValueProviderFactory.cs
new file mode 100644 (file)
index 0000000..370933f
--- /dev/null
@@ -0,0 +1,15 @@
+namespace System.Web.Mvc {
+    using System;
+
+    public sealed class HttpFileCollectionValueProviderFactory : ValueProviderFactory {
+
+        public override IValueProvider GetValueProvider(ControllerContext controllerContext) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+
+            return new HttpFileCollectionValueProvider(controllerContext);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/HttpGetAttribute.cs b/mcs/class/System.Web.Mvc3/Mvc/HttpGetAttribute.cs
new file mode 100644 (file)
index 0000000..edcd2aa
--- /dev/null
@@ -0,0 +1,15 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Reflection;
+    using System.Web;
+
+    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
+    public sealed class HttpGetAttribute : ActionMethodSelectorAttribute {
+
+        private static readonly AcceptVerbsAttribute _innerAttribute = new AcceptVerbsAttribute(HttpVerbs.Get);
+
+        public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) {
+            return _innerAttribute.IsValidForRequest(controllerContext, methodInfo);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/HttpHandlerUtil.cs b/mcs/class/System.Web.Mvc3/Mvc/HttpHandlerUtil.cs
new file mode 100644 (file)
index 0000000..83fad89
--- /dev/null
@@ -0,0 +1,77 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Web;
+    using System.Web.Mvc.Resources;
+    using System.Web.UI;
+
+    internal static class HttpHandlerUtil {
+
+        // Since Server.Execute() doesn't propagate HttpExceptions where the status code is
+        // anything other than 500, we need to wrap these exceptions ourselves.
+        [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "The Dispose on Page doesn't do anything by default, and we control both of these internal types.")]
+        public static IHttpHandler WrapForServerExecute(IHttpHandler httpHandler) {
+            IHttpAsyncHandler asyncHandler = httpHandler as IHttpAsyncHandler;
+            return (asyncHandler != null) ? new ServerExecuteHttpHandlerAsyncWrapper(asyncHandler) : new ServerExecuteHttpHandlerWrapper(httpHandler);
+        }
+
+        // Server.Execute() requires that the provided IHttpHandler subclass Page.
+        internal class ServerExecuteHttpHandlerWrapper : Page {
+            private readonly IHttpHandler _httpHandler;
+
+            public ServerExecuteHttpHandlerWrapper(IHttpHandler httpHandler) {
+                _httpHandler = httpHandler;
+            }
+
+            internal IHttpHandler InnerHandler {
+                get {
+                    return _httpHandler;
+                }
+            }
+
+            public override void ProcessRequest(HttpContext context) {
+                Wrap(() => _httpHandler.ProcessRequest(context));
+            }
+
+            protected static void Wrap(Action action) {
+                Wrap(delegate {
+                    action();
+                    return (object)null;
+                });
+            }
+
+            protected static TResult Wrap<TResult>(Func<TResult> func) {
+                try {
+                    return func();
+                }
+                catch (HttpException he) {
+                    if (he.GetHttpCode() == 500) {
+                        throw; // doesn't need to be wrapped
+                    }
+                    else {
+                        HttpException newHe = new HttpException(500, MvcResources.ViewPageHttpHandlerWrapper_ExceptionOccurred, he);
+                        throw newHe;
+                    }
+                }
+            }
+        }
+
+        private sealed class ServerExecuteHttpHandlerAsyncWrapper : ServerExecuteHttpHandlerWrapper, IHttpAsyncHandler {
+            private readonly IHttpAsyncHandler _httpHandler;
+
+            public ServerExecuteHttpHandlerAsyncWrapper(IHttpAsyncHandler httpHandler)
+                : base(httpHandler) {
+                _httpHandler = httpHandler;
+            }
+
+            public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) {
+                return Wrap(() => _httpHandler.BeginProcessRequest(context, cb, extraData));
+            }
+
+            public void EndProcessRequest(IAsyncResult result) {
+                Wrap(() => _httpHandler.EndProcessRequest(result));
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/HttpNotFoundResult.cs b/mcs/class/System.Web.Mvc3/Mvc/HttpNotFoundResult.cs
new file mode 100644 (file)
index 0000000..0ac8b67
--- /dev/null
@@ -0,0 +1,16 @@
+namespace System.Web.Mvc {
+
+    public class HttpNotFoundResult : HttpStatusCodeResult {
+
+        // HTTP 404 is the status code for Not Found
+        private const int NotFoundCode = 404;
+
+        public HttpNotFoundResult()
+            : this(null) {
+        }
+
+        public HttpNotFoundResult(string statusDescription)
+            : base(NotFoundCode, statusDescription) {
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/HttpPostAttribute.cs b/mcs/class/System.Web.Mvc3/Mvc/HttpPostAttribute.cs
new file mode 100644 (file)
index 0000000..2ce720a
--- /dev/null
@@ -0,0 +1,15 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Reflection;
+    using System.Web;
+
+    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
+    public sealed class HttpPostAttribute : ActionMethodSelectorAttribute {
+
+        private static readonly AcceptVerbsAttribute _innerAttribute = new AcceptVerbsAttribute(HttpVerbs.Post);
+
+        public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) {
+            return _innerAttribute.IsValidForRequest(controllerContext, methodInfo);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/HttpPostedFileBaseModelBinder.cs b/mcs/class/System.Web.Mvc3/Mvc/HttpPostedFileBaseModelBinder.cs
new file mode 100644 (file)
index 0000000..0778e53
--- /dev/null
@@ -0,0 +1,36 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Web;
+
+    public class HttpPostedFileBaseModelBinder : IModelBinder {
+
+        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+            if (bindingContext == null) {
+                throw new ArgumentNullException("bindingContext");
+            }
+
+            HttpPostedFileBase theFile = controllerContext.HttpContext.Request.Files[bindingContext.ModelName];
+            return ChooseFileOrNull(theFile);
+        }
+
+        // helper that returns the original file if there was content uploaded, null if empty
+        internal static HttpPostedFileBase ChooseFileOrNull(HttpPostedFileBase rawFile) {
+            // case 1: there was no <input type="file" ... /> element in the post
+            if (rawFile == null) {
+                return null;
+            }
+
+            // case 2: there was an <input type="file" ... /> element in the post, but it was left blank
+            if (rawFile.ContentLength == 0 && String.IsNullOrEmpty(rawFile.FileName)) {
+                return null;
+            }
+
+            // case 3: the file was posted
+            return rawFile;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/HttpPutAttribute.cs b/mcs/class/System.Web.Mvc3/Mvc/HttpPutAttribute.cs
new file mode 100644 (file)
index 0000000..821b5d6
--- /dev/null
@@ -0,0 +1,15 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Reflection;
+    using System.Web;
+
+    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
+    public sealed class HttpPutAttribute : ActionMethodSelectorAttribute {
+
+        private static readonly AcceptVerbsAttribute _innerAttribute = new AcceptVerbsAttribute(HttpVerbs.Put);
+
+        public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) {
+            return _innerAttribute.IsValidForRequest(controllerContext, methodInfo);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/HttpRequestExtensions.cs b/mcs/class/System.Web.Mvc3/Mvc/HttpRequestExtensions.cs
new file mode 100644 (file)
index 0000000..a6ec856
--- /dev/null
@@ -0,0 +1,44 @@
+namespace System.Web.Mvc {
+    using System;
+
+    public static class HttpRequestExtensions {
+        internal const string XHttpMethodOverrideKey = "X-HTTP-Method-Override";
+
+        public static string GetHttpMethodOverride(this HttpRequestBase request) {
+            if (request == null) {
+                throw new ArgumentNullException("request");
+            }
+
+            string incomingVerb = request.HttpMethod;
+
+            if (!String.Equals(incomingVerb, "POST", StringComparison.OrdinalIgnoreCase)) {
+                return incomingVerb;
+            }
+
+            string verbOverride = null;
+            string headerOverrideValue = request.Headers[XHttpMethodOverrideKey];
+            if (!String.IsNullOrEmpty(headerOverrideValue)) {
+                verbOverride = headerOverrideValue;
+            }
+            else {
+                string formOverrideValue = request.Form[XHttpMethodOverrideKey];
+                if (!String.IsNullOrEmpty(formOverrideValue)) {
+                    verbOverride = formOverrideValue;
+                }
+                else {
+                    string queryStringOverrideValue = request.QueryString[XHttpMethodOverrideKey];
+                    if (!String.IsNullOrEmpty(queryStringOverrideValue)) {
+                        verbOverride = queryStringOverrideValue;
+                    }
+                }
+            }
+            if (verbOverride != null) {
+                if (!String.Equals(verbOverride, "GET", StringComparison.OrdinalIgnoreCase) &&
+                    !String.Equals(verbOverride, "POST", StringComparison.OrdinalIgnoreCase)) {
+                    incomingVerb = verbOverride;
+                }
+            }
+            return incomingVerb;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/HttpStatusCodeResult.cs b/mcs/class/System.Web.Mvc3/Mvc/HttpStatusCodeResult.cs
new file mode 100644 (file)
index 0000000..d71b400
--- /dev/null
@@ -0,0 +1,34 @@
+namespace System.Web.Mvc {
+
+    public class HttpStatusCodeResult : ActionResult {
+        public HttpStatusCodeResult(int statusCode)
+            : this(statusCode, null) {
+        }
+
+        public HttpStatusCodeResult(int statusCode, string statusDescription) {
+            StatusCode = statusCode;
+            StatusDescription = statusDescription;
+        }
+
+        public int StatusCode {
+            get;
+            private set;
+        }
+
+        public string StatusDescription {
+            get;
+            private set;
+        }
+
+        public override void ExecuteResult(ControllerContext context) {
+            if (context == null) {
+                throw new ArgumentNullException("context");
+            }
+
+            context.HttpContext.Response.StatusCode = StatusCode;
+            if (StatusDescription != null) {
+                context.HttpContext.Response.StatusDescription = StatusDescription;
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/HttpUnauthorizedResult.cs b/mcs/class/System.Web.Mvc3/Mvc/HttpUnauthorizedResult.cs
new file mode 100644 (file)
index 0000000..2e5e6aa
--- /dev/null
@@ -0,0 +1,19 @@
+namespace System.Web.Mvc {
+
+    public class HttpUnauthorizedResult : HttpStatusCodeResult {
+
+        // HTTP 401 is the status code for unauthorized access. Other code might
+        // intercept this and perform some special logic. For example, the
+        // FormsAuthenticationModule looks for 401 responses and instead redirects
+        // the user to the login page.
+        private const int UnauthorizedCode = 401;
+
+        public HttpUnauthorizedResult()
+            : this(null) {
+        }
+
+        public HttpUnauthorizedResult(string statusDescription)
+            : base(UnauthorizedCode, statusDescription) {
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/HttpVerbs.cs b/mcs/class/System.Web.Mvc3/Mvc/HttpVerbs.cs
new file mode 100644 (file)
index 0000000..f616348
--- /dev/null
@@ -0,0 +1,12 @@
+namespace System.Web.Mvc {
+    using System;
+
+    [Flags]
+    public enum HttpVerbs {
+        Get = 1 << 0,
+        Post = 1 << 1,
+        Put = 1 << 2,
+        Delete = 1 << 3,
+        Head = 1 << 4
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/IActionFilter.cs b/mcs/class/System.Web.Mvc3/Mvc/IActionFilter.cs
new file mode 100644 (file)
index 0000000..fd0dd75
--- /dev/null
@@ -0,0 +1,7 @@
+namespace System.Web.Mvc {
+
+    public interface IActionFilter {
+        void OnActionExecuting(ActionExecutingContext filterContext);
+        void OnActionExecuted(ActionExecutedContext filterContext);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/IActionInvoker.cs b/mcs/class/System.Web.Mvc3/Mvc/IActionInvoker.cs
new file mode 100644 (file)
index 0000000..c6cff02
--- /dev/null
@@ -0,0 +1,6 @@
+namespace System.Web.Mvc {
+
+    public interface IActionInvoker {
+        bool InvokeAction(ControllerContext controllerContext, string actionName);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/IAuthorizationFilter.cs b/mcs/class/System.Web.Mvc3/Mvc/IAuthorizationFilter.cs
new file mode 100644 (file)
index 0000000..2207633
--- /dev/null
@@ -0,0 +1,6 @@
+namespace System.Web.Mvc {
+
+    public interface IAuthorizationFilter {
+        void OnAuthorization(AuthorizationContext filterContext);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/IBuildManager.cs b/mcs/class/System.Web.Mvc3/Mvc/IBuildManager.cs
new file mode 100644 (file)
index 0000000..c753a5b
--- /dev/null
@@ -0,0 +1,12 @@
+namespace System.Web.Mvc {
+    using System.Collections;
+    using System.IO;
+
+    internal interface IBuildManager {
+        bool FileExists(string virtualPath);
+        Type GetCompiledType(string virtualPath);
+        ICollection GetReferencedAssemblies();
+        Stream ReadCachedFile(string fileName);
+        Stream CreateCachedFile(string fileName);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/IClientValidatable.cs b/mcs/class/System.Web.Mvc3/Mvc/IClientValidatable.cs
new file mode 100644 (file)
index 0000000..d8e8e41
--- /dev/null
@@ -0,0 +1,17 @@
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+
+    // The purpose of this interface is to make something as supporting client-side
+    // validation, which could be discovered at runtime by whatever validation
+    // framework you're using. Because this interface is designed to be independent
+    // of underlying implementation details, where you apply this interface will
+    // depend on your specific validation framework.
+    //
+    // For DataAnnotations, you'll apply this interface to your validation attribute
+    // (the class which derives from ValidationAttribute). When you've implemented
+    // this interface, it will alleviate the need of writing a validator and registering
+    // it with the DataAnnotationsModelValidatorProvider.
+    public interface IClientValidatable {
+        IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/IController.cs b/mcs/class/System.Web.Mvc3/Mvc/IController.cs
new file mode 100644 (file)
index 0000000..221b433
--- /dev/null
@@ -0,0 +1,7 @@
+namespace System.Web.Mvc {
+    using System.Web.Routing;
+
+    public interface IController {
+        void Execute(RequestContext requestContext);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/IControllerActivator.cs b/mcs/class/System.Web.Mvc3/Mvc/IControllerActivator.cs
new file mode 100644 (file)
index 0000000..3d99ef9
--- /dev/null
@@ -0,0 +1,7 @@
+namespace System.Web.Mvc {
+    using System.Web.Routing;
+
+    public interface IControllerActivator {
+        IController Create(RequestContext requestContext, Type controllerType);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/IControllerFactory.cs b/mcs/class/System.Web.Mvc3/Mvc/IControllerFactory.cs
new file mode 100644 (file)
index 0000000..94f3d95
--- /dev/null
@@ -0,0 +1,10 @@
+namespace System.Web.Mvc {
+    using System.Web.Routing;
+    using System.Web.SessionState;
+
+    public interface IControllerFactory {
+        IController CreateController(RequestContext requestContext, string controllerName);
+        SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName);
+        void ReleaseController(IController controller);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/IDependencyResolver.cs b/mcs/class/System.Web.Mvc3/Mvc/IDependencyResolver.cs
new file mode 100644 (file)
index 0000000..326c4d9
--- /dev/null
@@ -0,0 +1,8 @@
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+
+    public interface IDependencyResolver {
+        object GetService(Type serviceType);
+        IEnumerable<object> GetServices(Type serviceType);
+    }
+}
\ No newline at end of file
diff --git a/mcs/class/System.Web.Mvc3/Mvc/IExceptionFilter.cs b/mcs/class/System.Web.Mvc3/Mvc/IExceptionFilter.cs
new file mode 100644 (file)
index 0000000..20d4344
--- /dev/null
@@ -0,0 +1,6 @@
+namespace System.Web.Mvc {
+
+    public interface IExceptionFilter {
+        void OnException(ExceptionContext filterContext);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/IFilterProvider.cs b/mcs/class/System.Web.Mvc3/Mvc/IFilterProvider.cs
new file mode 100644 (file)
index 0000000..63723ed
--- /dev/null
@@ -0,0 +1,7 @@
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+
+    public interface IFilterProvider {
+        IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/IMetadataAware.cs b/mcs/class/System.Web.Mvc3/Mvc/IMetadataAware.cs
new file mode 100644 (file)
index 0000000..a2cacb4
--- /dev/null
@@ -0,0 +1,10 @@
+namespace System.Web.Mvc {
+    // This interface is implemented by attributes which wish to contribute to the
+    // ModelMetadata creation process without needing to write a custom metadata
+    // provider. It is consumed by AssociatedMetadataProvider, so this behavior is
+    // automatically inherited by all classes which derive from it (notably, the
+    // DataAnnotationsModelMetadataProvider).
+    public interface IMetadataAware {
+        void OnMetadataCreated(ModelMetadata metadata);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/IModelBinder.cs b/mcs/class/System.Web.Mvc3/Mvc/IModelBinder.cs
new file mode 100644 (file)
index 0000000..1e1dde0
--- /dev/null
@@ -0,0 +1,6 @@
+namespace System.Web.Mvc {
+
+    public interface IModelBinder {
+        object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/IModelBinderProvider.cs b/mcs/class/System.Web.Mvc3/Mvc/IModelBinderProvider.cs
new file mode 100644 (file)
index 0000000..6820263
--- /dev/null
@@ -0,0 +1,6 @@
+namespace System.Web.Mvc {
+
+    public interface IModelBinderProvider {
+        IModelBinder GetBinder(Type modelType);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/IMvcControlBuilder.cs b/mcs/class/System.Web.Mvc3/Mvc/IMvcControlBuilder.cs
new file mode 100644 (file)
index 0000000..5211b0f
--- /dev/null
@@ -0,0 +1,5 @@
+namespace System.Web.Mvc {
+    internal interface IMvcControlBuilder {
+        string Inherits { set; }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/IMvcFilter.cs b/mcs/class/System.Web.Mvc3/Mvc/IMvcFilter.cs
new file mode 100644 (file)
index 0000000..c69955d
--- /dev/null
@@ -0,0 +1,6 @@
+namespace System.Web.Mvc {
+    public interface IMvcFilter {
+        bool AllowMultiple { get; }
+        int Order { get; }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/IResolver.cs b/mcs/class/System.Web.Mvc3/Mvc/IResolver.cs
new file mode 100644 (file)
index 0000000..dfa0271
--- /dev/null
@@ -0,0 +1,5 @@
+namespace System.Web.Mvc {
+    internal interface IResolver<T> {
+        T Current { get; }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/IResultFilter.cs b/mcs/class/System.Web.Mvc3/Mvc/IResultFilter.cs
new file mode 100644 (file)
index 0000000..73a5f0b
--- /dev/null
@@ -0,0 +1,7 @@
+namespace System.Web.Mvc {
+
+    public interface IResultFilter {
+        void OnResultExecuting(ResultExecutingContext filterContext);
+        void OnResultExecuted(ResultExecutedContext filterContext);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/IRouteWithArea.cs b/mcs/class/System.Web.Mvc3/Mvc/IRouteWithArea.cs
new file mode 100644 (file)
index 0000000..8128a3a
--- /dev/null
@@ -0,0 +1,9 @@
+namespace System.Web.Mvc {
+    using System;
+
+    public interface IRouteWithArea {
+
+        string Area { get; }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ITempDataProvider.cs b/mcs/class/System.Web.Mvc3/Mvc/ITempDataProvider.cs
new file mode 100644 (file)
index 0000000..4b3e52d
--- /dev/null
@@ -0,0 +1,8 @@
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+
+    public interface ITempDataProvider {
+        IDictionary<string, object> LoadTempData(ControllerContext controllerContext);
+        void SaveTempData(ControllerContext controllerContext, IDictionary<string, object> values);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/IUniquelyIdentifiable.cs b/mcs/class/System.Web.Mvc3/Mvc/IUniquelyIdentifiable.cs
new file mode 100644 (file)
index 0000000..5f32338
--- /dev/null
@@ -0,0 +1,5 @@
+namespace System.Web.Mvc {
+    internal interface IUniquelyIdentifiable {
+        string UniqueId { get; }
+    }
+}
\ No newline at end of file
diff --git a/mcs/class/System.Web.Mvc3/Mvc/IUnvalidatedRequestValues.cs b/mcs/class/System.Web.Mvc3/Mvc/IUnvalidatedRequestValues.cs
new file mode 100644 (file)
index 0000000..8cf2781
--- /dev/null
@@ -0,0 +1,13 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Specialized;
+    using System.Web;
+
+    // Used for mocking the UnvalidatedRequestValues type in System.Web.WebPages
+
+    internal interface IUnvalidatedRequestValues {
+        NameValueCollection Form { get; }
+        NameValueCollection QueryString { get; }
+        string this[string key] { get; }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/IUnvalidatedValueProvider.cs b/mcs/class/System.Web.Mvc3/Mvc/IUnvalidatedValueProvider.cs
new file mode 100644 (file)
index 0000000..129a3a1
--- /dev/null
@@ -0,0 +1,8 @@
+namespace System.Web.Mvc {
+    using System;
+
+    // Represents a special IValueProvider that has the ability to skip request validation.
+    public interface IUnvalidatedValueProvider : IValueProvider {
+        ValueProviderResult GetValue(string key, bool skipValidation);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/IValueProvider.cs b/mcs/class/System.Web.Mvc3/Mvc/IValueProvider.cs
new file mode 100644 (file)
index 0000000..c4dec89
--- /dev/null
@@ -0,0 +1,8 @@
+namespace System.Web.Mvc {
+    using System;
+
+    public interface IValueProvider {
+        bool ContainsPrefix(string prefix);
+        ValueProviderResult GetValue(string key);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/IView.cs b/mcs/class/System.Web.Mvc3/Mvc/IView.cs
new file mode 100644 (file)
index 0000000..af41043
--- /dev/null
@@ -0,0 +1,7 @@
+namespace System.Web.Mvc {
+    using System.IO;
+
+    public interface IView {
+        void Render(ViewContext viewContext, TextWriter writer);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/IViewDataContainer.cs b/mcs/class/System.Web.Mvc3/Mvc/IViewDataContainer.cs
new file mode 100644 (file)
index 0000000..a179a75
--- /dev/null
@@ -0,0 +1,8 @@
+namespace System.Web.Mvc {
+    using System.Diagnostics.CodeAnalysis;
+
+    public interface IViewDataContainer {
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "This is the mechanism by which the ViewPage / ViewUserControl get their ViewDataDictionary objects.")]
+        ViewDataDictionary ViewData { get; set; }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/IViewEngine.cs b/mcs/class/System.Web.Mvc3/Mvc/IViewEngine.cs
new file mode 100644 (file)
index 0000000..ee5c992
--- /dev/null
@@ -0,0 +1,8 @@
+namespace System.Web.Mvc {
+
+    public interface IViewEngine {
+        ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache);
+        ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache);
+        void ReleaseView(ControllerContext controllerContext, IView view);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/IViewLocationCache.cs b/mcs/class/System.Web.Mvc3/Mvc/IViewLocationCache.cs
new file mode 100644 (file)
index 0000000..ca62b47
--- /dev/null
@@ -0,0 +1,8 @@
+namespace System.Web.Mvc {
+    using System.Web;
+
+    public interface IViewLocationCache {
+        string GetViewLocation(HttpContextBase httpContext, string key);
+        void InsertViewLocation(HttpContextBase httpContext, string key, string virtualPath);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/IViewPageActivator.cs b/mcs/class/System.Web.Mvc3/Mvc/IViewPageActivator.cs
new file mode 100644 (file)
index 0000000..9f8bd9f
--- /dev/null
@@ -0,0 +1,6 @@
+namespace System.Web.Mvc {
+
+    public interface IViewPageActivator {
+        object Create(ControllerContext controllerContext, Type type);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/IViewStartPageChild.cs b/mcs/class/System.Web.Mvc3/Mvc/IViewStartPageChild.cs
new file mode 100644 (file)
index 0000000..2cfedc5
--- /dev/null
@@ -0,0 +1,8 @@
+namespace System.Web.Mvc {
+
+    internal interface IViewStartPageChild {
+        HtmlHelper<object> Html { get; }
+        UrlHelper Url { get; }
+        ViewContext ViewContext { get; }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/InputType.cs b/mcs/class/System.Web.Mvc3/Mvc/InputType.cs
new file mode 100644 (file)
index 0000000..eb14a1b
--- /dev/null
@@ -0,0 +1,9 @@
+namespace System.Web.Mvc {
+    public enum InputType {
+        CheckBox,
+        Hidden,
+        Password,
+        Radio,
+        Text
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/JavaScriptResult.cs b/mcs/class/System.Web.Mvc3/Mvc/JavaScriptResult.cs
new file mode 100644 (file)
index 0000000..b3e7d54
--- /dev/null
@@ -0,0 +1,24 @@
+namespace System.Web.Mvc {
+    using System;
+
+    public class JavaScriptResult : ActionResult {
+
+        public string Script {
+            get;
+            set;
+        }
+
+        public override void ExecuteResult(ControllerContext context) {
+            if (context == null) {
+                throw new ArgumentNullException("context");
+            }
+
+            HttpResponseBase response = context.HttpContext.Response;
+            response.ContentType = "application/x-javascript";
+
+            if (Script != null) {
+                response.Write(Script);
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/JsonRequestBehavior.cs b/mcs/class/System.Web.Mvc3/Mvc/JsonRequestBehavior.cs
new file mode 100644 (file)
index 0000000..e040dbb
--- /dev/null
@@ -0,0 +1,6 @@
+namespace System.Web.Mvc {
+    public enum JsonRequestBehavior {
+        AllowGet,
+        DenyGet,
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/JsonResult.cs b/mcs/class/System.Web.Mvc3/Mvc/JsonResult.cs
new file mode 100644 (file)
index 0000000..b5b8f61
--- /dev/null
@@ -0,0 +1,60 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Text;
+    using System.Web;
+    using System.Web.Mvc.Resources;
+    using System.Web.Script.Serialization;
+
+    public class JsonResult : ActionResult {
+
+        public JsonResult() {
+            JsonRequestBehavior = JsonRequestBehavior.DenyGet;
+        }
+
+        public Encoding ContentEncoding {
+            get;
+            set;
+        }
+
+        public string ContentType {
+            get;
+            set;
+        }
+
+        public object Data {
+            get;
+            set;
+        }
+
+        public JsonRequestBehavior JsonRequestBehavior {
+            get;
+            set;
+        }
+
+        public override void ExecuteResult(ControllerContext context) {
+            if (context == null) {
+                throw new ArgumentNullException("context");
+            }
+            if (JsonRequestBehavior == JsonRequestBehavior.DenyGet &&
+                String.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase)) {
+                throw new InvalidOperationException(MvcResources.JsonRequest_GetNotAllowed);
+            }
+
+            HttpResponseBase response = context.HttpContext.Response;
+
+            if (!String.IsNullOrEmpty(ContentType)) {
+                response.ContentType = ContentType;
+            }
+            else {
+                response.ContentType = "application/json";
+            }
+            if (ContentEncoding != null) {
+                response.ContentEncoding = ContentEncoding;
+            }
+            if (Data != null) {
+                JavaScriptSerializer serializer = new JavaScriptSerializer();
+                response.Write(serializer.Serialize(Data));
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/JsonValueProviderFactory.cs b/mcs/class/System.Web.Mvc3/Mvc/JsonValueProviderFactory.cs
new file mode 100644 (file)
index 0000000..f3e6056
--- /dev/null
@@ -0,0 +1,73 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Globalization;
+    using System.IO;
+    using System.Web.Script.Serialization;
+
+    public sealed class JsonValueProviderFactory : ValueProviderFactory {
+
+        private static void AddToBackingStore(Dictionary<string, object> backingStore, string prefix, object value) {
+            IDictionary<string, object> d = value as IDictionary<string, object>;
+            if (d != null) {
+                foreach (KeyValuePair<string, object> entry in d) {
+                    AddToBackingStore(backingStore, MakePropertyKey(prefix, entry.Key), entry.Value);
+                }
+                return;
+            }
+
+            IList l = value as IList;
+            if (l != null) {
+                for (int i = 0; i < l.Count; i++) {
+                    AddToBackingStore(backingStore, MakeArrayKey(prefix, i), l[i]);
+                }
+                return;
+            }
+
+            // primitive
+            backingStore[prefix] = value;
+        }
+
+        private static object GetDeserializedObject(ControllerContext controllerContext) {
+            if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase)) {
+                // not JSON request
+                return null;
+            }
+
+            StreamReader reader = new StreamReader(controllerContext.HttpContext.Request.InputStream);
+            string bodyText = reader.ReadToEnd();
+            if (String.IsNullOrEmpty(bodyText)) {
+                // no JSON data
+                return null;
+            }
+
+            JavaScriptSerializer serializer = new JavaScriptSerializer();
+            object jsonData = serializer.DeserializeObject(bodyText);
+            return jsonData;
+        }
+
+        public override IValueProvider GetValueProvider(ControllerContext controllerContext) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+
+            object jsonData = GetDeserializedObject(controllerContext);
+            if (jsonData == null) {
+                return null;
+            }
+
+            Dictionary<string, object> backingStore = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
+            AddToBackingStore(backingStore, String.Empty, jsonData);
+            return new DictionaryValueProvider<object>(backingStore, CultureInfo.CurrentCulture);
+        }
+
+        private static string MakeArrayKey(string prefix, int index) {
+            return prefix + "[" + index.ToString(CultureInfo.InvariantCulture) + "]";
+        }
+
+        private static string MakePropertyKey(string prefix, string propertyName) {
+            return (String.IsNullOrEmpty(prefix)) ? propertyName : prefix + "." + propertyName;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/LinqBinaryModelBinder.cs b/mcs/class/System.Web.Mvc3/Mvc/LinqBinaryModelBinder.cs
new file mode 100644 (file)
index 0000000..9c5aef0
--- /dev/null
@@ -0,0 +1,14 @@
+namespace System.Web.Mvc {
+    using System.Data.Linq;
+
+    public class LinqBinaryModelBinder : ByteArrayModelBinder {
+        public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {
+            byte[] byteValue = (byte[])base.BindModel(controllerContext, bindingContext);
+            if (byteValue == null) {
+                return null;
+            }
+
+            return new Binary(byteValue);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ModelBinderAttribute.cs b/mcs/class/System.Web.Mvc3/Mvc/ModelBinderAttribute.cs
new file mode 100644 (file)
index 0000000..b466c55
--- /dev/null
@@ -0,0 +1,42 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Globalization;
+    using System.Web.Mvc.Resources;
+
+    [AttributeUsage(ValidTargets, AllowMultiple = false, Inherited = false)]
+    public sealed class ModelBinderAttribute : CustomModelBinderAttribute {
+
+        public ModelBinderAttribute(Type binderType) {
+            if (binderType == null) {
+                throw new ArgumentNullException("binderType");
+            }
+            if (!typeof(IModelBinder).IsAssignableFrom(binderType)) {
+                string message = String.Format(CultureInfo.CurrentCulture,
+                    MvcResources.ModelBinderAttribute_TypeNotIModelBinder, binderType.FullName);
+                throw new ArgumentException(message, "binderType");
+            }
+
+            BinderType = binderType;
+        }
+
+        public Type BinderType {
+            get;
+            private set;
+        }
+
+        public override IModelBinder GetBinder() {
+            try {
+                return (IModelBinder)Activator.CreateInstance(BinderType);
+            }
+            catch (Exception ex) {
+                throw new InvalidOperationException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.ModelBinderAttribute_ErrorCreatingModelBinder,
+                        BinderType.FullName),
+                    ex);
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ModelBinderDictionary.cs b/mcs/class/System.Web.Mvc3/Mvc/ModelBinderDictionary.cs
new file mode 100644 (file)
index 0000000..900569f
--- /dev/null
@@ -0,0 +1,152 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Globalization;
+    using System.Web.Mvc.Resources;
+
+    public class ModelBinderDictionary : IDictionary<Type, IModelBinder> {
+
+        private IModelBinder _defaultBinder;
+        private readonly Dictionary<Type, IModelBinder> _innerDictionary = new Dictionary<Type, IModelBinder>();
+        private ModelBinderProviderCollection _modelBinderProviders;
+
+        public ModelBinderDictionary()
+            : this(ModelBinderProviders.BinderProviders) {
+        }
+
+        internal ModelBinderDictionary(ModelBinderProviderCollection modelBinderProviders) {
+            _modelBinderProviders = modelBinderProviders;
+        }
+
+        public int Count {
+            get {
+                return _innerDictionary.Count;
+            }
+        }
+
+        public IModelBinder DefaultBinder {
+            get {
+                if (_defaultBinder == null) {
+                    _defaultBinder = new DefaultModelBinder();
+                }
+                return _defaultBinder;
+            }
+            set {
+                _defaultBinder = value;
+            }
+        }
+
+        public bool IsReadOnly {
+            get {
+                return ((IDictionary<Type, IModelBinder>)_innerDictionary).IsReadOnly;
+            }
+        }
+
+        public ICollection<Type> Keys {
+            get {
+                return _innerDictionary.Keys;
+            }
+        }
+
+        public IModelBinder this[Type key] {
+            get {
+
+                IModelBinder binder;
+                _innerDictionary.TryGetValue(key, out binder);
+                return binder;
+            }
+            set {
+                _innerDictionary[key] = value;
+            }
+        }
+
+        public ICollection<IModelBinder> Values {
+            get {
+                return _innerDictionary.Values;
+            }
+        }
+
+        public void Add(KeyValuePair<Type, IModelBinder> item) {
+            ((IDictionary<Type, IModelBinder>)_innerDictionary).Add(item);
+        }
+
+        public void Add(Type key, IModelBinder value) {
+            _innerDictionary.Add(key, value);
+        }
+
+        public void Clear() {
+            _innerDictionary.Clear();
+        }
+
+        public bool Contains(KeyValuePair<Type, IModelBinder> item) {
+            return ((IDictionary<Type, IModelBinder>)_innerDictionary).Contains(item);
+        }
+
+        public bool ContainsKey(Type key) {
+            return _innerDictionary.ContainsKey(key);
+        }
+
+        public void CopyTo(KeyValuePair<Type, IModelBinder>[] array, int arrayIndex) {
+            ((IDictionary<Type, IModelBinder>)_innerDictionary).CopyTo(array, arrayIndex);
+        }
+
+        public IModelBinder GetBinder(Type modelType) {
+            return GetBinder(modelType, true /* fallbackToDefault */);
+        }
+
+        public virtual IModelBinder GetBinder(Type modelType, bool fallbackToDefault) {
+            if (modelType == null) {
+                throw new ArgumentNullException("modelType");
+            }
+
+            return GetBinder(modelType, (fallbackToDefault) ? DefaultBinder : null);
+        }
+
+        private IModelBinder GetBinder(Type modelType, IModelBinder fallbackBinder) {
+
+            // Try to look up a binder for this type. We use this order of precedence:
+            // 1. Binder returned from provider
+            // 2. Binder registered in the global table
+            // 3. Binder attribute defined on the type
+            // 4. Supplied fallback binder
+
+            IModelBinder binder = _modelBinderProviders.GetBinder(modelType);
+            if (binder != null) {
+                return binder;
+            }
+
+            if (_innerDictionary.TryGetValue(modelType, out binder)) {
+                return binder;
+            }
+
+            binder = ModelBinders.GetBinderFromAttributes(modelType,
+                () => String.Format(CultureInfo.CurrentCulture, MvcResources.ModelBinderDictionary_MultipleAttributes, modelType.FullName));
+
+            return binder ?? fallbackBinder;
+        }
+
+        public IEnumerator<KeyValuePair<Type, IModelBinder>> GetEnumerator() {
+            return _innerDictionary.GetEnumerator();
+        }
+
+        public bool Remove(KeyValuePair<Type, IModelBinder> item) {
+            return ((IDictionary<Type, IModelBinder>)_innerDictionary).Remove(item);
+        }
+
+        public bool Remove(Type key) {
+            return _innerDictionary.Remove(key);
+        }
+
+        public bool TryGetValue(Type key, out IModelBinder value) {
+            return _innerDictionary.TryGetValue(key, out value);
+        }
+
+        #region IEnumerable Members
+        IEnumerator IEnumerable.GetEnumerator() {
+            return ((IEnumerable)_innerDictionary).GetEnumerator();
+        }
+        #endregion
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ModelBinderProviderCollection.cs b/mcs/class/System.Web.Mvc3/Mvc/ModelBinderProviderCollection.cs
new file mode 100644 (file)
index 0000000..9b6cb77
--- /dev/null
@@ -0,0 +1,58 @@
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+    using System.Collections.ObjectModel;
+    using System.Linq;
+
+    public class ModelBinderProviderCollection : Collection<IModelBinderProvider> {
+
+        private IResolver<IEnumerable<IModelBinderProvider>> _serviceResolver;
+
+        public ModelBinderProviderCollection() {
+            _serviceResolver = new MultiServiceResolver<IModelBinderProvider>(() => Items);
+        }
+
+        public ModelBinderProviderCollection(IList<IModelBinderProvider> list)
+            : base(list) {
+            _serviceResolver = new MultiServiceResolver<IModelBinderProvider>(() => Items);
+        }
+
+        internal ModelBinderProviderCollection(IResolver<IEnumerable<IModelBinderProvider>> resolver, params IModelBinderProvider[] providers)
+            : base(providers) {
+            _serviceResolver = resolver ?? new MultiServiceResolver<IModelBinderProvider>(() => Items);
+        }
+
+        private IEnumerable<IModelBinderProvider> CombinedItems {
+            get {
+                return _serviceResolver.Current;
+            }
+        }
+
+        protected override void InsertItem(int index, IModelBinderProvider item) {
+            if (item == null) {
+                throw new ArgumentNullException("item");
+            }
+            base.InsertItem(index, item);
+        }
+
+        protected override void SetItem(int index, IModelBinderProvider item) {
+            if (item == null) {
+                throw new ArgumentNullException("item");
+            }
+            base.SetItem(index, item);
+        }
+
+        public IModelBinder GetBinder(Type modelType) {
+
+            if (modelType == null) {
+                throw new ArgumentNullException("modelType");
+            }
+
+            var modelBinders = from providers in CombinedItems
+                               let modelBinder = providers.GetBinder(modelType)
+                               where modelBinder != null
+                               select modelBinder;
+
+            return modelBinders.FirstOrDefault();
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ModelBinderProviders.cs b/mcs/class/System.Web.Mvc3/Mvc/ModelBinderProviders.cs
new file mode 100644 (file)
index 0000000..238cd95
--- /dev/null
@@ -0,0 +1,14 @@
+namespace System.Web.Mvc {
+
+    public static class ModelBinderProviders {
+
+        private readonly static ModelBinderProviderCollection _binderProviders = new ModelBinderProviderCollection {
+        };
+
+        public static ModelBinderProviderCollection BinderProviders {
+            get {
+                return _binderProviders;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ModelBinders.cs b/mcs/class/System.Web.Mvc3/Mvc/ModelBinders.cs
new file mode 100644 (file)
index 0000000..43549a1
--- /dev/null
@@ -0,0 +1,65 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.ComponentModel;
+    using System.Data.Linq;
+    using System.Linq;
+    using System.Reflection;
+    using System.Web;
+
+    public static class ModelBinders {
+
+        private static readonly ModelBinderDictionary _binders = CreateDefaultBinderDictionary();
+
+        public static ModelBinderDictionary Binders {
+            get {
+                return _binders;
+            }
+        }
+
+        internal static IModelBinder GetBinderFromAttributes(Type type, Func<string> errorMessageAccessor) {
+            AttributeCollection allAttrs = TypeDescriptorHelper.Get(type).GetAttributes();
+            CustomModelBinderAttribute[] filteredAttrs = allAttrs.OfType<CustomModelBinderAttribute>().ToArray();
+            return GetBinderFromAttributesImpl(filteredAttrs, errorMessageAccessor);
+        }
+
+        internal static IModelBinder GetBinderFromAttributes(ICustomAttributeProvider element, Func<string> errorMessageAccessor) {
+            CustomModelBinderAttribute[] attrs = (CustomModelBinderAttribute[])element.GetCustomAttributes(typeof(CustomModelBinderAttribute), true /* inherit */);
+            return GetBinderFromAttributesImpl(attrs, errorMessageAccessor);
+        }
+
+        private static IModelBinder GetBinderFromAttributesImpl(CustomModelBinderAttribute[] attrs, Func<string> errorMessageAccessor) {
+            // this method is used to get a custom binder based on the attributes of the element passed to it.
+            // it will return null if a binder cannot be detected based on the attributes alone.
+
+            if (attrs == null) {
+                return null;
+            }
+
+            switch (attrs.Length) {
+                case 0:
+                    return null;
+
+                case 1:
+                    IModelBinder binder = attrs[0].GetBinder();
+                    return binder;
+
+                default:
+                    string errorMessage = errorMessageAccessor();
+                    throw new InvalidOperationException(errorMessage);
+            }
+        }
+
+        private static ModelBinderDictionary CreateDefaultBinderDictionary() {
+            // We can't add a binder to the HttpPostedFileBase type as an attribute, so we'll just
+            // prepopulate the dictionary as a convenience to users.
+
+            ModelBinderDictionary binders = new ModelBinderDictionary() {
+                { typeof(HttpPostedFileBase), new HttpPostedFileBaseModelBinder() },
+                { typeof(byte[]), new ByteArrayModelBinder() },
+                { typeof(Binary), new LinqBinaryModelBinder() }
+            };
+            return binders;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ModelBindingContext.cs b/mcs/class/System.Web.Mvc3/Mvc/ModelBindingContext.cs
new file mode 100644 (file)
index 0000000..1c75181
--- /dev/null
@@ -0,0 +1,141 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq;
+    using System.Web.Mvc.Resources;
+
+    public class ModelBindingContext {
+
+        private static readonly Predicate<string> _defaultPropertyFilter = _ => true;
+
+        private string _modelName;
+        private ModelStateDictionary _modelState;
+        private Predicate<string> _propertyFilter;
+        private Dictionary<string, ModelMetadata> _propertyMetadata;
+
+        public ModelBindingContext()
+            : this(null) {
+        }
+
+        // copies certain values that won't change between parent and child objects,
+        // e.g. ValueProvider, ModelState
+        public ModelBindingContext(ModelBindingContext bindingContext) {
+            if (bindingContext != null) {
+                ModelState = bindingContext.ModelState;
+                ValueProvider = bindingContext.ValueProvider;
+            }
+        }
+
+        public bool FallbackToEmptyPrefix {
+            get;
+            set;
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "value", Justification = "Cannot remove setter as that's a breaking change")]
+        public object Model {
+            get {
+                return ModelMetadata.Model;
+            }
+            set {
+                throw new InvalidOperationException(MvcResources.ModelMetadata_PropertyNotSettable);
+            }
+        }
+
+        public ModelMetadata ModelMetadata {
+            get;
+            set;
+        }
+
+        public string ModelName {
+            get {
+                if (_modelName == null) {
+                    _modelName = String.Empty;
+                }
+                return _modelName;
+            }
+            set {
+                _modelName = value;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "The containing type is mutable.")]
+        public ModelStateDictionary ModelState {
+            get {
+                if (_modelState == null) {
+                    _modelState = new ModelStateDictionary();
+                }
+                return _modelState;
+            }
+            set {
+                _modelState = value;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "value", Justification = "Cannot remove setter as that's a breaking change")]
+        public Type ModelType {
+            get {
+                return ModelMetadata.ModelType;
+            }
+            set {
+                throw new InvalidOperationException(MvcResources.ModelMetadata_PropertyNotSettable);
+            }
+        }
+
+        public Predicate<string> PropertyFilter {
+            get {
+                if (_propertyFilter == null) {
+                    _propertyFilter = _defaultPropertyFilter;
+                }
+                return _propertyFilter;
+            }
+            set {
+                _propertyFilter = value;
+            }
+        }
+
+        public IDictionary<string, ModelMetadata> PropertyMetadata {
+            get {
+                if (_propertyMetadata == null) {
+                    _propertyMetadata = ModelMetadata.Properties.ToDictionary(m => m.PropertyName, StringComparer.OrdinalIgnoreCase);
+                }
+
+                return _propertyMetadata;
+            }
+        }
+
+        public IValueProvider ValueProvider {
+            get;
+            set;
+        }
+
+        internal IUnvalidatedValueProvider UnvalidatedValueProvider {
+            get {
+                return (ValueProvider as IUnvalidatedValueProvider) ?? new UnvalidatedValueProviderWrapper(ValueProvider);
+            }
+        }
+
+        // Used to wrap an IValueProvider in an IUnvalidatedValueProvider
+        private sealed class UnvalidatedValueProviderWrapper : IValueProvider, IUnvalidatedValueProvider {
+            private readonly IValueProvider _backingProvider;
+
+            public UnvalidatedValueProviderWrapper(IValueProvider backingProvider) {
+                _backingProvider = backingProvider;
+            }
+
+            public ValueProviderResult GetValue(string key, bool skipValidation) {
+                // 'skipValidation' isn't understood by the backing provider and can be ignored
+                return GetValue(key);
+            }
+
+            public bool ContainsPrefix(string prefix) {
+                return _backingProvider.ContainsPrefix(prefix);
+            }
+
+            public ValueProviderResult GetValue(string key) {
+                return _backingProvider.GetValue(key);
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ModelClientValidationEqualToRule.cs b/mcs/class/System.Web.Mvc3/Mvc/ModelClientValidationEqualToRule.cs
new file mode 100644 (file)
index 0000000..5dc365c
--- /dev/null
@@ -0,0 +1,9 @@
+namespace System.Web.Mvc {
+    public class ModelClientValidationEqualToRule: ModelClientValidationRule {
+        public ModelClientValidationEqualToRule(string errorMessage, object other){
+            ErrorMessage = errorMessage;
+            ValidationType = "equalto";
+            ValidationParameters["other"] = other;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ModelClientValidationRangeRule.cs b/mcs/class/System.Web.Mvc3/Mvc/ModelClientValidationRangeRule.cs
new file mode 100644 (file)
index 0000000..647e21f
--- /dev/null
@@ -0,0 +1,10 @@
+namespace System.Web.Mvc {
+    public class ModelClientValidationRangeRule : ModelClientValidationRule {
+        public ModelClientValidationRangeRule(string errorMessage, object minValue, object maxValue) {
+            ErrorMessage = errorMessage;
+            ValidationType = "range";
+            ValidationParameters["min"] = minValue;
+            ValidationParameters["max"] = maxValue;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ModelClientValidationRegexRule.cs b/mcs/class/System.Web.Mvc3/Mvc/ModelClientValidationRegexRule.cs
new file mode 100644 (file)
index 0000000..8efbfe1
--- /dev/null
@@ -0,0 +1,9 @@
+namespace System.Web.Mvc {
+    public class ModelClientValidationRegexRule : ModelClientValidationRule {
+        public ModelClientValidationRegexRule(string errorMessage, string pattern) {
+            ErrorMessage = errorMessage;
+            ValidationType = "regex";
+            ValidationParameters.Add("pattern", pattern);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ModelClientValidationRemoteRule.cs b/mcs/class/System.Web.Mvc3/Mvc/ModelClientValidationRemoteRule.cs
new file mode 100644 (file)
index 0000000..e292e62
--- /dev/null
@@ -0,0 +1,19 @@
+namespace System.Web.Mvc {
+    using System.Diagnostics.CodeAnalysis;
+
+    public class ModelClientValidationRemoteRule : ModelClientValidationRule {
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", Justification = "The value is a not a regular URL since it may contain ~/ ASP.NET-specific characters")]
+        public ModelClientValidationRemoteRule(string errorMessage, string url, string httpMethod, string additionalFields) {
+            ErrorMessage = errorMessage;
+            ValidationType = "remote";
+            ValidationParameters["url"] = url;
+
+            if (!string.IsNullOrEmpty(httpMethod)) {
+                ValidationParameters["type"] = httpMethod;
+            }
+
+            ValidationParameters["additionalfields"] = additionalFields;
+        }
+    }
+}
\ No newline at end of file
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ModelClientValidationRequiredRule.cs b/mcs/class/System.Web.Mvc3/Mvc/ModelClientValidationRequiredRule.cs
new file mode 100644 (file)
index 0000000..0df7ea0
--- /dev/null
@@ -0,0 +1,8 @@
+namespace System.Web.Mvc {
+    public class ModelClientValidationRequiredRule : ModelClientValidationRule {
+        public ModelClientValidationRequiredRule(string errorMessage) {
+            ErrorMessage = errorMessage;
+            ValidationType = "required";
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ModelClientValidationRule.cs b/mcs/class/System.Web.Mvc3/Mvc/ModelClientValidationRule.cs
new file mode 100644 (file)
index 0000000..a3dfbd4
--- /dev/null
@@ -0,0 +1,31 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+
+    public class ModelClientValidationRule {
+
+        private readonly Dictionary<string, object> _validationParameters = new Dictionary<string, object>();
+        private string _validationType;
+
+        public string ErrorMessage {
+            get;
+            set;
+        }
+
+        public IDictionary<string, object> ValidationParameters {
+            get {
+                return _validationParameters;
+            }
+        }
+
+        public string ValidationType {
+            get {
+                return _validationType ?? String.Empty;
+            }
+            set {
+                _validationType = value;
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ModelClientValidationStringLengthRule.cs b/mcs/class/System.Web.Mvc3/Mvc/ModelClientValidationStringLengthRule.cs
new file mode 100644 (file)
index 0000000..d521fc8
--- /dev/null
@@ -0,0 +1,16 @@
+namespace System.Web.Mvc {
+    public class ModelClientValidationStringLengthRule : ModelClientValidationRule {
+        public ModelClientValidationStringLengthRule(string errorMessage, int minimumLength, int maximumLength) {
+            ErrorMessage = errorMessage;
+            ValidationType = "length";
+
+            if (minimumLength != 0) {
+                ValidationParameters["min"] = minimumLength;
+            }
+
+            if (maximumLength != Int32.MaxValue) {
+                ValidationParameters["max"] = maximumLength;
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ModelError.cs b/mcs/class/System.Web.Mvc3/Mvc/ModelError.cs
new file mode 100644 (file)
index 0000000..c5f7666
--- /dev/null
@@ -0,0 +1,34 @@
+namespace System.Web.Mvc {
+    using System;
+
+    [Serializable]
+    public class ModelError {
+
+        public ModelError(Exception exception)
+            : this(exception, null /* errorMessage */) {
+        }
+
+        public ModelError(Exception exception, string errorMessage)
+            : this(errorMessage) {
+            if (exception == null) {
+                throw new ArgumentNullException("exception");
+            }
+
+            Exception = exception;
+        }
+
+        public ModelError(string errorMessage) {
+            ErrorMessage = errorMessage ?? String.Empty;
+        }
+
+        public Exception Exception {
+            get;
+            private set;
+        }
+
+        public string ErrorMessage {
+            get;
+            private set;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ModelErrorCollection.cs b/mcs/class/System.Web.Mvc3/Mvc/ModelErrorCollection.cs
new file mode 100644 (file)
index 0000000..e431a09
--- /dev/null
@@ -0,0 +1,16 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.ObjectModel;
+
+    [Serializable]
+    public class ModelErrorCollection : Collection<ModelError> {
+
+        public void Add(Exception exception) {
+            Add(new ModelError(exception));
+        }
+
+        public void Add(string errorMessage) {
+            Add(new ModelError(errorMessage));
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ModelMetadata.cs b/mcs/class/System.Web.Mvc3/Mvc/ModelMetadata.cs
new file mode 100644 (file)
index 0000000..5faa387
--- /dev/null
@@ -0,0 +1,401 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.ComponentModel;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Linq;
+    using System.Linq.Expressions;
+    using System.Reflection;
+    using System.Web.Mvc.ExpressionUtil;
+    using System.Web.Mvc.Resources;
+
+    public class ModelMetadata {
+        public const int DefaultOrder = 10000;
+
+        // Explicit backing store for the things we want initialized by default, so don't have to call
+        // the protected virtual setters of an auto-generated property
+        private Dictionary<string, object> _additionalValues = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
+        private readonly Type _containerType;
+        private bool _convertEmptyStringToNull = true;
+        private bool _isRequired;
+        private object _model;
+        private Func<object> _modelAccessor;
+        private readonly Type _modelType;
+        private int _order = DefaultOrder;
+        private IEnumerable<ModelMetadata> _properties;
+        private readonly string _propertyName;
+        private Type _realModelType;
+        private bool _requestValidationEnabled = true;
+        private bool _showForDisplay = true;
+        private bool _showForEdit = true;
+        private string _simpleDisplayText;
+
+        public ModelMetadata(ModelMetadataProvider provider, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName) {
+            if (provider == null) {
+                throw new ArgumentNullException("provider");
+            }
+            if (modelType == null) {
+                throw new ArgumentNullException("modelType");
+            }
+
+            Provider = provider;
+
+            _containerType = containerType;
+            _isRequired = !TypeHelpers.TypeAllowsNullValue(modelType);
+            _modelAccessor = modelAccessor;
+            _modelType = modelType;
+            _propertyName = propertyName;
+        }
+
+        public virtual Dictionary<string, object> AdditionalValues {
+            get {
+                return _additionalValues;
+            }
+        }
+
+        public Type ContainerType {
+            get {
+                return _containerType;
+            }
+        }
+
+        public virtual bool ConvertEmptyStringToNull {
+            get {
+                return _convertEmptyStringToNull;
+            }
+            set {
+                _convertEmptyStringToNull = value;
+            }
+        }
+
+        public virtual string DataTypeName {
+            get;
+            set;
+        }
+
+        public virtual string Description {
+            get;
+            set;
+        }
+
+        public virtual string DisplayFormatString {
+            get;
+            set;
+        }
+
+        [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Justification = "The method is a delegating helper to choose among multiple property values")]
+        public virtual string DisplayName {
+            get;
+            set;
+        }
+
+        public virtual string EditFormatString {
+            get;
+            set;
+        }
+
+        public virtual bool HideSurroundingHtml {
+            get;
+            set;
+        }
+
+        public virtual bool IsComplexType {
+            get {
+                return !(TypeDescriptor.GetConverter(ModelType).CanConvertFrom(typeof(string)));
+            }
+        }
+
+        public bool IsNullableValueType {
+            get {
+                return TypeHelpers.IsNullableValueType(ModelType);
+            }
+        }
+
+        public virtual bool IsReadOnly {
+            get;
+            set;
+        }
+
+        public virtual bool IsRequired {
+            get {
+                return _isRequired;
+            }
+            set {
+                _isRequired = value;
+            }
+        }
+
+        public object Model {
+            get {
+                if (_modelAccessor != null) {
+                    _model = _modelAccessor();
+                    _modelAccessor = null;
+                }
+                return _model;
+            }
+            set {
+                _model = value;
+                _modelAccessor = null;
+                _properties = null;
+                _realModelType = null;
+            }
+        }
+
+        public Type ModelType {
+            get {
+                return _modelType;
+            }
+        }
+
+        public virtual string NullDisplayText {
+            get;
+            set;
+        }
+
+        public virtual int Order {
+            get {
+                return _order;
+            }
+            set {
+                _order = value;
+            }
+        }
+
+        public virtual IEnumerable<ModelMetadata> Properties {
+            get {
+                if (_properties == null) {
+                    _properties = Provider.GetMetadataForProperties(Model, RealModelType).OrderBy(m => m.Order);
+                }
+                return _properties;
+            }
+        }
+
+        public string PropertyName {
+            get {
+                return _propertyName;
+            }
+        }
+
+        protected ModelMetadataProvider Provider {
+            get;
+            set;
+        }
+
+        internal Type RealModelType {
+            get {
+                if (_realModelType == null) {
+                    _realModelType = ModelType;
+
+                    // Don't call GetType() if the model is Nullable<T>, because it will
+                    // turn Nullable<T> into T for non-null values
+                    if (Model != null && !TypeHelpers.IsNullableValueType(ModelType)) {
+                        _realModelType = Model.GetType();
+                    }
+                }
+
+                return _realModelType;
+            }
+        }
+
+        public virtual bool RequestValidationEnabled {
+            get {
+                return _requestValidationEnabled;
+            }
+            set {
+                _requestValidationEnabled = value;
+            }
+        }
+
+        public virtual string ShortDisplayName {
+            get;
+            set;
+        }
+
+        public virtual bool ShowForDisplay {
+            get {
+                return _showForDisplay;
+            }
+            set {
+                _showForDisplay = value;
+            }
+        }
+
+        public virtual bool ShowForEdit {
+            get {
+                return _showForEdit;
+            }
+            set {
+                _showForEdit = value;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Justification = "This property delegates to the method when the user has not yet set a simple display text value.")]
+        public virtual string SimpleDisplayText {
+            get {
+                if (_simpleDisplayText == null) {
+                    _simpleDisplayText = GetSimpleDisplayText();
+                }
+                return _simpleDisplayText;
+            }
+            set {
+                _simpleDisplayText = value;
+            }
+        }
+
+        public virtual string TemplateHint {
+            get;
+            set;
+        }
+
+        public virtual string Watermark {
+            get;
+            set;
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
+        public static ModelMetadata FromLambdaExpression<TParameter, TValue>(Expression<Func<TParameter, TValue>> expression,
+                                                                             ViewDataDictionary<TParameter> viewData) {
+            if (expression == null) {
+                throw new ArgumentNullException("expression");
+            }
+            if (viewData == null) {
+                throw new ArgumentNullException("viewData");
+            }
+
+            string propertyName = null;
+            Type containerType = null;
+            bool legalExpression = false;
+
+            // Need to verify the expression is valid; it needs to at least end in something
+            // that we can convert to a meaningful string for model binding purposes
+
+            switch (expression.Body.NodeType) {
+                // ArrayIndex always means a single-dimensional indexer; multi-dimensional indexer is a method call to Get()
+                case ExpressionType.ArrayIndex:
+                    legalExpression = true;
+                    break;
+
+                // Only legal method call is a single argument indexer/DefaultMember call
+                case ExpressionType.Call:
+                    legalExpression = ExpressionHelper.IsSingleArgumentIndexer(expression.Body);
+                    break;
+
+                // Property/field access is always legal
+                case ExpressionType.MemberAccess:
+                    MemberExpression memberExpression = (MemberExpression)expression.Body;
+                    propertyName = memberExpression.Member is PropertyInfo ? memberExpression.Member.Name : null;
+                    containerType = memberExpression.Expression.Type;
+                    legalExpression = true;
+                    break;
+
+                // Parameter expression means "model => model", so we delegate to FromModel
+                case ExpressionType.Parameter:
+                    return FromModel(viewData);
+            }
+
+            if (!legalExpression) {
+                throw new InvalidOperationException(MvcResources.TemplateHelpers_TemplateLimitations);
+            }
+
+            TParameter container = viewData.Model;
+            Func<object> modelAccessor = () => {
+                try {
+                    return CachedExpressionCompiler.Process(expression)(container);
+                }
+                catch (NullReferenceException) {
+                    return null;
+                }
+            };
+
+            return GetMetadataFromProvider(modelAccessor, typeof(TValue), propertyName, containerType);
+        }
+
+        private static ModelMetadata FromModel(ViewDataDictionary viewData) {
+            return viewData.ModelMetadata ?? GetMetadataFromProvider(null, typeof(string), null, null);
+        }
+
+        public static ModelMetadata FromStringExpression(string expression, ViewDataDictionary viewData) {
+            if (expression == null) {
+                throw new ArgumentNullException("expression");
+            }
+            if (viewData == null) {
+                throw new ArgumentNullException("viewData");
+            }
+            if (expression.Length == 0) {    // Empty string really means "model metadata for the current model"
+                return FromModel(viewData);
+            }
+
+            ViewDataInfo vdi = viewData.GetViewDataInfo(expression);
+            Type containerType = null;
+            Type modelType = null;
+            Func<object> modelAccessor = null;
+            string propertyName = null;
+
+            if (vdi != null) {
+                if (vdi.Container != null) {
+                    containerType = vdi.Container.GetType();
+                }
+
+                modelAccessor = () => vdi.Value;
+
+                if (vdi.PropertyDescriptor != null) {
+                    propertyName = vdi.PropertyDescriptor.Name;
+                    modelType = vdi.PropertyDescriptor.PropertyType;
+                }
+                else if (vdi.Value != null) {  // We only need to delay accessing properties (for LINQ to SQL)
+                    modelType = vdi.Value.GetType();
+                }
+            }
+            //  Try getting a property from ModelMetadata if we couldn't find an answer in ViewData
+            else if (viewData.ModelMetadata != null) {
+                ModelMetadata propertyMetadata = viewData.ModelMetadata.Properties.Where(p => p.PropertyName == expression).FirstOrDefault();
+                if (propertyMetadata != null) {
+                    return propertyMetadata;
+                }
+            }
+
+
+            return GetMetadataFromProvider(modelAccessor, modelType ?? typeof(string), propertyName, containerType);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "The method is a delegating helper to choose among multiple property values")]
+        public string GetDisplayName() {
+            return DisplayName ?? PropertyName ?? ModelType.Name;
+        }
+
+        private static ModelMetadata GetMetadataFromProvider(Func<object> modelAccessor, Type modelType, string propertyName, Type containerType) {
+            if (containerType != null && !String.IsNullOrEmpty(propertyName)) {
+                return ModelMetadataProviders.Current.GetMetadataForProperty(modelAccessor, containerType, propertyName);
+            }
+            return ModelMetadataProviders.Current.GetMetadataForType(modelAccessor, modelType);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "This method is used to resolve the simple display text when it was not explicitly set through other means.")]
+        protected virtual string GetSimpleDisplayText() {
+            if (Model == null) {
+                return NullDisplayText;
+            }
+
+            string toStringResult = Convert.ToString(Model, CultureInfo.CurrentCulture);
+            if (!toStringResult.Equals(Model.GetType().FullName, StringComparison.Ordinal)) {
+                return toStringResult;
+            }
+
+            ModelMetadata firstProperty = Properties.FirstOrDefault();
+            if (firstProperty == null) {
+                return String.Empty;
+            }
+
+            if (firstProperty.Model == null) {
+                return firstProperty.NullDisplayText;
+            }
+
+            return Convert.ToString(firstProperty.Model, CultureInfo.CurrentCulture);
+        }
+
+        public virtual IEnumerable<ModelValidator> GetValidators(ControllerContext context) {
+            return ModelValidatorProviders.Providers.GetValidators(this, context);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ModelMetadataProvider.cs b/mcs/class/System.Web.Mvc3/Mvc/ModelMetadataProvider.cs
new file mode 100644 (file)
index 0000000..6e2cfb1
--- /dev/null
@@ -0,0 +1,11 @@
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+
+    public abstract class ModelMetadataProvider {
+        public abstract IEnumerable<ModelMetadata> GetMetadataForProperties(object container, Type containerType);
+
+        public abstract ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, string propertyName);
+
+        public abstract ModelMetadata GetMetadataForType(Func<object> modelAccessor, Type modelType);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ModelMetadataProviders.cs b/mcs/class/System.Web.Mvc3/Mvc/ModelMetadataProviders.cs
new file mode 100644 (file)
index 0000000..5d0df02
--- /dev/null
@@ -0,0 +1,33 @@
+namespace System.Web.Mvc {
+    public class ModelMetadataProviders {
+        private ModelMetadataProvider _currentProvider;
+        private static ModelMetadataProviders _instance = new ModelMetadataProviders();
+        private IResolver<ModelMetadataProvider> _resolver;
+
+        internal ModelMetadataProviders(IResolver<ModelMetadataProvider> resolver = null) {
+            _resolver = resolver ?? new SingleServiceResolver<ModelMetadataProvider>(
+                () => _currentProvider,
+                new DataAnnotationsModelMetadataProvider(),
+                "ModelMetadataProviders.Current"
+            );
+        }
+
+        public static ModelMetadataProvider Current {
+            get {
+                return _instance.CurrentInternal;
+            }
+            set {
+                _instance.CurrentInternal = value;
+            }
+        }
+
+        internal ModelMetadataProvider CurrentInternal {
+            get {
+                return _resolver.Current;
+            }
+            set {
+                _currentProvider = value ?? new EmptyModelMetadataProvider();
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ModelState.cs b/mcs/class/System.Web.Mvc3/Mvc/ModelState.cs
new file mode 100644 (file)
index 0000000..6c4c234
--- /dev/null
@@ -0,0 +1,19 @@
+namespace System.Web.Mvc {
+
+    [Serializable]
+    public class ModelState {
+
+        private ModelErrorCollection _errors = new ModelErrorCollection();
+
+        public ValueProviderResult Value {
+            get;
+            set;
+        }
+
+        public ModelErrorCollection Errors {
+            get {
+                return _errors;
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ModelStateDictionary.cs b/mcs/class/System.Web.Mvc3/Mvc/ModelStateDictionary.cs
new file mode 100644 (file)
index 0000000..8a0a2ca
--- /dev/null
@@ -0,0 +1,158 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Linq;
+
+    [Serializable]
+    public class ModelStateDictionary : IDictionary<string, ModelState> {
+
+        private readonly Dictionary<string, ModelState> _innerDictionary = new Dictionary<string, ModelState>(StringComparer.OrdinalIgnoreCase);
+
+        public ModelStateDictionary() {
+        }
+
+        public ModelStateDictionary(ModelStateDictionary 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, ModelState>)_innerDictionary).IsReadOnly;
+            }
+        }
+
+        public bool IsValid {
+            get {
+                return Values.All(modelState => modelState.Errors.Count == 0);
+            }
+        }
+
+        public ICollection<string> Keys {
+            get {
+                return _innerDictionary.Keys;
+            }
+        }
+
+        public ModelState this[string key] {
+            get {
+                ModelState value;
+                _innerDictionary.TryGetValue(key, out value);
+                return value;
+            }
+            set {
+                _innerDictionary[key] = value;
+            }
+        }
+
+        public ICollection<ModelState> Values {
+            get {
+                return _innerDictionary.Values;
+            }
+        }
+
+        public void Add(KeyValuePair<string, ModelState> item) {
+            ((IDictionary<string, ModelState>)_innerDictionary).Add(item);
+        }
+
+        public void Add(string key, ModelState value) {
+            _innerDictionary.Add(key, value);
+        }
+
+        public void AddModelError(string key, Exception exception) {
+            GetModelStateForKey(key).Errors.Add(exception);
+        }
+
+        public void AddModelError(string key, string errorMessage) {
+            GetModelStateForKey(key).Errors.Add(errorMessage);
+        }
+
+        public void Clear() {
+            _innerDictionary.Clear();
+        }
+
+        public bool Contains(KeyValuePair<string, ModelState> item) {
+            return ((IDictionary<string, ModelState>)_innerDictionary).Contains(item);
+        }
+
+        public bool ContainsKey(string key) {
+            return _innerDictionary.ContainsKey(key);
+        }
+
+        public void CopyTo(KeyValuePair<string, ModelState>[] array, int arrayIndex) {
+            ((IDictionary<string, ModelState>)_innerDictionary).CopyTo(array, arrayIndex);
+        }
+
+        public IEnumerator<KeyValuePair<string, ModelState>> GetEnumerator() {
+            return _innerDictionary.GetEnumerator();
+        }
+
+        private ModelState GetModelStateForKey(string key) {
+            if (key == null) {
+                throw new ArgumentNullException("key");
+            }
+
+            ModelState modelState;
+            if (!TryGetValue(key, out modelState)) {
+                modelState = new ModelState();
+                this[key] = modelState;
+            }
+
+            return modelState;
+        }
+
+        public bool IsValidField(string key) {
+            if (key == null) {
+                throw new ArgumentNullException("key");
+            }
+
+            // if the key is not found in the dictionary, we just say that it's valid (since there are no errors)
+            return DictionaryHelpers.FindKeysWithPrefix(this, key).All(entry => entry.Value.Errors.Count == 0);
+        }
+
+        public void Merge(ModelStateDictionary dictionary) {
+            if (dictionary == null) {
+                return;
+            }
+
+            foreach (var entry in dictionary) {
+                this[entry.Key] = entry.Value;
+            }
+        }
+
+        public bool Remove(KeyValuePair<string, ModelState> item) {
+            return ((IDictionary<string, ModelState>)_innerDictionary).Remove(item);
+        }
+
+        public bool Remove(string key) {
+            return _innerDictionary.Remove(key);
+        }
+
+        public void SetModelValue(string key, ValueProviderResult value) {
+            GetModelStateForKey(key).Value = value;
+        }
+
+        public bool TryGetValue(string key, out ModelState value) {
+            return _innerDictionary.TryGetValue(key, out value);
+        }
+
+        #region IEnumerable Members
+        IEnumerator IEnumerable.GetEnumerator() {
+            return ((IEnumerable)_innerDictionary).GetEnumerator();
+        }
+        #endregion
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ModelValidationResult.cs b/mcs/class/System.Web.Mvc3/Mvc/ModelValidationResult.cs
new file mode 100644 (file)
index 0000000..255acc0
--- /dev/null
@@ -0,0 +1,28 @@
+namespace System.Web.Mvc {
+    using System;
+
+    public class ModelValidationResult {
+
+        private string _memberName;
+        private string _message;
+
+        public string MemberName {
+            get {
+                return _memberName ?? String.Empty;
+            }
+            set {
+                _memberName = value;
+            }
+        }
+
+        public string Message {
+            get {
+                return _message ?? String.Empty;
+            }
+            set {
+                _message = value;
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ModelValidator.cs b/mcs/class/System.Web.Mvc3/Mvc/ModelValidator.cs
new file mode 100644 (file)
index 0000000..9ced7cd
--- /dev/null
@@ -0,0 +1,71 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq;
+
+    public abstract class ModelValidator {
+        protected ModelValidator(ModelMetadata metadata, ControllerContext controllerContext) {
+            if (metadata == null) {
+                throw new ArgumentNullException("metadata");
+            }
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+
+            Metadata = metadata;
+            ControllerContext = controllerContext;
+        }
+
+        protected internal ControllerContext ControllerContext { get; private set; }
+
+        public virtual bool IsRequired {
+            get {
+                return false;
+            }
+        }
+
+        protected internal ModelMetadata Metadata { get; private set; }
+
+        [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "This method may perform non-trivial work.")]
+        public virtual IEnumerable<ModelClientValidationRule> GetClientValidationRules() {
+            return Enumerable.Empty<ModelClientValidationRule>();
+        }
+
+        public static ModelValidator GetModelValidator(ModelMetadata metadata, ControllerContext context) {
+            return new CompositeModelValidator(metadata, context);
+        }
+
+        public abstract IEnumerable<ModelValidationResult> Validate(object container);
+
+        private class CompositeModelValidator : ModelValidator {
+            public CompositeModelValidator(ModelMetadata metadata, ControllerContext controllerContext)
+                : base(metadata, controllerContext) {
+            }
+
+            public override IEnumerable<ModelValidationResult> Validate(object container) {
+                bool propertiesValid = true;
+
+                foreach (ModelMetadata propertyMetadata in Metadata.Properties) {
+                    foreach (ModelValidator propertyValidator in propertyMetadata.GetValidators(ControllerContext)) {
+                        foreach (ModelValidationResult propertyResult in propertyValidator.Validate(Metadata.Model)) {
+                            propertiesValid = false;
+                            yield return new ModelValidationResult {
+                                MemberName = DefaultModelBinder.CreateSubPropertyName(propertyMetadata.PropertyName, propertyResult.MemberName),
+                                Message = propertyResult.Message
+                            };
+                        }
+                    }
+                }
+
+                if (propertiesValid) {
+                    foreach (ModelValidator typeValidator in Metadata.GetValidators(ControllerContext)) {
+                        foreach (ModelValidationResult typeResult in typeValidator.Validate(container)) {
+                            yield return typeResult;
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ModelValidatorProvider.cs b/mcs/class/System.Web.Mvc3/Mvc/ModelValidatorProvider.cs
new file mode 100644 (file)
index 0000000..452de72
--- /dev/null
@@ -0,0 +1,7 @@
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+
+    public abstract class ModelValidatorProvider {
+        public abstract IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ModelValidatorProviderCollection.cs b/mcs/class/System.Web.Mvc3/Mvc/ModelValidatorProviderCollection.cs
new file mode 100644 (file)
index 0000000..ea016f9
--- /dev/null
@@ -0,0 +1,51 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Collections.ObjectModel;
+    using System.Linq;
+
+    public class ModelValidatorProviderCollection : Collection<ModelValidatorProvider> {
+        private IResolver<IEnumerable<ModelValidatorProvider>> _serviceResolver;
+
+        public ModelValidatorProviderCollection() {
+            _serviceResolver = new MultiServiceResolver<ModelValidatorProvider>(() => Items);
+        }
+
+        public ModelValidatorProviderCollection(IList<ModelValidatorProvider> list)
+            : base(list) {
+            _serviceResolver = new MultiServiceResolver<ModelValidatorProvider>(() => Items);
+        }
+
+        internal ModelValidatorProviderCollection(IResolver<IEnumerable<ModelValidatorProvider>> serviceResolver, params ModelValidatorProvider[] validatorProvidors)
+            : base(validatorProvidors) {
+            _serviceResolver = serviceResolver ??  new MultiServiceResolver<ModelValidatorProvider>(
+                ()=>Items
+                );
+        }
+
+        private IEnumerable<ModelValidatorProvider> CombinedItems {
+            get {
+                return _serviceResolver.Current;
+            }
+        }
+
+        protected override void InsertItem(int index, ModelValidatorProvider item) {
+            if (item == null) {
+                throw new ArgumentNullException("item");
+            }
+            base.InsertItem(index, item);
+        }
+
+        protected override void SetItem(int index, ModelValidatorProvider item) {
+            if (item == null) {
+                throw new ArgumentNullException("item");
+            }
+            base.SetItem(index, item);
+        }
+
+        public IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context) {
+            return CombinedItems.SelectMany(provider => provider.GetValidators(metadata, context));
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ModelValidatorProviders.cs b/mcs/class/System.Web.Mvc3/Mvc/ModelValidatorProviders.cs
new file mode 100644 (file)
index 0000000..e973af9
--- /dev/null
@@ -0,0 +1,17 @@
+namespace System.Web.Mvc {
+    public static class ModelValidatorProviders {
+
+        private static readonly ModelValidatorProviderCollection _providers = new ModelValidatorProviderCollection() {
+            new DataAnnotationsModelValidatorProvider(),
+            new DataErrorInfoModelValidatorProvider(),
+            new ClientDataTypeModelValidatorProvider()
+        };
+
+        public static ModelValidatorProviderCollection Providers {
+            get {
+                return _providers;
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/MultiSelectList.cs b/mcs/class/System.Web.Mvc3/Mvc/MultiSelectList.cs
new file mode 100644 (file)
index 0000000..5ea1a1f
--- /dev/null
@@ -0,0 +1,111 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Linq;
+    using System.Web.UI;
+
+    [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
+    [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Multi", Justification = "Common shorthand for 'multiple'.")]
+    public class MultiSelectList : IEnumerable<SelectListItem> {
+
+        public MultiSelectList(IEnumerable items)
+            : this(items, null /* selectedValues */) {
+        }
+
+        public MultiSelectList(IEnumerable items, IEnumerable selectedValues)
+            : this(items, null /* dataValuefield */, null /* dataTextField */, selectedValues) {
+        }
+
+        public MultiSelectList(IEnumerable items, string dataValueField, string dataTextField)
+            : this(items, dataValueField, dataTextField, null /* selectedValues */) {
+        }
+
+        public MultiSelectList(IEnumerable items, string dataValueField, string dataTextField, IEnumerable selectedValues) {
+            if (items == null) {
+                throw new ArgumentNullException("items");
+            }
+
+            Items = items;
+            DataValueField = dataValueField;
+            DataTextField = dataTextField;
+            SelectedValues = selectedValues;
+        }
+
+        public string DataTextField {
+            get;
+            private set;
+        }
+
+        public string DataValueField {
+            get;
+            private set;
+        }
+
+        public IEnumerable Items {
+            get;
+            private set;
+        }
+
+        public IEnumerable SelectedValues {
+            get;
+            private set;
+        }
+
+        public virtual IEnumerator<SelectListItem> GetEnumerator() {
+            return GetListItems().GetEnumerator();
+        }
+
+        internal IList<SelectListItem> GetListItems() {
+            return (!String.IsNullOrEmpty(DataValueField)) ?
+                GetListItemsWithValueField() :
+                GetListItemsWithoutValueField();
+        }
+
+        private IList<SelectListItem> GetListItemsWithValueField() {
+            HashSet<string> selectedValues = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
+            if (SelectedValues != null) {
+                selectedValues.UnionWith(from object value in SelectedValues select Convert.ToString(value, CultureInfo.CurrentCulture));
+            }
+
+            var listItems = from object item in Items
+                            let value = Eval(item, DataValueField)
+                            select new SelectListItem {
+                                Value = value,
+                                Text = Eval(item, DataTextField),
+                                Selected = selectedValues.Contains(value)
+                            };
+            return listItems.ToList();
+        }
+
+        private IList<SelectListItem> GetListItemsWithoutValueField() {
+            HashSet<object> selectedValues = new HashSet<object>();
+            if (SelectedValues != null) {
+                selectedValues.UnionWith(SelectedValues.Cast<object>());
+            }
+
+            var listItems = from object item in Items
+                            select new SelectListItem {
+                                Text = Eval(item, DataTextField),
+                                Selected = selectedValues.Contains(item)
+                            };
+            return listItems.ToList();
+        }
+
+        private static string Eval(object container, string expression) {
+            object value = container;
+            if (!String.IsNullOrEmpty(expression)) {
+                value = DataBinder.Eval(container, expression);
+            }
+            return Convert.ToString(value, CultureInfo.CurrentCulture);
+        }
+
+        #region IEnumerable Members
+        IEnumerator IEnumerable.GetEnumerator() {
+            return GetEnumerator();
+        }
+        #endregion
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/MultiServiceResolver.cs b/mcs/class/System.Web.Mvc3/Mvc/MultiServiceResolver.cs
new file mode 100644 (file)
index 0000000..5a56a1f
--- /dev/null
@@ -0,0 +1,41 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Linq;
+
+    internal class MultiServiceResolver<TService> : IResolver<IEnumerable<TService>> where TService : class {
+        private IEnumerable<TService> _itemsFromService;
+        private Func<IEnumerable<TService>> _itemsThunk;
+        private Func<IDependencyResolver> _resolverThunk;
+
+        public MultiServiceResolver(Func<IEnumerable<TService>> itemsThunk) {
+            if (itemsThunk == null) {
+                throw new ArgumentNullException("itemsThunk");
+            }
+
+            _itemsThunk = itemsThunk;
+            _resolverThunk = () => DependencyResolver.Current;
+        }
+
+        internal MultiServiceResolver(Func<IEnumerable<TService>> itemsThunk, IDependencyResolver resolver)
+            : this(itemsThunk) {
+            if (resolver != null) {
+                _resolverThunk = () => resolver;
+            }
+        }
+
+        public IEnumerable<TService> Current {
+            get {
+                if (_itemsFromService == null) {
+                    lock (_itemsThunk) {
+                        if (_itemsFromService == null) {
+                            _itemsFromService = _resolverThunk().GetServices<TService>();
+                        }
+                    }
+                }
+                return _itemsFromService.Concat(_itemsThunk());
+            }
+        }
+    }
+}
+
diff --git a/mcs/class/System.Web.Mvc3/Mvc/MvcFilter.cs b/mcs/class/System.Web.Mvc3/Mvc/MvcFilter.cs
new file mode 100644 (file)
index 0000000..b7fa042
--- /dev/null
@@ -0,0 +1,21 @@
+namespace System.Web.Mvc {
+    public abstract class MvcFilter : IMvcFilter {
+        protected MvcFilter() {
+        }
+
+        protected MvcFilter(bool allowMultiple, int order) {
+            AllowMultiple = allowMultiple;
+            Order = order;
+        }
+
+        public bool AllowMultiple {
+            get;
+            private set;
+        }
+
+        public int Order {
+            get;
+            private set;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/MvcHandler.cs b/mcs/class/System.Web.Mvc3/Mvc/MvcHandler.cs
new file mode 100644 (file)
index 0000000..cefac02
--- /dev/null
@@ -0,0 +1,212 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Globalization;
+    using System.Linq;
+    using System.Reflection;
+    using System.Threading;
+    using System.Web;
+    using System.Web.Mvc.Async;
+    using System.Web.Mvc.Resources;
+    using System.Web.Routing;
+    using System.Web.SessionState;
+    using Microsoft.Web.Infrastructure.DynamicValidationHelper;
+
+    public class MvcHandler : IHttpAsyncHandler, IHttpHandler, IRequiresSessionState {
+        private static readonly object _processRequestTag = new object();
+        private ControllerBuilder _controllerBuilder;
+
+        internal static readonly string MvcVersion = GetMvcVersionString();
+        public static readonly string MvcVersionHeaderName = "X-AspNetMvc-Version";
+
+        public MvcHandler(RequestContext requestContext) {
+            if (requestContext == null) {
+                throw new ArgumentNullException("requestContext");
+            }
+
+            RequestContext = requestContext;
+        }
+
+        internal ControllerBuilder ControllerBuilder {
+            get {
+                if (_controllerBuilder == null) {
+                    _controllerBuilder = ControllerBuilder.Current;
+                }
+                return _controllerBuilder;
+            }
+            set {
+                _controllerBuilder = value;
+            }
+        }
+
+        public static bool DisableMvcResponseHeader {
+            get;
+            set;
+        }
+
+        protected virtual bool IsReusable {
+            get {
+                return false;
+            }
+        }
+
+        public RequestContext RequestContext {
+            get;
+            private set;
+        }
+
+        protected internal virtual void AddVersionHeader(HttpContextBase httpContext) {
+            if (!DisableMvcResponseHeader) {
+                httpContext.Response.AppendHeader(MvcVersionHeaderName, MvcVersion);
+            }
+        }
+
+        protected virtual IAsyncResult BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, object state) {
+            HttpContextBase iHttpContext = new HttpContextWrapper(httpContext);
+            return BeginProcessRequest(iHttpContext, callback, state);
+        }
+
+        protected internal virtual IAsyncResult BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, object state) {
+            return SecurityUtil.ProcessInApplicationTrust(() => {
+                IController controller;
+                IControllerFactory factory;
+                ProcessRequestInit(httpContext, out controller, out factory);
+
+                IAsyncController asyncController = controller as IAsyncController;
+                if (asyncController != null) {
+                    // asynchronous controller
+                    BeginInvokeDelegate beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState) {
+                        try {
+                            return asyncController.BeginExecute(RequestContext, asyncCallback, asyncState);
+                        }
+                        catch {
+                            factory.ReleaseController(asyncController);
+                            throw;
+                        }
+                    };
+
+                    EndInvokeDelegate endDelegate = delegate(IAsyncResult asyncResult) {
+                        try {
+                            asyncController.EndExecute(asyncResult);
+                        }
+                        finally {
+                            factory.ReleaseController(asyncController);
+                        }
+                    };
+
+                    SynchronizationContext syncContext = SynchronizationContextUtil.GetSynchronizationContext();
+                    AsyncCallback newCallback = AsyncUtil.WrapCallbackForSynchronizedExecution(callback, syncContext);
+                    return AsyncResultWrapper.Begin(newCallback, state, beginDelegate, endDelegate, _processRequestTag);
+                }
+                else {
+                    // synchronous controller
+                    Action action = delegate {
+                        try {
+                            controller.Execute(RequestContext);
+                        }
+                        finally {
+                            factory.ReleaseController(controller);
+                        }
+                    };
+
+                    return AsyncResultWrapper.BeginSynchronous(callback, state, action, _processRequestTag);
+                }
+            });
+        }
+
+        protected internal virtual void EndProcessRequest(IAsyncResult asyncResult) {
+            SecurityUtil.ProcessInApplicationTrust(() => {
+                AsyncResultWrapper.End(asyncResult, _processRequestTag);
+            });
+        }
+
+        private static string GetMvcVersionString() {
+            // DevDiv 216459:
+            // This code originally used Assembly.GetName(), but that requires FileIOPermission, which isn't granted in
+            // medium trust. However, Assembly.FullName *is* accessible in medium trust.
+            return new AssemblyName(typeof(MvcHandler).Assembly.FullName).Version.ToString(2);
+        }
+
+        protected virtual void ProcessRequest(HttpContext httpContext) {
+            HttpContextBase iHttpContext = new HttpContextWrapper(httpContext);
+            ProcessRequest(iHttpContext);
+        }
+
+        protected internal virtual void ProcessRequest(HttpContextBase httpContext) {
+            SecurityUtil.ProcessInApplicationTrust(() => {
+                IController controller;
+                IControllerFactory factory;
+                ProcessRequestInit(httpContext, out controller, out factory);
+
+                try {
+                    controller.Execute(RequestContext);
+                }
+                finally {
+                    factory.ReleaseController(controller);
+                }
+            });
+        }
+
+        private void ProcessRequestInit(HttpContextBase httpContext, out IController controller, out IControllerFactory factory) {
+            // If request validation has already been enabled, make it lazy. This allows attributes like [HttpPost] (which looks
+            // at Request.Form) to work correctly without triggering full validation.
+            bool? isRequestValidationEnabled = ValidationUtility.IsValidationEnabled(HttpContext.Current);
+            if (isRequestValidationEnabled == true) {
+                ValidationUtility.EnableDynamicValidation(HttpContext.Current);
+            }
+
+            AddVersionHeader(httpContext);
+            RemoveOptionalRoutingParameters();
+
+            // Get the controller type
+            string controllerName = RequestContext.RouteData.GetRequiredString("controller");
+
+            // Instantiate the controller and call Execute
+            factory = ControllerBuilder.GetControllerFactory();
+            controller = factory.CreateController(RequestContext, controllerName);
+            if (controller == null) {
+                throw new InvalidOperationException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.ControllerBuilder_FactoryReturnedNull,
+                        factory.GetType(),
+                        controllerName));
+            }
+        }
+
+        private void RemoveOptionalRoutingParameters() {
+            RouteValueDictionary rvd = RequestContext.RouteData.Values;
+
+            // Get all keys for which the corresponding value is 'Optional'.
+            // ToArray() necessary so that we don't manipulate the dictionary while enumerating.
+            string[] matchingKeys = (from entry in rvd
+                                     where entry.Value == UrlParameter.Optional
+                                     select entry.Key).ToArray();
+
+            foreach (string key in matchingKeys) {
+                rvd.Remove(key);
+            }
+        }
+
+        #region IHttpHandler Members
+        bool IHttpHandler.IsReusable {
+            get {
+                return IsReusable;
+            }
+        }
+
+        void IHttpHandler.ProcessRequest(HttpContext httpContext) {
+            ProcessRequest(httpContext);
+        }
+        #endregion
+
+        #region IHttpAsyncHandler Members
+        IAsyncResult IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) {
+            return BeginProcessRequest(context, cb, extraData);
+        }
+
+        void IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) {
+            EndProcessRequest(result);
+        }
+        #endregion
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/MvcHtmlString.cs b/mcs/class/System.Web.Mvc3/Mvc/MvcHtmlString.cs
new file mode 100644 (file)
index 0000000..675c2e3
--- /dev/null
@@ -0,0 +1,25 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Web;
+
+    public sealed class MvcHtmlString : HtmlString {
+        private readonly string _value;
+
+        public MvcHtmlString(string value)
+            : base(value ?? String.Empty) {
+            _value = value ?? String.Empty;
+        }
+
+        [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "MvcHtmlString is immutable")]
+        public static readonly MvcHtmlString Empty = Create(String.Empty);
+
+        public static MvcHtmlString Create(string value) {
+            return new MvcHtmlString(value);
+        }
+
+        public static bool IsNullOrEmpty(MvcHtmlString value) {
+            return (value == null || value._value.Length == 0);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/MvcHttpHandler.cs b/mcs/class/System.Web.Mvc3/Mvc/MvcHttpHandler.cs
new file mode 100644 (file)
index 0000000..c8e2faa
--- /dev/null
@@ -0,0 +1,89 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Web;
+    using System.Web.Mvc.Async;
+    using System.Web.Routing;
+    using System.Web.SessionState;
+
+    public class MvcHttpHandler : UrlRoutingHandler, IHttpAsyncHandler, IRequiresSessionState {
+
+        private static readonly object _processRequestTag = new object();
+
+        protected virtual IAsyncResult BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, object state) {
+            HttpContextBase iHttpContext = new HttpContextWrapper(httpContext);
+            return BeginProcessRequest(iHttpContext, callback, state);
+        }
+
+        protected internal virtual IAsyncResult BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, object state) {
+            IHttpHandler httpHandler = GetHttpHandler(httpContext);
+            IHttpAsyncHandler httpAsyncHandler = httpHandler as IHttpAsyncHandler;
+
+            if (httpAsyncHandler != null) {
+                // asynchronous handler
+                BeginInvokeDelegate beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState) {
+                    return httpAsyncHandler.BeginProcessRequest(HttpContext.Current, asyncCallback, asyncState);
+                };
+                EndInvokeDelegate endDelegate = delegate(IAsyncResult asyncResult) {
+                    httpAsyncHandler.EndProcessRequest(asyncResult);
+                };
+                return AsyncResultWrapper.Begin(callback, state, beginDelegate, endDelegate, _processRequestTag);
+            }
+            else {
+                // synchronous handler
+                Action action = delegate {
+                    httpHandler.ProcessRequest(HttpContext.Current);
+                };
+                return AsyncResultWrapper.BeginSynchronous(callback, state, action, _processRequestTag);
+            }
+        }
+
+        protected internal virtual void EndProcessRequest(IAsyncResult asyncResult) {
+            AsyncResultWrapper.End(asyncResult, _processRequestTag);
+        }
+
+        private static IHttpHandler GetHttpHandler(HttpContextBase httpContext) {
+            DummyHttpHandler dummyHandler = new DummyHttpHandler();
+            dummyHandler.PublicProcessRequest(httpContext);
+            return dummyHandler.HttpHandler;
+        }
+
+        // synchronous code
+        protected override void VerifyAndProcessRequest(IHttpHandler httpHandler, HttpContextBase httpContext) {
+            if (httpHandler == null) {
+                throw new ArgumentNullException("httpHandler");
+            }
+
+            httpHandler.ProcessRequest(HttpContext.Current);
+        }
+
+        #region IHttpAsyncHandler Members
+        IAsyncResult IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) {
+            return BeginProcessRequest(context, cb, extraData);
+        }
+
+        void IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) {
+            EndProcessRequest(result);
+        }
+        #endregion
+
+        // Since UrlRoutingHandler.ProcessRequest() does the heavy lifting of looking at the RouteCollection for
+        // a matching route, we need to call into it. However, that method is also responsible for kicking off
+        // the synchronous request, and we can't allow it to do that. The purpose of this dummy class is to run
+        // only the lookup portion of UrlRoutingHandler.ProcessRequest(), then intercept the handler it returns
+        // and execute it asynchronously.
+
+        private sealed class DummyHttpHandler : UrlRoutingHandler {
+            public IHttpHandler HttpHandler;
+
+            public void PublicProcessRequest(HttpContextBase httpContext) {
+                ProcessRequest(httpContext);
+            }
+
+            protected override void VerifyAndProcessRequest(IHttpHandler httpHandler, HttpContextBase httpContext) {
+                // don't process the request, just store a reference to it
+                HttpHandler = httpHandler;
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/MvcRouteHandler.cs b/mcs/class/System.Web.Mvc3/Mvc/MvcRouteHandler.cs
new file mode 100644 (file)
index 0000000..17633de
--- /dev/null
@@ -0,0 +1,32 @@
+namespace System.Web.Mvc {
+    using System.Web.Routing;
+    using System.Web.SessionState;
+
+    public class MvcRouteHandler : IRouteHandler {
+        private IControllerFactory _controllerFactory;
+
+        public MvcRouteHandler() {
+        }
+
+        public MvcRouteHandler(IControllerFactory controllerFactory) {
+            _controllerFactory = controllerFactory;
+        }
+
+        protected virtual IHttpHandler GetHttpHandler(RequestContext requestContext) {
+            requestContext.HttpContext.SetSessionStateBehavior(GetSessionStateBehavior(requestContext));
+            return new MvcHandler(requestContext);
+        }
+
+        protected virtual SessionStateBehavior GetSessionStateBehavior(RequestContext requestContext) {
+            string controllerName = (string)requestContext.RouteData.Values["controller"];
+            IControllerFactory controllerFactory = _controllerFactory ?? ControllerBuilder.Current.GetControllerFactory();
+            return controllerFactory.GetControllerSessionBehavior(requestContext, controllerName);
+        }
+
+        #region IRouteHandler Members
+        IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext) {
+            return GetHttpHandler(requestContext);
+        }
+        #endregion
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/MvcWebRazorHostFactory.cs b/mcs/class/System.Web.Mvc3/Mvc/MvcWebRazorHostFactory.cs
new file mode 100644 (file)
index 0000000..d10bfbf
--- /dev/null
@@ -0,0 +1,17 @@
+namespace System.Web.Mvc {
+    using System.Web.Mvc.Razor;
+    using System.Web.WebPages.Razor;
+
+    public class MvcWebRazorHostFactory : WebRazorHostFactory {
+
+        public override WebPageRazorHost CreateHost(string virtualPath, string physicalPath) {
+            WebPageRazorHost host = base.CreateHost(virtualPath, physicalPath);
+
+            if(!host.IsSpecialPage) {
+                return new MvcWebPageRazorHost(virtualPath, physicalPath);
+            }
+
+            return host;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/NameValueCollectionExtensions.cs b/mcs/class/System.Web.Mvc3/Mvc/NameValueCollectionExtensions.cs
new file mode 100644 (file)
index 0000000..d76eaf9
--- /dev/null
@@ -0,0 +1,27 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Collections.Specialized;
+
+    public static class NameValueCollectionExtensions {
+
+        public static void CopyTo(this NameValueCollection collection, IDictionary<string, object> destination) {
+            CopyTo(collection, destination, false /* replaceEntries */);
+        }
+
+        public static void CopyTo(this NameValueCollection collection, IDictionary<string, object> destination, bool replaceEntries) {
+            if (collection == null) {
+                throw new ArgumentNullException("collection");
+            }
+            if (destination == null) {
+                throw new ArgumentNullException("destination");
+            }
+
+            foreach (string key in collection.Keys) {
+                if (replaceEntries || !destination.ContainsKey(key)) {
+                    destination[key] = collection[key];
+                }
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/NameValueCollectionValueProvider.cs b/mcs/class/System.Web.Mvc3/Mvc/NameValueCollectionValueProvider.cs
new file mode 100644 (file)
index 0000000..207f819
--- /dev/null
@@ -0,0 +1,97 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Collections.Specialized;
+    using System.Globalization;
+    using System.Threading;
+
+    public class NameValueCollectionValueProvider : IValueProvider, IUnvalidatedValueProvider {
+
+        private readonly HashSet<string> _prefixes = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
+        private readonly Dictionary<string, ValueProviderResultPlaceholder> _values = new Dictionary<string, ValueProviderResultPlaceholder>(StringComparer.OrdinalIgnoreCase);
+
+        public NameValueCollectionValueProvider(NameValueCollection collection, CultureInfo culture)
+            : this(collection, null /* unvalidatedCollection */, culture) {
+        }
+
+        public NameValueCollectionValueProvider(NameValueCollection collection, NameValueCollection unvalidatedCollection, CultureInfo culture) {
+            if (collection == null) {
+                throw new ArgumentNullException("collection");
+            }
+
+            AddValues(collection, unvalidatedCollection ?? collection, culture);
+        }
+
+        private void AddValues(NameValueCollection validatedCollection, NameValueCollection unvalidatedCollection, CultureInfo culture) {
+            // Need to read keys from the unvalidated collection, as M.W.I's granular request validation is a bit touchy
+            // and validated entries at the time the key or value is looked at. For example, GetKey() will throw if the
+            // value fails request validation, even though the value's not being looked at (M.W.I can't tell the difference).
+
+            if (unvalidatedCollection.Count > 0) {
+                _prefixes.Add("");
+            }
+
+            foreach (string key in unvalidatedCollection) {
+                if (key != null) {
+                    _prefixes.UnionWith(ValueProviderUtil.GetPrefixes(key));
+
+                    // need to look up values lazily, as eagerly looking at the collection might trigger validation
+                    _values[key] = new ValueProviderResultPlaceholder(key, validatedCollection, unvalidatedCollection, culture);
+                }
+            }
+        }
+
+        public virtual bool ContainsPrefix(string prefix) {
+            if (prefix == null) {
+                throw new ArgumentNullException("prefix");
+            }
+
+            return _prefixes.Contains(prefix);
+        }
+
+        public virtual ValueProviderResult GetValue(string key) {
+            return GetValue(key, skipValidation: false);
+        }
+
+        public virtual ValueProviderResult GetValue(string key, bool skipValidation) {
+            if (key == null) {
+                throw new ArgumentNullException("key");
+            }
+
+            ValueProviderResultPlaceholder placeholder;
+            _values.TryGetValue(key, out placeholder);
+            if (placeholder == null) {
+                return null;
+            }
+            else {
+                return (skipValidation) ? placeholder.UnvalidatedResult : placeholder.ValidatedResult;
+            }
+        }
+
+        // Placeholder that can store a validated (in relation to request validation) or unvalidated
+        // ValueProviderResult for a given key.
+        private sealed class ValueProviderResultPlaceholder {
+            private readonly Lazy<ValueProviderResult> _validatedResultPlaceholder;
+            private readonly Lazy<ValueProviderResult> _unvalidatedResultPlaceholder;
+
+            public ValueProviderResultPlaceholder(string key, NameValueCollection validatedCollection, NameValueCollection unvalidatedCollection, CultureInfo culture) {
+                _validatedResultPlaceholder = new Lazy<ValueProviderResult>(() => GetResultFromCollection(key, validatedCollection, culture), LazyThreadSafetyMode.None);
+                _unvalidatedResultPlaceholder = new Lazy<ValueProviderResult>(() => GetResultFromCollection(key, unvalidatedCollection, culture), LazyThreadSafetyMode.None);
+            }
+
+            private static ValueProviderResult GetResultFromCollection(string key, NameValueCollection collection, CultureInfo culture) {
+                string[] rawValue = collection.GetValues(key);
+                string attemptedValue = collection[key];
+                return new ValueProviderResult(rawValue, attemptedValue, culture);
+            }
+
+            public ValueProviderResult ValidatedResult {
+                get { return _validatedResultPlaceholder.Value; }
+            }
+
+            public ValueProviderResult UnvalidatedResult {
+                get { return _unvalidatedResultPlaceholder.Value; }
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/NoAsyncTimeoutAttribute.cs b/mcs/class/System.Web.Mvc3/Mvc/NoAsyncTimeoutAttribute.cs
new file mode 100644 (file)
index 0000000..6ca0639
--- /dev/null
@@ -0,0 +1,12 @@
+namespace System.Web.Mvc {
+    using System.Threading;
+
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
+    public sealed class NoAsyncTimeoutAttribute : AsyncTimeoutAttribute {
+
+        public NoAsyncTimeoutAttribute()
+            : base(Timeout.Infinite) {
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/NonActionAttribute.cs b/mcs/class/System.Web.Mvc3/Mvc/NonActionAttribute.cs
new file mode 100644 (file)
index 0000000..412b228
--- /dev/null
@@ -0,0 +1,10 @@
+namespace System.Web.Mvc {
+    using System.Reflection;
+
+    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
+    public sealed class NonActionAttribute : ActionMethodSelectorAttribute {
+        public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) {
+            return false;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/NullViewLocationCache.cs b/mcs/class/System.Web.Mvc3/Mvc/NullViewLocationCache.cs
new file mode 100644 (file)
index 0000000..003b21f
--- /dev/null
@@ -0,0 +1,18 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Linq;
+    using System.Text;
+
+    internal sealed class NullViewLocationCache : IViewLocationCache {
+
+        #region IViewLocationCache Members
+        public string GetViewLocation(HttpContextBase httpContext, string key) {
+            return null;
+        }
+
+        public void InsertViewLocation(HttpContextBase httpContext, string key, string virtualPath) {
+        }
+        #endregion
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/OutputCacheAttribute.cs b/mcs/class/System.Web.Mvc3/Mvc/OutputCacheAttribute.cs
new file mode 100644 (file)
index 0000000..685b3ec
--- /dev/null
@@ -0,0 +1,337 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.IO;
+    using System.Linq;
+    using System.Runtime.Caching;
+    using System.Security.Cryptography;
+    using System.Text;
+    using System.Web;
+    using System.Web.Mvc.Resources;
+    using System.Web.UI;
+
+    [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes", Justification = "Unsealed so that subclassed types can set properties in the default constructor.")]
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
+    public class OutputCacheAttribute : ActionFilterAttribute, IExceptionFilter {
+
+        private OutputCacheParameters _cacheSettings = new OutputCacheParameters { VaryByParam = "*" };
+        private const string _cacheKeyPrefix = "_MvcChildActionCache_";
+        private static ObjectCache _childActionCache;
+        private Func<ObjectCache> _childActionCacheThunk = () => ChildActionCache;
+        private static object _childActionFilterFinishCallbackKey = new object();
+        private bool _locationWasSet;
+        private bool _noStoreWasSet;
+
+        public OutputCacheAttribute() {
+        }
+
+        internal OutputCacheAttribute(ObjectCache childActionCache) {
+            _childActionCacheThunk = () => childActionCache;
+        }
+
+        public string CacheProfile {
+            get {
+                return _cacheSettings.CacheProfile ?? String.Empty;
+            }
+            set {
+                _cacheSettings.CacheProfile = value;
+            }
+        }
+
+        internal OutputCacheParameters CacheSettings {
+            get {
+                return _cacheSettings;
+            }
+        }
+
+        public static ObjectCache ChildActionCache {
+            get {
+                return _childActionCache ?? MemoryCache.Default;
+            }
+            set {
+                _childActionCache = value;
+            }
+        }
+
+        private ObjectCache ChildActionCacheInternal {
+            get {
+                return _childActionCacheThunk();
+            }
+        }
+
+        public int Duration {
+            get {
+                return _cacheSettings.Duration;
+            }
+            set {
+                _cacheSettings.Duration = value;
+            }
+        }
+
+        public OutputCacheLocation Location {
+            get {
+                return _cacheSettings.Location;
+            }
+            set {
+                _cacheSettings.Location = value;
+                _locationWasSet = true;
+            }
+        }
+
+        public bool NoStore {
+            get {
+                return _cacheSettings.NoStore;
+            }
+            set {
+                _cacheSettings.NoStore = value;
+                _noStoreWasSet = true;
+            }
+        }
+
+        public string SqlDependency {
+            get {
+                return _cacheSettings.SqlDependency ?? String.Empty;
+            }
+            set {
+                _cacheSettings.SqlDependency = value;
+            }
+        }
+
+        public string VaryByContentEncoding {
+            get {
+                return _cacheSettings.VaryByContentEncoding ?? String.Empty;
+            }
+            set {
+                _cacheSettings.VaryByContentEncoding = value;
+            }
+        }
+
+        public string VaryByCustom {
+            get {
+                return _cacheSettings.VaryByCustom ?? String.Empty;
+            }
+            set {
+                _cacheSettings.VaryByCustom = value;
+            }
+        }
+
+        public string VaryByHeader {
+            get {
+                return _cacheSettings.VaryByHeader ?? String.Empty;
+            }
+            set {
+                _cacheSettings.VaryByHeader = value;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Param", Justification = "Matches the @ OutputCache page directive.")]
+        public string VaryByParam {
+            get {
+                return _cacheSettings.VaryByParam ?? String.Empty;
+            }
+            set {
+                _cacheSettings.VaryByParam = value;
+            }
+        }
+
+        private static void ClearChildActionFilterFinishCallback(ControllerContext controllerContext) {
+            controllerContext.HttpContext.Items.Remove(_childActionFilterFinishCallbackKey);
+        }
+
+        private static void CompleteChildAction(ControllerContext filterContext, bool wasException) {
+            Action<bool> callback = GetChildActionFilterFinishCallback(filterContext);
+
+            if (callback != null) {
+                ClearChildActionFilterFinishCallback(filterContext);
+                callback(wasException);
+            }
+        }
+
+        private static Action<bool> GetChildActionFilterFinishCallback(ControllerContext controllerContext) {
+            return controllerContext.HttpContext.Items[_childActionFilterFinishCallbackKey] as Action<bool>;
+        }
+
+        internal string GetChildActionUniqueId(ActionExecutingContext filterContext) {
+            StringBuilder uniqueIdBuilder = new StringBuilder();
+
+            // Start with a prefix, presuming that we share the cache with other users
+            uniqueIdBuilder.Append(_cacheKeyPrefix);
+
+            // Unique ID of the action description
+            uniqueIdBuilder.Append(filterContext.ActionDescriptor.UniqueId);
+
+            // Unique ID from the VaryByCustom settings, if any
+            uniqueIdBuilder.Append(DescriptorUtil.CreateUniqueId(VaryByCustom));
+            if (!String.IsNullOrEmpty(VaryByCustom)) {
+                string varyByCustomResult = filterContext.HttpContext.ApplicationInstance.GetVaryByCustomString(HttpContext.Current, VaryByCustom);
+                uniqueIdBuilder.Append(varyByCustomResult);
+            }
+
+            // Unique ID from the VaryByParam settings, if any
+            uniqueIdBuilder.Append(GetUniqueIdFromActionParameters(filterContext, SplitVaryByParam(VaryByParam)));
+
+            // The key is typically too long to be useful, so we use a cryptographic hash
+            // as the actual key (better randomization and key distribution, so small vary
+            // values will generate dramtically different keys).
+            using (SHA256 sha = SHA256.Create()) {
+                return Convert.ToBase64String(sha.ComputeHash(Encoding.UTF8.GetBytes(uniqueIdBuilder.ToString())));
+            }
+        }
+
+        private static string GetUniqueIdFromActionParameters(ActionExecutingContext filterContext, IEnumerable<string> keys) {
+            // Generate a unique ID of normalized key names + key values
+            var keyValues = new Dictionary<string, object>(filterContext.ActionParameters, StringComparer.OrdinalIgnoreCase);
+            keys = (keys ?? keyValues.Keys).Select(key => key.ToUpperInvariant())
+                                           .OrderBy(key => key, StringComparer.Ordinal);
+
+            return DescriptorUtil.CreateUniqueId(keys.Concat(keys.Select(key => keyValues.ContainsKey(key) ? keyValues[key] : null)));
+        }
+
+        public static bool IsChildActionCacheActive(ControllerContext controllerContext) {
+            return GetChildActionFilterFinishCallback(controllerContext) != null;
+        }
+
+        public override void OnActionExecuted(ActionExecutedContext filterContext) {
+            if (filterContext == null) {
+                throw new ArgumentNullException("filterContext");
+            }
+
+            // Complete the request if the child action threw an exception
+            if (filterContext.IsChildAction && filterContext.Exception != null) {
+                CompleteChildAction(filterContext, wasException: true);
+            }
+        }
+
+        public override void OnActionExecuting(ActionExecutingContext filterContext) {
+            if (filterContext == null) {
+                throw new ArgumentNullException("filterContext");
+            }
+
+            if (filterContext.IsChildAction) {
+                ValidateChildActionConfiguration();
+
+                // Already actively being captured? (i.e., cached child action inside of cached child action)
+                // Realistically, this needs write substitution to do properly (including things like authentication)
+                if (GetChildActionFilterFinishCallback(filterContext) != null) {
+                    throw new InvalidOperationException(MvcResources.OutputCacheAttribute_CannotNestChildCache);
+                }
+
+                // Already cached?
+                string uniqueId = GetChildActionUniqueId(filterContext);
+                string cachedValue = ChildActionCacheInternal.Get(uniqueId) as string;
+                if (cachedValue != null) {
+                    filterContext.Result = new ContentResult() { Content = cachedValue };
+                    return;
+                }
+
+                // Swap in a new TextWriter so we can capture the output
+                StringWriter cachingWriter = new StringWriter(CultureInfo.InvariantCulture);
+                TextWriter originalWriter = filterContext.HttpContext.Response.Output;
+                filterContext.HttpContext.Response.Output = cachingWriter;
+
+                // Set a finish callback to clean up
+                SetChildActionFilterFinishCallback(filterContext, wasException => {
+                    // Restore original writer
+                    filterContext.HttpContext.Response.Output = originalWriter;
+
+                    // Grab output and write it
+                    string capturedText = cachingWriter.ToString();
+                    filterContext.HttpContext.Response.Write(capturedText);
+
+                    // Only cache output if this wasn't an error
+                    if (!wasException) {
+                        ChildActionCacheInternal.Add(uniqueId, capturedText, DateTimeOffset.UtcNow.AddSeconds(Duration));
+                    }
+                });
+            }
+        }
+
+        public void OnException(ExceptionContext filterContext) {
+            if (filterContext == null) {
+                throw new ArgumentNullException("filterContext");
+            }
+
+            if (filterContext.IsChildAction) {
+                CompleteChildAction(filterContext, wasException: true);
+            }
+        }
+
+        public override void OnResultExecuting(ResultExecutingContext filterContext) {
+            if (filterContext == null) {
+                throw new ArgumentNullException("filterContext");
+            }
+
+            if (!filterContext.IsChildAction) {
+                // we need to call ProcessRequest() since there's no other way to set the Page.Response intrinsic
+                using (OutputCachedPage page = new OutputCachedPage(_cacheSettings)) {
+                    page.ProcessRequest(HttpContext.Current);
+                }
+            }
+        }
+
+        public override void OnResultExecuted(ResultExecutedContext filterContext) {
+            if (filterContext == null) {
+                throw new ArgumentNullException("filterContext");
+            }
+
+            if (filterContext.IsChildAction) {
+                CompleteChildAction(filterContext, wasException: filterContext.Exception != null);
+            }
+        }
+
+        private static void SetChildActionFilterFinishCallback(ControllerContext controllerContext, Action<bool> callback) {
+            controllerContext.HttpContext.Items[_childActionFilterFinishCallbackKey] = callback;
+        }
+
+        private static IEnumerable<string> SplitVaryByParam(string varyByParam) {
+            if (String.Equals(varyByParam, "none", StringComparison.OrdinalIgnoreCase)) {  // Vary by nothing
+                return Enumerable.Empty<string>();
+            }
+
+            if (String.Equals(varyByParam, "*", StringComparison.OrdinalIgnoreCase)) {  // Vary by everything
+                return null;
+            }
+
+            return from part in varyByParam.Split(';')  // Vary by specific parameters
+                   let trimmed = part.Trim()
+                   where !String.IsNullOrEmpty(trimmed)
+                   select trimmed;
+        }
+
+        private void ValidateChildActionConfiguration() {
+            if (Duration <= 0) {
+                throw new InvalidOperationException(MvcResources.OutputCacheAttribute_InvalidDuration);
+            }
+
+            if (String.IsNullOrWhiteSpace(VaryByParam)) {
+                throw new InvalidOperationException(MvcResources.OutputCacheAttribute_InvalidVaryByParam);
+            }
+
+            if (!String.IsNullOrWhiteSpace(CacheProfile) ||
+                !String.IsNullOrWhiteSpace(SqlDependency) ||
+                !String.IsNullOrWhiteSpace(VaryByContentEncoding) ||
+                !String.IsNullOrWhiteSpace(VaryByHeader) ||
+                _locationWasSet || _noStoreWasSet) {
+                throw new InvalidOperationException(MvcResources.OutputCacheAttribute_ChildAction_UnsupportedSetting);
+            }
+        }
+
+        private sealed class OutputCachedPage : Page {
+            private OutputCacheParameters _cacheSettings;
+
+            public OutputCachedPage(OutputCacheParameters cacheSettings) {
+                // Tracing requires Page IDs to be unique.
+                ID = Guid.NewGuid().ToString();
+                _cacheSettings = cacheSettings;
+            }
+
+            protected override void FrameworkInitialize() {
+                // when you put the <%@ OutputCache %> directive on a page, the generated code calls InitOutputCache() from here
+                base.FrameworkInitialize();
+                InitOutputCache(_cacheSettings);
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ParameterBindingInfo.cs b/mcs/class/System.Web.Mvc3/Mvc/ParameterBindingInfo.cs
new file mode 100644 (file)
index 0000000..33518d2
--- /dev/null
@@ -0,0 +1,31 @@
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+
+    public abstract class ParameterBindingInfo {
+
+        public virtual IModelBinder Binder {
+            get {
+                return null;
+            }
+        }
+
+        public virtual ICollection<string> Exclude {
+            get {
+                return new string[0];
+            }
+        }
+
+        public virtual ICollection<string> Include {
+            get {
+                return new string[0];
+            }
+        }
+
+        public virtual string Prefix {
+            get {
+                return null;
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ParameterDescriptor.cs b/mcs/class/System.Web.Mvc3/Mvc/ParameterDescriptor.cs
new file mode 100644 (file)
index 0000000..50fe4c6
--- /dev/null
@@ -0,0 +1,57 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Reflection;
+
+    public abstract class ParameterDescriptor : ICustomAttributeProvider {
+
+        private static readonly EmptyParameterBindingInfo _emptyBindingInfo = new EmptyParameterBindingInfo();
+
+        public abstract ActionDescriptor ActionDescriptor {
+            get;
+        }
+
+        public virtual ParameterBindingInfo BindingInfo {
+            get {
+                return _emptyBindingInfo;
+            }
+        }
+
+        public virtual object DefaultValue {
+            get {
+                return null;
+            }
+        }
+
+        public abstract string ParameterName {
+            get;
+        }
+
+        public abstract Type ParameterType {
+            get;
+        }
+
+        public virtual object[] GetCustomAttributes(bool inherit) {
+            return GetCustomAttributes(typeof(object), inherit);
+        }
+
+        public virtual object[] GetCustomAttributes(Type attributeType, bool inherit) {
+            if (attributeType == null) {
+                throw new ArgumentNullException("attributeType");
+            }
+
+            return (object[])Array.CreateInstance(attributeType, 0);
+        }
+
+        public virtual bool IsDefined(Type attributeType, bool inherit) {
+            if (attributeType == null) {
+                throw new ArgumentNullException("attributeType");
+            }
+
+            return false;
+        }
+
+        private sealed class EmptyParameterBindingInfo : ParameterBindingInfo {
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ParameterInfoUtil.cs b/mcs/class/System.Web.Mvc3/Mvc/ParameterInfoUtil.cs
new file mode 100644 (file)
index 0000000..b10adba
--- /dev/null
@@ -0,0 +1,30 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.ComponentModel;
+    using System.Reflection;
+
+    internal static class ParameterInfoUtil {
+
+        public static bool TryGetDefaultValue(ParameterInfo parameterInfo, out object value) {
+            // this will get the default value as seen by the VB / C# compilers
+            // if no value was baked in, RawDefaultValue returns DBNull.Value
+            object defaultValue = parameterInfo.DefaultValue;
+            if (defaultValue != DBNull.Value) {
+                value = defaultValue;
+                return true;
+            }
+
+            // if the compiler did not bake in a default value, check the [DefaultValue] attribute
+            DefaultValueAttribute[] attrs = (DefaultValueAttribute[])parameterInfo.GetCustomAttributes(typeof(DefaultValueAttribute), false);
+            if (attrs == null || attrs.Length == 0) {
+                value = default(object);
+                return false;
+            }
+            else {
+                value = attrs[0].Value;
+                return true;
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/PartialViewResult.cs b/mcs/class/System.Web.Mvc3/Mvc/PartialViewResult.cs
new file mode 100644 (file)
index 0000000..3e8f93b
--- /dev/null
@@ -0,0 +1,25 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Globalization;
+    using System.Text;
+    using System.Web.Mvc.Resources;
+
+    public class PartialViewResult : ViewResultBase {
+
+        protected override ViewEngineResult FindView(ControllerContext context) {
+            ViewEngineResult result = ViewEngineCollection.FindPartialView(context, ViewName);
+            if (result.View != null) {
+                return result;
+            }
+
+            // we need to generate an exception containing all the locations we searched
+            StringBuilder locationsText = new StringBuilder();
+            foreach (string location in result.SearchedLocations) {
+                locationsText.AppendLine();
+                locationsText.Append(location);
+            }
+            throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
+                MvcResources.Common_PartialViewNotFound, ViewName, locationsText));
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/PathHelpers.cs b/mcs/class/System.Web.Mvc3/Mvc/PathHelpers.cs
new file mode 100644 (file)
index 0000000..a2645e8
--- /dev/null
@@ -0,0 +1,84 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Specialized;
+    using System.Web;
+
+    internal static class PathHelpers {
+
+        private readonly static UrlRewriterHelper _urlRewriterHelper = new UrlRewriterHelper();
+
+        // this method can accept an app-relative path or an absolute path for contentPath
+        public static string GenerateClientUrl(HttpContextBase httpContext, string contentPath) {
+            if (String.IsNullOrEmpty(contentPath)) {
+                return contentPath;
+            }
+
+            // many of the methods we call internally can't handle query strings properly, so just strip it out for
+            // the time being
+            string query;
+            contentPath = StripQuery(contentPath, out query);
+
+            return GenerateClientUrlInternal(httpContext, contentPath) + query;
+        }
+
+        private static string GenerateClientUrlInternal(HttpContextBase httpContext, string contentPath) {
+            if (String.IsNullOrEmpty(contentPath)) {
+                return contentPath;
+            }
+
+            // can't call VirtualPathUtility.IsAppRelative since it throws on some inputs
+            bool isAppRelative = contentPath[0] == '~';
+            if (isAppRelative) {
+                string absoluteContentPath = VirtualPathUtility.ToAbsolute(contentPath, httpContext.Request.ApplicationPath);
+                string modifiedAbsoluteContentPath = httpContext.Response.ApplyAppPathModifier(absoluteContentPath);
+                return GenerateClientUrlInternal(httpContext, modifiedAbsoluteContentPath);
+            }
+
+            // we only want to manipulate the path if URL rewriting is active for this request, else we risk breaking the generated URL
+            bool wasRequestRewritten = _urlRewriterHelper.WasRequestRewritten(httpContext);
+            if (!wasRequestRewritten) {
+                return contentPath;
+            }
+
+            // Since the rawUrl represents what the user sees in his browser, it is what we want to use as the base
+            // of our absolute paths. For example, consider mysite.example.com/foo, which is internally
+            // rewritten to content.example.com/mysite/foo. When we want to generate a link to ~/bar, we want to
+            // base it from / instead of /foo, otherwise the user ends up seeing mysite.example.com/foo/bar,
+            // which is incorrect.
+            string relativeUrlToDestination = MakeRelative(httpContext.Request.Path, contentPath);
+            string absoluteUrlToDestination = MakeAbsolute(httpContext.Request.RawUrl, relativeUrlToDestination);
+            return absoluteUrlToDestination;
+        }
+
+        public static string MakeAbsolute(string basePath, string relativePath) {
+            // The Combine() method can't handle query strings on the base path, so we trim it off.
+            string query;
+            basePath = StripQuery(basePath, out query);
+            return VirtualPathUtility.Combine(basePath, relativePath);
+        }
+
+        public static string MakeRelative(string fromPath, string toPath) {
+            string relativeUrl = VirtualPathUtility.MakeRelative(fromPath, toPath);
+            if (String.IsNullOrEmpty(relativeUrl) || relativeUrl[0] == '?') {
+                // Sometimes VirtualPathUtility.MakeRelative() will return an empty string when it meant to return '.',
+                // but links to {empty string} are browser dependent. We replace it with an explicit path to force
+                // consistency across browsers.
+                relativeUrl = "./" + relativeUrl;
+            }
+            return relativeUrl;
+        }
+
+        private static string StripQuery(string path, out string query) {
+            int queryIndex = path.IndexOf('?');
+            if (queryIndex >= 0) {
+                query = path.Substring(queryIndex);
+                return path.Substring(0, queryIndex);
+            }
+            else {
+                query = null;
+                return path;
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/PreApplicationStartCode.cs b/mcs/class/System.Web.Mvc3/Mvc/PreApplicationStartCode.cs
new file mode 100644 (file)
index 0000000..d5b9df8
--- /dev/null
@@ -0,0 +1,22 @@
+namespace System.Web.Mvc {
+    using System.ComponentModel;
+    using System.Web.WebPages.Scope;
+
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public static class PreApplicationStartCode {
+        private static bool _startWasCalled;
+
+        public static void Start() {
+            // Guard against multiple calls. All Start calls are made on same thread, so no lock needed here
+            if (_startWasCalled) {
+                return;
+            }
+            _startWasCalled = true;
+
+            System.Web.WebPages.Razor.PreApplicationStartCode.Start();
+            System.Web.WebPages.PreApplicationStartCode.Start();
+
+            ViewContext.GlobalScopeThunk = () => ScopeStorage.CurrentScope;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/QueryStringValueProvider.cs b/mcs/class/System.Web.Mvc3/Mvc/QueryStringValueProvider.cs
new file mode 100644 (file)
index 0000000..1c70edf
--- /dev/null
@@ -0,0 +1,21 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Specialized;
+    using System.Globalization;
+    using System.Web.Helpers;
+
+    public sealed class QueryStringValueProvider : NameValueCollectionValueProvider {
+
+        // QueryString should use the invariant culture since it's part of the URL, and the URL should be
+        // interpreted in a uniform fashion regardless of the origin of a particular request.
+        public QueryStringValueProvider(ControllerContext controllerContext)
+            : this(controllerContext, new UnvalidatedRequestValuesWrapper(controllerContext.HttpContext.Request.Unvalidated())) {
+        }
+
+        // For unit testing
+        internal QueryStringValueProvider(ControllerContext controllerContext, IUnvalidatedRequestValues unvalidatedValues)
+            : base(controllerContext.HttpContext.Request.QueryString, unvalidatedValues.QueryString, CultureInfo.InvariantCulture) {
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/QueryStringValueProviderFactory.cs b/mcs/class/System.Web.Mvc3/Mvc/QueryStringValueProviderFactory.cs
new file mode 100644 (file)
index 0000000..8e9cc10
--- /dev/null
@@ -0,0 +1,28 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Specialized;
+    using System.Web.Helpers;
+
+    public sealed class QueryStringValueProviderFactory : ValueProviderFactory {
+
+        private readonly UnvalidatedRequestValuesAccessor _unvalidatedValuesAccessor;
+
+        public QueryStringValueProviderFactory()
+            : this(null) {
+        }
+
+        // For unit testing
+        internal QueryStringValueProviderFactory(UnvalidatedRequestValuesAccessor unvalidatedValuesAccessor) {
+            _unvalidatedValuesAccessor = unvalidatedValuesAccessor ?? (cc => new UnvalidatedRequestValuesWrapper(cc.HttpContext.Request.Unvalidated()));
+        }
+
+        public override IValueProvider GetValueProvider(ControllerContext controllerContext) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+
+            return new QueryStringValueProvider(controllerContext, _unvalidatedValuesAccessor(controllerContext));
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/RangeAttributeAdapter.cs b/mcs/class/System.Web.Mvc3/Mvc/RangeAttributeAdapter.cs
new file mode 100644 (file)
index 0000000..3aa86af
--- /dev/null
@@ -0,0 +1,15 @@
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+    using System.ComponentModel.DataAnnotations;
+
+    public class RangeAttributeAdapter : DataAnnotationsModelValidator<RangeAttribute> {
+        public RangeAttributeAdapter(ModelMetadata metadata, ControllerContext context, RangeAttribute attribute)
+            : base(metadata, context, attribute) {
+        }
+
+        public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() {
+            string errorMessage = ErrorMessage; // Per Dev10 Bug #923283, need to make sure ErrorMessage is called before Minimum/Maximum
+            return new[] { new ModelClientValidationRangeRule(errorMessage, Attribute.Minimum, Attribute.Maximum) };
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Razor/ModelSpan.cs b/mcs/class/System.Web.Mvc3/Mvc/Razor/ModelSpan.cs
new file mode 100644 (file)
index 0000000..ed02ea7
--- /dev/null
@@ -0,0 +1,34 @@
+namespace System.Web.Mvc.Razor {
+    using System.Web.Razor.Parser;
+    using System.Web.Razor.Parser.SyntaxTree;
+    using System.Web.Razor.Text;
+
+    public class ModelSpan : CodeSpan {
+        public ModelSpan(SourceLocation start, string content, string modelTypeName)
+            : base(start, content) {
+            this.ModelTypeName = modelTypeName;
+        }
+
+        internal ModelSpan(ParserContext context, string modelTypeName)
+            : this(context.CurrentSpanStart, context.ContentBuffer.ToString(), modelTypeName) {
+        }
+
+        public string ModelTypeName {
+            get;
+            private set;
+        }
+
+        public override int GetHashCode() {
+            return base.GetHashCode() ^ (ModelTypeName ?? String.Empty).GetHashCode();
+        }
+
+        public override bool Equals(object obj) {
+            ModelSpan span = obj as ModelSpan;
+            return span != null && Equals(span);
+        }
+
+        private bool Equals(ModelSpan span) {
+            return base.Equals(span) && String.Equals(ModelTypeName, span.ModelTypeName, StringComparison.Ordinal);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Razor/MvcCSharpRazorCodeGenerator.cs b/mcs/class/System.Web.Mvc3/Mvc/Razor/MvcCSharpRazorCodeGenerator.cs
new file mode 100644 (file)
index 0000000..b09a95a
--- /dev/null
@@ -0,0 +1,30 @@
+using System.CodeDom;
+using System.Web.Razor;
+using System.Web.Razor.Generator;
+
+namespace System.Web.Mvc.Razor
+{
+    internal class MvcCSharpRazorCodeGenerator : CSharpRazorCodeGenerator
+    {
+        private const string DefaultModelTypeName = "dynamic";
+
+        public MvcCSharpRazorCodeGenerator(string className, string rootNamespaceName, string sourceFileName, RazorEngineHost host)
+            : base(className, rootNamespaceName, sourceFileName, host)
+        {
+            var mvcHost = host as MvcWebPageRazorHost;
+            if (mvcHost != null && !mvcHost.IsSpecialPage)
+            {
+                // set the default model type to "dynamic" (Dev10 bug 935656)
+                // don't set it for "special" pages (such as "_viewStart.cshtml")
+                SetBaseType(DefaultModelTypeName);
+            }
+        }
+
+        private void SetBaseType(string modelTypeName)
+        {
+            var baseType = new CodeTypeReference(Context.Host.DefaultBaseClass + "<" + modelTypeName + ">");
+            Context.GeneratedClass.BaseTypes.Clear();
+            Context.GeneratedClass.BaseTypes.Add(baseType);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Razor/MvcCSharpRazorCodeParser.cs b/mcs/class/System.Web.Mvc3/Mvc/Razor/MvcCSharpRazorCodeParser.cs
new file mode 100644 (file)
index 0000000..95f53b7
--- /dev/null
@@ -0,0 +1,68 @@
+using System.Globalization;
+using System.Web.Mvc.Resources;
+using System.Web.Razor.Generator;
+using System.Web.Razor.Parser;
+using System.Web.Razor.Text;
+
+namespace System.Web.Mvc.Razor
+{
+    public class MvcCSharpRazorCodeParser : CSharpCodeParser
+    {
+        private const string ModelKeyword = "model";
+        private const string GenericTypeFormatString = "{0}<{1}>";
+        private SourceLocation? _endInheritsLocation;
+        private bool _modelStatementFound;
+
+        public MvcCSharpRazorCodeParser()
+        {
+            MapDirectives(ModelDirective, ModelKeyword);
+        }
+
+        protected override void InheritsDirective()
+        {
+            // Verify we're on the right keyword and accept
+            AssertDirective(SyntaxConstants.CSharp.InheritsKeyword);
+            AcceptAndMoveNext();
+            _endInheritsLocation = CurrentLocation;
+
+            InheritsDirectiveCore();
+            CheckForInheritsAndModelStatements();
+        }
+
+        private void CheckForInheritsAndModelStatements()
+        {
+            if (_modelStatementFound && _endInheritsLocation.HasValue)
+            {
+                Context.OnError(_endInheritsLocation.Value, String.Format(CultureInfo.CurrentCulture, MvcResources.MvcRazorCodeParser_CannotHaveModelAndInheritsKeyword, ModelKeyword));
+            }
+        }
+
+        protected virtual void ModelDirective()
+        {
+            // Verify we're on the right keyword and accept
+            AssertDirective(ModelKeyword);
+            AcceptAndMoveNext();
+
+            SourceLocation endModelLocation = CurrentLocation;
+
+            BaseTypeDirective(
+                String.Format(CultureInfo.CurrentCulture,
+                              MvcResources.MvcRazorCodeParser_ModelKeywordMustBeFollowedByTypeName, ModelKeyword),
+                CreateModelCodeGenerator);
+
+            if (_modelStatementFound)
+            {
+                Context.OnError(endModelLocation, String.Format(CultureInfo.CurrentCulture, MvcResources.MvcRazorCodeParser_OnlyOneModelStatementIsAllowed, ModelKeyword));
+            }
+
+            _modelStatementFound = true;
+
+            CheckForInheritsAndModelStatements();
+        }
+
+        private SpanCodeGenerator CreateModelCodeGenerator(string model)
+        {
+            return new SetModelTypeCodeGenerator(model, GenericTypeFormatString);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Razor/MvcVBRazorCodeGenerator.cs b/mcs/class/System.Web.Mvc3/Mvc/Razor/MvcVBRazorCodeGenerator.cs
new file mode 100644 (file)
index 0000000..13c5c5a
--- /dev/null
@@ -0,0 +1,28 @@
+namespace System.Web.Mvc.Razor {
+    using System.CodeDom;
+    using System.Web.Razor;
+    using System.Web.Razor.Generator;
+    using System.Web.Razor.Parser.SyntaxTree;
+
+    public class MvcVBRazorCodeGenerator : VBRazorCodeGenerator {
+        public MvcVBRazorCodeGenerator(string className, string rootNamespaceName, string sourceFileName, RazorEngineHost host)
+            : base(className, rootNamespaceName, sourceFileName, host) {
+        }
+
+        protected override bool TryVisitSpecialSpan(Span span) {
+            return TryVisit<ModelSpan>(span, VisitModelSpan);
+        }
+
+        private void VisitModelSpan(ModelSpan span) {
+            string modelName = span.ModelTypeName;
+            var baseType = new CodeTypeReference(Host.DefaultBaseClass + "(Of " + modelName + ")");
+
+            GeneratedClass.BaseTypes.Clear();
+            GeneratedClass.BaseTypes.Add(baseType);
+
+            if (DesignTimeMode) {
+                WriteHelperVariable(span.Content, "__modelHelper");
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Razor/MvcVBRazorCodeParser.cs b/mcs/class/System.Web.Mvc3/Mvc/Razor/MvcVBRazorCodeParser.cs
new file mode 100644 (file)
index 0000000..9ac6889
--- /dev/null
@@ -0,0 +1,93 @@
+using System.Globalization;
+using System.Linq;
+using System.Web.Mvc.Resources;
+using System.Web.Razor.Generator;
+using System.Web.Razor.Parser;
+using System.Web.Razor.Parser.SyntaxTree;
+using System.Web.Razor.Text;
+using System.Web.Razor.Tokenizer.Symbols;
+
+namespace System.Web.Mvc.Razor
+{
+    public class MvcVBRazorCodeParser : VBCodeParser
+    {
+        internal const string ModelTypeKeyword = "ModelType";
+        private const string GenericTypeFormatString = "{0}(Of {1})";
+        private SourceLocation? _endInheritsLocation;
+        private bool _modelStatementFound;
+
+        public MvcVBRazorCodeParser()
+        {
+            MapDirective(ModelTypeKeyword, ModelTypeDirective);
+        }
+
+        protected override bool InheritsStatement()
+        {
+            // Verify we're on the right keyword and accept
+            Assert(VBKeyword.Inherits);
+            VBSymbol inherits = CurrentSymbol;
+            NextToken();
+            _endInheritsLocation = CurrentLocation;
+            PutCurrentBack();
+            PutBack(inherits);
+            EnsureCurrent();
+
+            bool result = base.InheritsStatement();
+            CheckForInheritsAndModelStatements();
+            return result;
+        }
+
+        private void CheckForInheritsAndModelStatements()
+        {
+            if (_modelStatementFound && _endInheritsLocation.HasValue)
+            {
+                Context.OnError(_endInheritsLocation.Value, String.Format(CultureInfo.CurrentCulture, MvcResources.MvcRazorCodeParser_CannotHaveModelAndInheritsKeyword, ModelTypeKeyword));
+            }
+        }
+
+        protected virtual bool ModelTypeDirective()
+        {
+            AssertDirective(ModelTypeKeyword);
+
+            Span.CodeGenerator = SpanCodeGenerator.Null;
+            Context.CurrentBlock.Type = BlockType.Directive;
+
+            AcceptAndMoveNext();
+            SourceLocation endModelLocation = CurrentLocation;
+
+            if (At(VBSymbolType.WhiteSpace))
+            {
+                Span.EditHandler.AcceptedCharacters = AcceptedCharacters.None;
+            }
+
+            AcceptWhile(VBSymbolType.WhiteSpace);
+            Output(SpanKind.MetaCode);
+
+            if (_modelStatementFound)
+            {
+                Context.OnError(endModelLocation, String.Format(CultureInfo.CurrentCulture, MvcResources.MvcRazorCodeParser_OnlyOneModelStatementIsAllowed, ModelTypeKeyword));
+            }
+            _modelStatementFound = true;
+
+            if (EndOfFile || At(VBSymbolType.WhiteSpace) || At(VBSymbolType.NewLine))
+            {
+                Context.OnError(endModelLocation, MvcResources.MvcRazorCodeParser_ModelKeywordMustBeFollowedByTypeName, ModelTypeKeyword);
+            }
+
+            // Just accept to a newline
+            AcceptUntil(VBSymbolType.NewLine);
+            if (!Context.DesignTimeMode)
+            {
+                // We want the newline to be treated as code, but it causes issues at design-time.
+                Optional(VBSymbolType.NewLine);
+            }
+
+            string baseType = String.Concat(Span.Symbols.Select(s => s.Content)).Trim();
+            Span.CodeGenerator = new SetModelTypeCodeGenerator(baseType, GenericTypeFormatString);
+
+            CheckForInheritsAndModelStatements();
+            Output(SpanKind.Code);
+            return false;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Razor/MvcWebPageRazorHost.cs b/mcs/class/System.Web.Mvc3/Mvc/Razor/MvcWebPageRazorHost.cs
new file mode 100644 (file)
index 0000000..69f058f
--- /dev/null
@@ -0,0 +1,64 @@
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Web.Razor.Generator;
+using System.Web.Razor.Parser;
+using System.Web.WebPages.Razor;
+
+namespace System.Web.Mvc.Razor
+{
+    [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "WebPage", Justification = "The class name is derived from the name of the base type")]
+    public class MvcWebPageRazorHost : WebPageRazorHost
+    {
+        [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", Justification = "The NamespaceImports property should not be virtual. This is a temporary fix.")]
+        public MvcWebPageRazorHost(string virtualPath, string physicalPath)
+            : base(virtualPath, physicalPath)
+        {
+            RegisterSpecialFile(RazorViewEngine.ViewStartFileName, typeof(ViewStartPage));
+
+            DefaultPageBaseClass = typeof(WebViewPage).FullName;
+
+            // REVIEW get rid of the namespace import to not force additional references in default MVC projects
+            GetRidOfNamespace("System.Web.WebPages.Html");
+        }
+
+        public override RazorCodeGenerator DecorateCodeGenerator(RazorCodeGenerator incomingCodeGenerator)
+        {
+            if (incomingCodeGenerator is CSharpRazorCodeGenerator)
+            {
+                return new MvcCSharpRazorCodeGenerator(incomingCodeGenerator.ClassName,
+                                                       incomingCodeGenerator.RootNamespaceName,
+                                                       incomingCodeGenerator.SourceFileName,
+                                                       incomingCodeGenerator.Host);
+            }
+            else
+            {
+                return base.DecorateCodeGenerator(incomingCodeGenerator);
+            }
+        }
+
+        public override ParserBase DecorateCodeParser(ParserBase incomingCodeParser)
+        {
+            if (incomingCodeParser is CSharpCodeParser)
+            {
+                return new MvcCSharpRazorCodeParser();
+            }
+            else if (incomingCodeParser is VBCodeParser)
+            {
+                return new MvcVBRazorCodeParser();
+            }
+            else
+            {
+                return base.DecorateCodeParser(incomingCodeParser);
+            }
+        }
+
+        private void GetRidOfNamespace(string ns)
+        {
+            Debug.Assert(NamespaceImports.Contains(ns), ns + " is not a default namespace anymore");
+            if (NamespaceImports.Contains(ns))
+            {
+                NamespaceImports.Remove(ns);
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Razor/SetModelTypeCodeGenerator.cs b/mcs/class/System.Web.Mvc3/Mvc/Razor/SetModelTypeCodeGenerator.cs
new file mode 100644 (file)
index 0000000..e8640b2
--- /dev/null
@@ -0,0 +1,47 @@
+using System.Globalization;
+using System.Web.Mvc.ExpressionUtil;
+using System.Web.Razor.Generator;
+
+namespace System.Web.Mvc.Razor
+{
+    internal class SetModelTypeCodeGenerator : SetBaseTypeCodeGenerator
+    {
+        private string _genericTypeFormat;
+
+        public SetModelTypeCodeGenerator(string modelType, string genericTypeFormat)
+            : base(modelType)
+        {
+            _genericTypeFormat = genericTypeFormat;
+        }
+
+        protected override string ResolveType(CodeGeneratorContext context, string baseType)
+        {
+            return String.Format(
+                CultureInfo.InvariantCulture,
+                _genericTypeFormat,
+                context.Host.DefaultBaseClass,
+                baseType);
+        }
+
+        public override bool Equals(object obj)
+        {
+            SetModelTypeCodeGenerator other = obj as SetModelTypeCodeGenerator;
+            return other != null &&
+                   base.Equals(obj) &&
+                   String.Equals(_genericTypeFormat, other._genericTypeFormat, StringComparison.Ordinal);
+        }
+
+        public override int GetHashCode()
+        {
+            var combiner = new HashCodeCombiner();
+            combiner.AddInt32(base.GetHashCode());
+            combiner.AddObject(_genericTypeFormat);
+            return combiner.CombinedHash;
+        }
+
+        public override string ToString()
+        {
+            return "Model:" + BaseType;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Razor/StartPageLookupDelegate.cs b/mcs/class/System.Web.Mvc3/Mvc/Razor/StartPageLookupDelegate.cs
new file mode 100644 (file)
index 0000000..0719761
--- /dev/null
@@ -0,0 +1,7 @@
+using System.Collections.Generic;
+using System.Web.WebPages;
+
+namespace System.Web.Mvc.Razor
+{
+    internal delegate WebPageRenderingBase StartPageLookupDelegate(WebPageRenderingBase page, string fileName, IEnumerable<string> supportedExtensions);
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/RazorView.cs b/mcs/class/System.Web.Mvc3/Mvc/RazorView.cs
new file mode 100644 (file)
index 0000000..49e5b9d
--- /dev/null
@@ -0,0 +1,73 @@
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+    using System.Globalization;
+    using System.IO;
+    using System.Linq;
+    using System.Web.Mvc.Razor;
+    using System.Web.Mvc.Resources;
+    using System.Web.WebPages;
+
+    public class RazorView : BuildManagerCompiledView {
+
+        public RazorView(ControllerContext controllerContext, string viewPath, string layoutPath, bool runViewStartPages, IEnumerable<string> viewStartFileExtensions)
+            : this(controllerContext, viewPath, layoutPath, runViewStartPages, viewStartFileExtensions, null) {
+        }
+
+        public RazorView(ControllerContext controllerContext, string viewPath, string layoutPath, bool runViewStartPages, IEnumerable<string> viewStartFileExtensions, IViewPageActivator viewPageActivator)
+            : base(controllerContext, viewPath, viewPageActivator) {
+            LayoutPath = layoutPath ?? String.Empty;
+            RunViewStartPages = runViewStartPages;
+            StartPageLookup = StartPage.GetStartPage;
+            ViewStartFileExtensions = viewStartFileExtensions ?? Enumerable.Empty<string>();
+        }
+
+        public string LayoutPath {
+            get;
+            private set;
+        }
+
+        public bool RunViewStartPages {
+            get;
+            private set;
+        }
+
+        internal StartPageLookupDelegate StartPageLookup {
+            get;
+            set;
+        }
+
+        public IEnumerable<string> ViewStartFileExtensions {
+            get;
+            private set;
+        }
+
+        protected override void RenderView(ViewContext viewContext, TextWriter writer, object instance) {
+            if (writer == null) {
+                throw new ArgumentNullException("writer");
+            }
+
+            WebViewPage webViewPage = instance as WebViewPage;
+            if (webViewPage == null) {
+                throw new InvalidOperationException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.CshtmlView_WrongViewBase,
+                        ViewPath));
+            }
+
+            // An overriden master layout might have been specified when the ViewActionResult got returned.
+            // We need to hold on to it so that we can set it on the inner page once it has executed.
+            webViewPage.OverridenLayoutPath = LayoutPath;
+            webViewPage.VirtualPath = ViewPath;
+            webViewPage.ViewContext = viewContext;
+            webViewPage.ViewData = viewContext.ViewData;
+
+            webViewPage.InitHelpers();
+            WebPageRenderingBase startPage = null;
+            if (RunViewStartPages) {
+                startPage = StartPageLookup(webViewPage, RazorViewEngine.ViewStartFileName, ViewStartFileExtensions);
+            }
+            webViewPage.ExecutePageHierarchy(new WebPageContext(context: viewContext.HttpContext, page: null, model: null), writer, startPage);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/RazorViewEngine.cs b/mcs/class/System.Web.Mvc3/Mvc/RazorViewEngine.cs
new file mode 100644 (file)
index 0000000..72c85e2
--- /dev/null
@@ -0,0 +1,68 @@
+namespace System.Web.Mvc {
+    using System.Diagnostics.CodeAnalysis;
+
+    public class RazorViewEngine : BuildManagerViewEngine {
+        internal static readonly string ViewStartFileName = "_ViewStart";
+
+        public RazorViewEngine()
+            : this(null) {
+        }
+
+        public RazorViewEngine(IViewPageActivator viewPageActivator)
+            : base(viewPageActivator) {
+            AreaViewLocationFormats = new[] {
+                "~/Areas/{2}/Views/{1}/{0}.cshtml",
+                "~/Areas/{2}/Views/{1}/{0}.vbhtml",
+                "~/Areas/{2}/Views/Shared/{0}.cshtml",
+                "~/Areas/{2}/Views/Shared/{0}.vbhtml"
+            };
+            AreaMasterLocationFormats = new[] {
+                "~/Areas/{2}/Views/{1}/{0}.cshtml",
+                "~/Areas/{2}/Views/{1}/{0}.vbhtml",
+                "~/Areas/{2}/Views/Shared/{0}.cshtml",
+                "~/Areas/{2}/Views/Shared/{0}.vbhtml"
+            };
+            AreaPartialViewLocationFormats = new[] {
+                "~/Areas/{2}/Views/{1}/{0}.cshtml",
+                "~/Areas/{2}/Views/{1}/{0}.vbhtml",
+                "~/Areas/{2}/Views/Shared/{0}.cshtml",
+                "~/Areas/{2}/Views/Shared/{0}.vbhtml"
+            };
+
+            ViewLocationFormats = new[] {
+                "~/Views/{1}/{0}.cshtml",
+                "~/Views/{1}/{0}.vbhtml",
+                "~/Views/Shared/{0}.cshtml",
+                "~/Views/Shared/{0}.vbhtml"
+            };
+            MasterLocationFormats = new[] {
+                "~/Views/{1}/{0}.cshtml",
+                "~/Views/{1}/{0}.vbhtml",
+                "~/Views/Shared/{0}.cshtml",
+                "~/Views/Shared/{0}.vbhtml"
+            };
+            PartialViewLocationFormats = new[] {
+                "~/Views/{1}/{0}.cshtml",
+                "~/Views/{1}/{0}.vbhtml",
+                "~/Views/Shared/{0}.cshtml",
+                "~/Views/Shared/{0}.vbhtml"
+            };
+
+            FileExtensions = new[] {
+                "cshtml",
+                "vbhtml",
+            };
+        }
+
+        protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath) {
+            return new RazorView(controllerContext, partialPath,
+                                 layoutPath: null, runViewStartPages: false, viewStartFileExtensions: FileExtensions, viewPageActivator: ViewPageActivator);
+        }
+
+        protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath) {
+            var view = new RazorView(controllerContext, viewPath,
+                                     layoutPath: masterPath, runViewStartPages: true, viewStartFileExtensions: FileExtensions, viewPageActivator: ViewPageActivator);
+            return view;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ReaderWriterCache`2.cs b/mcs/class/System.Web.Mvc3/Mvc/ReaderWriterCache`2.cs
new file mode 100644 (file)
index 0000000..6856240
--- /dev/null
@@ -0,0 +1,59 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Threading;
+
+    [SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Instances of this type are meant to be singletons.")]
+    internal abstract class ReaderWriterCache<TKey, TValue> {
+
+        private readonly Dictionary<TKey, TValue> _cache;
+        private readonly ReaderWriterLockSlim _rwLock = new ReaderWriterLockSlim();
+
+        protected ReaderWriterCache()
+            : this(null) {
+        }
+
+        protected ReaderWriterCache(IEqualityComparer<TKey> comparer) {
+            _cache = new Dictionary<TKey, TValue>(comparer);
+        }
+
+        protected Dictionary<TKey, TValue> Cache {
+            get {
+                return _cache;
+            }
+        }
+
+        protected TValue FetchOrCreateItem(TKey key, Func<TValue> creator) {
+            // first, see if the item already exists in the cache
+            _rwLock.EnterReadLock();
+            try {
+                TValue existingEntry;
+                if (_cache.TryGetValue(key, out existingEntry)) {
+                    return existingEntry;
+                }
+            }
+            finally {
+                _rwLock.ExitReadLock();
+            }
+
+            // insert the new item into the cache
+            TValue newEntry = creator();
+            _rwLock.EnterWriteLock();
+            try {
+                TValue existingEntry;
+                if (_cache.TryGetValue(key, out existingEntry)) {
+                    // another thread already inserted an item, so use that one
+                    return existingEntry;
+                }
+
+                _cache[key] = newEntry;
+                return newEntry;
+            }
+            finally {
+                _rwLock.ExitWriteLock();
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/RedirectResult.cs b/mcs/class/System.Web.Mvc3/Mvc/RedirectResult.cs
new file mode 100644 (file)
index 0000000..bb3e93d
--- /dev/null
@@ -0,0 +1,55 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Web.Mvc.Resources;
+
+    // represents a result that performs a redirection given some URI
+    public class RedirectResult : ActionResult {
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "0#", Justification = "Response.Redirect() takes its URI as a string parameter.")]
+        public RedirectResult(string url)
+            : this(url, permanent: false) {
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "0#", Justification = "Response.Redirect() takes its URI as a string parameter.")]
+        public RedirectResult(string url, bool permanent) {
+            if (String.IsNullOrEmpty(url)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "url");
+            }
+
+            Permanent = permanent;
+            Url = url;
+        }
+
+        public bool Permanent {
+            get;
+            private set;
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "Response.Redirect() takes its URI as a string parameter.")]
+        public string Url {
+            get;
+            private set;
+        }
+
+        public override void ExecuteResult(ControllerContext context) {
+            if (context == null) {
+                throw new ArgumentNullException("context");
+            }
+            if (context.IsChildAction) {
+                throw new InvalidOperationException(MvcResources.RedirectAction_CannotRedirectInChildAction);
+            }
+
+            string destinationUrl = UrlHelper.GenerateContentUrl(Url, context.HttpContext);
+            context.Controller.TempData.Keep();
+
+            if (Permanent) {
+                context.HttpContext.Response.RedirectPermanent(destinationUrl, endResponse: false);
+            }
+            else {
+                context.HttpContext.Response.Redirect(destinationUrl, endResponse: false);
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/RedirectToRouteResult.cs b/mcs/class/System.Web.Mvc3/Mvc/RedirectToRouteResult.cs
new file mode 100644 (file)
index 0000000..d45b634
--- /dev/null
@@ -0,0 +1,76 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Web.Mvc.Resources;
+    using System.Web.Routing;
+
+    // represents a result that performs a redirection given some values dictionary
+    public class RedirectToRouteResult : ActionResult {
+
+        private RouteCollection _routes;
+
+        public RedirectToRouteResult(RouteValueDictionary routeValues) :
+            this(null, routeValues) {
+        }
+
+        public RedirectToRouteResult(string routeName, RouteValueDictionary routeValues)
+            : this(routeName, routeValues, permanent: false) {
+        }
+
+        public RedirectToRouteResult(string routeName, RouteValueDictionary routeValues, bool permanent) {
+            Permanent = permanent;
+            RouteName = routeName ?? String.Empty;
+            RouteValues = routeValues ?? new RouteValueDictionary();
+        }
+
+        public bool Permanent {
+            get;
+            private set;
+        }
+
+        public string RouteName {
+            get;
+            private set;
+        }
+
+        public RouteValueDictionary RouteValues {
+            get;
+            private set;
+        }
+
+        internal RouteCollection Routes {
+            get {
+                if (_routes == null) {
+                    _routes = RouteTable.Routes;
+                }
+                return _routes;
+            }
+            set {
+                _routes = value;
+            }
+        }
+
+        public override void ExecuteResult(ControllerContext context) {
+            if (context == null) {
+                throw new ArgumentNullException("context");
+            }
+            if (context.IsChildAction) {
+                throw new InvalidOperationException(MvcResources.RedirectAction_CannotRedirectInChildAction);
+            }
+
+            string destinationUrl = UrlHelper.GenerateUrl(RouteName, null /* actionName */, null /* controllerName */, RouteValues, Routes, context.RequestContext, false /* includeImplicitMvcValues */);
+            if (String.IsNullOrEmpty(destinationUrl)) {
+                throw new InvalidOperationException(MvcResources.Common_NoRouteMatched);
+            }
+
+            context.Controller.TempData.Keep();
+
+            if (Permanent) {
+                context.HttpContext.Response.RedirectPermanent(destinationUrl, endResponse: false);
+            }
+            else {
+                context.HttpContext.Response.Redirect(destinationUrl, endResponse: false);
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ReflectedActionDescriptor.cs b/mcs/class/System.Web.Mvc3/Mvc/ReflectedActionDescriptor.cs
new file mode 100644 (file)
index 0000000..afedad5
--- /dev/null
@@ -0,0 +1,134 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Linq;
+    using System.Reflection;
+    using System.Web.Mvc.Resources;
+
+    public class ReflectedActionDescriptor : ActionDescriptor {
+
+        private readonly string _actionName;
+        private readonly ControllerDescriptor _controllerDescriptor;
+        private ParameterDescriptor[] _parametersCache;
+        private readonly Lazy<string> _uniqueId;
+
+        public ReflectedActionDescriptor(MethodInfo methodInfo, string actionName, ControllerDescriptor controllerDescriptor)
+            : this(methodInfo, actionName, controllerDescriptor, true /* validateMethod */) {
+        }
+
+        internal ReflectedActionDescriptor(MethodInfo methodInfo, string actionName, ControllerDescriptor controllerDescriptor, bool validateMethod) {
+            if (methodInfo == null) {
+                throw new ArgumentNullException("methodInfo");
+            }
+            if (String.IsNullOrEmpty(actionName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "actionName");
+            }
+            if (controllerDescriptor == null) {
+                throw new ArgumentNullException("controllerDescriptor");
+            }
+
+            if (validateMethod) {
+                string failedMessage = VerifyActionMethodIsCallable(methodInfo);
+                if (failedMessage != null) {
+                    throw new ArgumentException(failedMessage, "methodInfo");
+                }
+            }
+
+            MethodInfo = methodInfo;
+            _actionName = actionName;
+            _controllerDescriptor = controllerDescriptor;
+            _uniqueId = new Lazy<string>(CreateUniqueId);
+        }
+
+        public override string ActionName {
+            get {
+                return _actionName;
+            }
+        }
+
+        public override ControllerDescriptor ControllerDescriptor {
+            get {
+                return _controllerDescriptor;
+            }
+        }
+
+        public MethodInfo MethodInfo {
+            get;
+            private set;
+        }
+
+        public override string UniqueId {
+            get {
+                return _uniqueId.Value;
+            }
+        }
+
+        private string CreateUniqueId() {
+            return base.UniqueId + DescriptorUtil.CreateUniqueId(MethodInfo);
+        }
+
+        public override object Execute(ControllerContext controllerContext, IDictionary<string, object> parameters) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+            if (parameters == null) {
+                throw new ArgumentNullException("parameters");
+            }
+
+            ParameterInfo[] parameterInfos = MethodInfo.GetParameters();
+            var rawParameterValues = from parameterInfo in parameterInfos
+                                     select ExtractParameterFromDictionary(parameterInfo, parameters, MethodInfo);
+            object[] parametersArray = rawParameterValues.ToArray();
+
+            ActionMethodDispatcher dispatcher = DispatcherCache.GetDispatcher(MethodInfo);
+            object actionReturnValue = dispatcher.Execute(controllerContext.Controller, parametersArray);
+            return actionReturnValue;
+        }
+
+        public override object[] GetCustomAttributes(bool inherit) {
+            return MethodInfo.GetCustomAttributes(inherit);
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit) {
+            return MethodInfo.GetCustomAttributes(attributeType, inherit);
+        }
+
+        internal override IEnumerable<FilterAttribute> GetFilterAttributes(bool useCache) {
+            if (useCache && GetType() == typeof(ReflectedActionDescriptor)) {
+                // Do not look at cache in types derived from this type because they might incorrectly implement GetCustomAttributes
+                return ReflectedAttributeCache.GetMethodFilterAttributes(MethodInfo);
+            }
+            return base.GetFilterAttributes(useCache);
+        }
+
+        public override ParameterDescriptor[] GetParameters() {
+            ParameterDescriptor[] parameters = LazilyFetchParametersCollection();
+
+            // need to clone array so that user modifications aren't accidentally stored
+            return (ParameterDescriptor[])parameters.Clone();
+        }
+
+        public override ICollection<ActionSelector> GetSelectors() {
+            ActionMethodSelectorAttribute[] attrs = (ActionMethodSelectorAttribute[])MethodInfo.GetCustomAttributes(typeof(ActionMethodSelectorAttribute), true /* inherit */);
+            ActionSelector[] selectors = Array.ConvertAll(attrs, attr => (ActionSelector)(controllerContext => attr.IsValidForRequest(controllerContext, MethodInfo)));
+            return selectors;
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit) {
+            return MethodInfo.IsDefined(attributeType, inherit);
+        }
+
+        private ParameterDescriptor[] LazilyFetchParametersCollection() {
+            return DescriptorUtil.LazilyFetchOrCreateDescriptors<ParameterInfo, ParameterDescriptor>(
+                ref _parametersCache /* cacheLocation */,
+                MethodInfo.GetParameters /* initializer */,
+                parameterInfo => new ReflectedParameterDescriptor(parameterInfo, this) /* converter */);
+        }
+
+        internal static ReflectedActionDescriptor TryCreateDescriptor(MethodInfo methodInfo, string name, ControllerDescriptor controllerDescriptor) {
+            ReflectedActionDescriptor descriptor = new ReflectedActionDescriptor(methodInfo, name, controllerDescriptor, false /* validateMethod */);
+            string failedMessage = VerifyActionMethodIsCallable(methodInfo);
+            return (failedMessage == null) ? descriptor : null;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ReflectedAttributeCache.cs b/mcs/class/System.Web.Mvc3/Mvc/ReflectedAttributeCache.cs
new file mode 100644 (file)
index 0000000..a05ad25
--- /dev/null
@@ -0,0 +1,41 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Concurrent;
+    using System.Diagnostics;
+    using System.Reflection;
+    using System.Collections.Generic;
+    using System.Collections.ObjectModel;
+
+    internal static class ReflectedAttributeCache {
+        private static readonly ConcurrentDictionary<MethodInfo, ReadOnlyCollection<ActionMethodSelectorAttribute>> _actionMethodSelectorAttributeCache = new ConcurrentDictionary<MethodInfo, ReadOnlyCollection<ActionMethodSelectorAttribute>>();
+        private static readonly ConcurrentDictionary<MethodInfo, ReadOnlyCollection<ActionNameSelectorAttribute>> _actionNameSelectorAttributeCache = new ConcurrentDictionary<MethodInfo, ReadOnlyCollection<ActionNameSelectorAttribute>>();
+        private static readonly ConcurrentDictionary<MethodInfo, ReadOnlyCollection<FilterAttribute>> _methodFilterAttributeCache = new ConcurrentDictionary<MethodInfo, ReadOnlyCollection<FilterAttribute>>();
+
+        private static readonly ConcurrentDictionary<Type, ReadOnlyCollection<FilterAttribute>> _typeFilterAttributeCache = new ConcurrentDictionary<Type, ReadOnlyCollection<FilterAttribute>>();
+
+        public static ICollection<FilterAttribute> GetTypeFilterAttributes(Type type) {
+            return GetAttributes(_typeFilterAttributeCache, type);
+        }
+
+        public static ICollection<FilterAttribute> GetMethodFilterAttributes(MethodInfo methodInfo) {
+            return GetAttributes(_methodFilterAttributeCache, methodInfo);
+        }
+
+        public static ICollection<ActionMethodSelectorAttribute> GetActionMethodSelectorAttributes(MethodInfo methodInfo) {
+            return GetAttributes(_actionMethodSelectorAttributeCache, methodInfo);
+        }
+
+        public static ICollection<ActionNameSelectorAttribute> GetActionNameSelectorAttributes(MethodInfo methodInfo) {
+            return GetAttributes(_actionNameSelectorAttributeCache, methodInfo);
+        }
+
+        private static ReadOnlyCollection<TAttribute> GetAttributes<TMemberInfo, TAttribute>(ConcurrentDictionary<TMemberInfo, ReadOnlyCollection<TAttribute>> lookup, TMemberInfo memberInfo)
+            where TAttribute : Attribute
+            where TMemberInfo : MemberInfo {
+
+            Debug.Assert(memberInfo != null);
+            Debug.Assert(lookup != null);
+            return lookup.GetOrAdd(memberInfo, mi => new ReadOnlyCollection<TAttribute>((TAttribute[])memberInfo.GetCustomAttributes(typeof(TAttribute), inherit: true)));
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ReflectedControllerDescriptor.cs b/mcs/class/System.Web.Mvc3/Mvc/ReflectedControllerDescriptor.cs
new file mode 100644 (file)
index 0000000..486207f
--- /dev/null
@@ -0,0 +1,87 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Linq;
+    using System.Reflection;
+    using System.Web.Mvc.Resources;
+
+    public class ReflectedControllerDescriptor : ControllerDescriptor {
+
+        private ActionDescriptor[] _canonicalActionsCache;
+        private readonly Type _controllerType;
+        private readonly ActionMethodSelector _selector;
+
+        public ReflectedControllerDescriptor(Type controllerType) {
+            if (controllerType == null) {
+                throw new ArgumentNullException("controllerType");
+            }
+
+            _controllerType = controllerType;
+            _selector = new ActionMethodSelector(_controllerType);
+        }
+
+        public sealed override Type ControllerType {
+            get {
+                return _controllerType;
+            }
+        }
+
+        public override ActionDescriptor FindAction(ControllerContext controllerContext, string actionName) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+            if (String.IsNullOrEmpty(actionName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "actionName");
+            }
+
+            MethodInfo matched = _selector.FindActionMethod(controllerContext, actionName);
+            if (matched == null) {
+                return null;
+            }
+
+            return new ReflectedActionDescriptor(matched, actionName, this);
+        }
+
+        private MethodInfo[] GetAllActionMethodsFromSelector() {
+            List<MethodInfo> allValidMethods = new List<MethodInfo>();
+            allValidMethods.AddRange(_selector.AliasedMethods);
+            allValidMethods.AddRange(_selector.NonAliasedMethods.SelectMany(g => g));
+            return allValidMethods.ToArray();
+        }
+
+        public override ActionDescriptor[] GetCanonicalActions() {
+            ActionDescriptor[] actions = LazilyFetchCanonicalActionsCollection();
+
+            // need to clone array so that user modifications aren't accidentally stored
+            return (ActionDescriptor[])actions.Clone();
+        }
+
+        public override object[] GetCustomAttributes(bool inherit) {
+            return ControllerType.GetCustomAttributes(inherit);
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit) {
+            return ControllerType.GetCustomAttributes(attributeType, inherit);
+        }
+
+        internal override IEnumerable<FilterAttribute> GetFilterAttributes(bool useCache) {
+            if (useCache && GetType() == typeof(ReflectedControllerDescriptor)) {
+                // Do not look at cache in types derived from this type because they might incorrectly implement GetCustomAttributes
+                return ReflectedAttributeCache.GetTypeFilterAttributes(ControllerType);
+            }
+            return base.GetFilterAttributes(useCache);
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit) {
+            return ControllerType.IsDefined(attributeType, inherit);
+        }
+
+        private ActionDescriptor[] LazilyFetchCanonicalActionsCollection() {
+            return DescriptorUtil.LazilyFetchOrCreateDescriptors<MethodInfo, ActionDescriptor>(
+                ref _canonicalActionsCache /* cacheLocation */,
+                GetAllActionMethodsFromSelector /* initializer */,
+                methodInfo => ReflectedActionDescriptor.TryCreateDescriptor(methodInfo, methodInfo.Name, this) /* converter */);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ReflectedParameterBindingInfo.cs b/mcs/class/System.Web.Mvc3/Mvc/ReflectedParameterBindingInfo.cs
new file mode 100644 (file)
index 0000000..e145ee4
--- /dev/null
@@ -0,0 +1,61 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Collections.ObjectModel;
+    using System.Globalization;
+    using System.Reflection;
+    using System.Web.Mvc.Resources;
+
+    internal class ReflectedParameterBindingInfo : ParameterBindingInfo {
+
+        private ICollection<string> _exclude = new string[0];
+        private ICollection<string> _include = new string[0];
+        private readonly ParameterInfo _parameterInfo;
+        private string _prefix;
+
+        public ReflectedParameterBindingInfo(ParameterInfo parameterInfo) {
+            _parameterInfo = parameterInfo;
+            ReadSettingsFromBindAttribute();
+        }
+
+        public override IModelBinder Binder {
+            get {
+                IModelBinder binder = ModelBinders.GetBinderFromAttributes(_parameterInfo,
+                    () => String.Format(CultureInfo.CurrentCulture, MvcResources.ReflectedParameterBindingInfo_MultipleConverterAttributes,
+                        _parameterInfo.Name, _parameterInfo.Member));
+
+                return binder;
+            }
+        }
+
+        public override ICollection<string> Exclude {
+            get {
+                return _exclude;
+            }
+        }
+
+        public override ICollection<string> Include {
+            get {
+                return _include;
+            }
+        }
+
+        public override string Prefix {
+            get {
+                return _prefix;
+            }
+        }
+
+        private void ReadSettingsFromBindAttribute() {
+            BindAttribute attr = (BindAttribute)Attribute.GetCustomAttribute(_parameterInfo, typeof(BindAttribute));
+            if (attr == null) {
+                return;
+            }
+
+            _exclude = new ReadOnlyCollection<string>(AuthorizeAttribute.SplitString(attr.Exclude));
+            _include = new ReadOnlyCollection<string>(AuthorizeAttribute.SplitString(attr.Include));
+            _prefix = attr.Prefix;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ReflectedParameterDescriptor.cs b/mcs/class/System.Web.Mvc3/Mvc/ReflectedParameterDescriptor.cs
new file mode 100644 (file)
index 0000000..42f7d25
--- /dev/null
@@ -0,0 +1,78 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.ComponentModel;
+    using System.Reflection;
+
+    public class ReflectedParameterDescriptor : ParameterDescriptor {
+
+        private readonly ActionDescriptor _actionDescriptor;
+        private readonly ReflectedParameterBindingInfo _bindingInfo;
+
+        public ReflectedParameterDescriptor(ParameterInfo parameterInfo, ActionDescriptor actionDescriptor) {
+            if (parameterInfo == null) {
+                throw new ArgumentNullException("parameterInfo");
+            }
+            if (actionDescriptor == null) {
+                throw new ArgumentNullException("actionDescriptor");
+            }
+
+            ParameterInfo = parameterInfo;
+            _actionDescriptor = actionDescriptor;
+            _bindingInfo = new ReflectedParameterBindingInfo(parameterInfo);
+        }
+
+        public override ActionDescriptor ActionDescriptor {
+            get {
+                return _actionDescriptor;
+            }
+        }
+
+        public override ParameterBindingInfo BindingInfo {
+            get {
+                return _bindingInfo;
+            }
+        }
+
+        public override object DefaultValue {
+            get {
+                object value;
+                if (ParameterInfoUtil.TryGetDefaultValue(ParameterInfo, out value)) {
+                    return value;
+                }
+                else {
+                    return base.DefaultValue;
+                }
+            }
+        }
+
+        public ParameterInfo ParameterInfo {
+            get;
+            private set;
+        }
+
+        public override string ParameterName {
+            get {
+                return ParameterInfo.Name;
+            }
+        }
+
+        public override Type ParameterType {
+            get {
+                return ParameterInfo.ParameterType;
+            }
+        }
+
+        public override object[] GetCustomAttributes(bool inherit) {
+            return ParameterInfo.GetCustomAttributes(inherit);
+        }
+
+        public override object[] GetCustomAttributes(Type attributeType, bool inherit) {
+            return ParameterInfo.GetCustomAttributes(attributeType, inherit);
+        }
+
+        public override bool IsDefined(Type attributeType, bool inherit) {
+            return ParameterInfo.IsDefined(attributeType, inherit);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/RegularExpressionAttributeAdapter.cs b/mcs/class/System.Web.Mvc3/Mvc/RegularExpressionAttributeAdapter.cs
new file mode 100644 (file)
index 0000000..2de12ac
--- /dev/null
@@ -0,0 +1,14 @@
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+    using System.ComponentModel.DataAnnotations;
+
+    public class RegularExpressionAttributeAdapter : DataAnnotationsModelValidator<RegularExpressionAttribute> {
+        public RegularExpressionAttributeAdapter(ModelMetadata metadata, ControllerContext context, RegularExpressionAttribute attribute)
+            : base(metadata, context, attribute) {
+        }
+
+        public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() {
+            return new[] { new ModelClientValidationRegexRule(ErrorMessage, Attribute.Pattern) };
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/RemoteAttribute.cs b/mcs/class/System.Web.Mvc3/Mvc/RemoteAttribute.cs
new file mode 100644 (file)
index 0000000..e49fd98
--- /dev/null
@@ -0,0 +1,121 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.ComponentModel.DataAnnotations;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Web.Mvc.Resources;
+    using System.Web.Routing;
+
+    [AttributeUsage(AttributeTargets.Property)]
+    [SuppressMessage("Microsoft.Design", "CA1019:DefineAccessorsForAttributeArguments", Justification = "The constructor parameters are used to feed RouteData, which is public.")]
+    [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes", Justification = "This attribute is designed to be a base class for other attributes.")]
+    public class RemoteAttribute : ValidationAttribute, IClientValidatable {
+
+        private string _additionalFields;
+        private string[] _additonalFieldsSplit = new string[0];
+
+        protected RemoteAttribute()
+            : base(MvcResources.RemoteAttribute_RemoteValidationFailed) {
+            RouteData = new RouteValueDictionary();
+        }
+
+        public RemoteAttribute(string routeName)
+            : this() {
+            if (String.IsNullOrWhiteSpace(routeName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "routeName");
+            }
+
+            RouteName = routeName;
+        }
+
+        public RemoteAttribute(string action, string controller) :
+            this(action, controller, null /* areaName */) {
+        }
+
+        public RemoteAttribute(string action, string controller, string areaName)
+            : this() {
+            if (String.IsNullOrWhiteSpace(action)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "action");
+            }
+            if (String.IsNullOrWhiteSpace(controller)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "controller");
+            }
+
+            RouteData["controller"] = controller;
+            RouteData["action"] = action;
+
+            if (!String.IsNullOrWhiteSpace(areaName)) {
+                RouteData["area"] = areaName;
+            }
+        }
+
+        public string HttpMethod { get; set; }
+
+        public string AdditionalFields {
+            get {
+                return _additionalFields ?? String.Empty;
+            }
+            set {
+                _additionalFields = value;
+                _additonalFieldsSplit = AuthorizeAttribute.SplitString(value);
+            }
+        }
+
+        public string FormatAdditionalFieldsForClientValidation(string property) {
+            if (String.IsNullOrEmpty(property)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "property");
+            }
+
+            string delimitedAdditionalFields = FormatPropertyForClientValidation(property);
+
+            foreach (string field in _additonalFieldsSplit) {
+                delimitedAdditionalFields += "," + FormatPropertyForClientValidation(field);
+            }
+
+            return delimitedAdditionalFields;
+        }
+
+        public static string FormatPropertyForClientValidation(string property) {
+            if (String.IsNullOrEmpty(property)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "property");
+            }
+            return "*." + property;
+        }
+
+        protected RouteValueDictionary RouteData { get; private set; }
+
+        protected string RouteName { get; set; }
+
+        protected virtual RouteCollection Routes {
+            get {
+                return RouteTable.Routes;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings", Justification = "The value is a not a regular URL since it may contain ~/ ASP.NET-specific characters")]
+        protected virtual string GetUrl(ControllerContext controllerContext) {
+            var pathData = Routes.GetVirtualPathForArea(controllerContext.RequestContext,
+                                                        RouteName,
+                                                        RouteData);
+
+            if (pathData == null) {
+                throw new InvalidOperationException(MvcResources.RemoteAttribute_NoUrlFound);
+            }
+
+            return pathData.VirtualPath;
+        }
+
+        public override string FormatErrorMessage(string name) {
+            return string.Format(CultureInfo.CurrentCulture, ErrorMessageString, name);
+        }
+
+        public override bool IsValid(object value) {
+            return true;
+        }
+
+        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) {
+            yield return new ModelClientValidationRemoteRule(FormatErrorMessage(metadata.GetDisplayName()), GetUrl(context), HttpMethod, FormatAdditionalFieldsForClientValidation(metadata.PropertyName));
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/RequireHttpsAttribute.cs b/mcs/class/System.Web.Mvc3/Mvc/RequireHttpsAttribute.cs
new file mode 100644 (file)
index 0000000..723f1b6
--- /dev/null
@@ -0,0 +1,34 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Web.Mvc.Resources;
+
+    [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes", Justification = "Unsealed because type contains virtual extensibility points.")]
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
+    public class RequireHttpsAttribute : FilterAttribute, IAuthorizationFilter {
+
+        public virtual void OnAuthorization(AuthorizationContext filterContext) {
+            if (filterContext == null) {
+                throw new ArgumentNullException("filterContext");
+            }
+
+            if (!filterContext.HttpContext.Request.IsSecureConnection) {
+                HandleNonHttpsRequest(filterContext);
+            }
+        }
+
+        protected virtual void HandleNonHttpsRequest(AuthorizationContext filterContext) {
+            // only redirect for GET requests, otherwise the browser might not propagate the verb and request
+            // body correctly.
+
+            if (!String.Equals(filterContext.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase)) {
+                throw new InvalidOperationException(MvcResources.RequireHttpsAttribute_MustUseSsl);
+            }
+
+            // redirect to HTTPS version of page
+            string url = "https://" + filterContext.HttpContext.Request.Url.Host + filterContext.HttpContext.Request.RawUrl;
+            filterContext.Result = new RedirectResult(url);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/RequiredAttributeAdapter.cs b/mcs/class/System.Web.Mvc3/Mvc/RequiredAttributeAdapter.cs
new file mode 100644 (file)
index 0000000..458ad5b
--- /dev/null
@@ -0,0 +1,14 @@
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+    using System.ComponentModel.DataAnnotations;
+
+    public class RequiredAttributeAdapter : DataAnnotationsModelValidator<RequiredAttribute> {
+        public RequiredAttributeAdapter(ModelMetadata metadata, ControllerContext context, RequiredAttribute attribute)
+            : base(metadata, context, attribute) {
+        }
+
+        public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() {
+            return new[] { new ModelClientValidationRequiredRule(ErrorMessage) };
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Resources/MvcResources.Designer.cs b/mcs/class/System.Web.Mvc3/Mvc/Resources/MvcResources.Designer.cs
new file mode 100644 (file)
index 0000000..b306729
--- /dev/null
@@ -0,0 +1,1022 @@
+//------------------------------------------------------------------------------
+// <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 System.Web.Mvc.Resources {
+    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 MvcResources {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal MvcResources() {
+        }
+        
+        /// <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("System.Web.Mvc.Resources.MvcResources", typeof(MvcResources).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;
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The current request for action &apos;{0}&apos; on controller type &apos;{1}&apos; is ambiguous between the following action methods:{2}.
+        /// </summary>
+        internal static string ActionMethodSelector_AmbiguousMatch {
+            get {
+                return ResourceManager.GetString("ActionMethodSelector_AmbiguousMatch", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to {0} on type {1}.
+        /// </summary>
+        internal static string ActionMethodSelector_AmbiguousMatchType {
+            get {
+                return ResourceManager.GetString("ActionMethodSelector_AmbiguousMatchType", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Lookup for method &apos;{0}&apos; on controller type &apos;{1}&apos; failed because of an ambiguity between the following methods:{2}.
+        /// </summary>
+        internal static string AsyncActionMethodSelector_AmbiguousMethodMatch {
+            get {
+                return ResourceManager.GetString("AsyncActionMethodSelector_AmbiguousMethodMatch", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Could not locate a method named &apos;{0}&apos; on controller type {1}..
+        /// </summary>
+        internal static string AsyncActionMethodSelector_CouldNotFindMethod {
+            get {
+                return ResourceManager.GetString("AsyncActionMethodSelector_CouldNotFindMethod", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The provided IAsyncResult has already been consumed..
+        /// </summary>
+        internal static string AsyncCommon_AsyncResultAlreadyConsumed {
+            get {
+                return ResourceManager.GetString("AsyncCommon_AsyncResultAlreadyConsumed", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The controller of type &apos;{0}&apos; must subclass AsyncController or implement the IAsyncManagerContainer interface..
+        /// </summary>
+        internal static string AsyncCommon_ControllerMustImplementIAsyncManagerContainer {
+            get {
+                return ResourceManager.GetString("AsyncCommon_ControllerMustImplementIAsyncManagerContainer", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The provided IAsyncResult is not valid for this method..
+        /// </summary>
+        internal static string AsyncCommon_InvalidAsyncResult {
+            get {
+                return ResourceManager.GetString("AsyncCommon_InvalidAsyncResult", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The timeout value must be non-negative or Timeout.Infinite..
+        /// </summary>
+        internal static string AsyncCommon_InvalidTimeout {
+            get {
+                return ResourceManager.GetString("AsyncCommon_InvalidTimeout", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to AuthorizeAttribute cannot be used within a child action caching block..
+        /// </summary>
+        internal static string AuthorizeAttribute_CannotUseWithinChildActionCache {
+            get {
+                return ResourceManager.GetString("AuthorizeAttribute_CannotUseWithinChildActionCache", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The action &apos;{0}&apos; is accessible only by a child request..
+        /// </summary>
+        internal static string ChildActionOnlyAttribute_MustBeInChildRequest {
+            get {
+                return ResourceManager.GetString("ChildActionOnlyAttribute_MustBeInChildRequest", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The field {0} must be a number..
+        /// </summary>
+        internal static string ClientDataTypeModelValidatorProvider_FieldMustBeNumeric {
+            get {
+                return ResourceManager.GetString("ClientDataTypeModelValidatorProvider_FieldMustBeNumeric", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to No route in the route table matches the supplied values..
+        /// </summary>
+        internal static string Common_NoRouteMatched {
+            get {
+                return ResourceManager.GetString("Common_NoRouteMatched", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Value cannot be null or empty..
+        /// </summary>
+        internal static string Common_NullOrEmpty {
+            get {
+                return ResourceManager.GetString("Common_NullOrEmpty", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The partial view &apos;{0}&apos; was not found or no view engine supports the searched locations. The following locations were searched:{1}.
+        /// </summary>
+        internal static string Common_PartialViewNotFound {
+            get {
+                return ResourceManager.GetString("Common_PartialViewNotFound", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The property &apos;{0}&apos; cannot be null or empty..
+        /// </summary>
+        internal static string Common_PropertyCannotBeNullOrEmpty {
+            get {
+                return ResourceManager.GetString("Common_PropertyCannotBeNullOrEmpty", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The property {0}.{1} could not be found..
+        /// </summary>
+        internal static string Common_PropertyNotFound {
+            get {
+                return ResourceManager.GetString("Common_PropertyNotFound", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to False.
+        /// </summary>
+        internal static string Common_TriState_False {
+            get {
+                return ResourceManager.GetString("Common_TriState_False", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Not Set.
+        /// </summary>
+        internal static string Common_TriState_NotSet {
+            get {
+                return ResourceManager.GetString("Common_TriState_NotSet", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to True.
+        /// </summary>
+        internal static string Common_TriState_True {
+            get {
+                return ResourceManager.GetString("Common_TriState_True", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The type {0} must derive from {1}.
+        /// </summary>
+        internal static string Common_TypeMustDriveFromType {
+            get {
+                return ResourceManager.GetString("Common_TypeMustDriveFromType", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The value &apos;{0}&apos; is invalid..
+        /// </summary>
+        internal static string Common_ValueNotValidForProperty {
+            get {
+                return ResourceManager.GetString("Common_ValueNotValidForProperty", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The view &apos;{0}&apos; or its master was not found or no view engine supports the searched locations. The following locations were searched:{1}.
+        /// </summary>
+        internal static string Common_ViewNotFound {
+            get {
+                return ResourceManager.GetString("Common_ViewNotFound", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to &apos;{0}&apos; and &apos;{1}&apos; do not match..
+        /// </summary>
+        internal static string CompareAttribute_MustMatch {
+            get {
+                return ResourceManager.GetString("CompareAttribute_MustMatch", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Could not find a property named {0}..
+        /// </summary>
+        internal static string CompareAttribute_UnknownProperty {
+            get {
+                return ResourceManager.GetString("CompareAttribute_UnknownProperty", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to A public action method &apos;{0}&apos; was not found on controller &apos;{1}&apos;..
+        /// </summary>
+        internal static string Controller_UnknownAction {
+            get {
+                return ResourceManager.GetString("Controller_UnknownAction", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The model of type &apos;{0}&apos; could not be updated..
+        /// </summary>
+        internal static string Controller_UpdateModel_UpdateUnsuccessful {
+            get {
+                return ResourceManager.GetString("Controller_UpdateModel_UpdateUnsuccessful", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The model of type &apos;{0}&apos; is not valid..
+        /// </summary>
+        internal static string Controller_Validate_ValidationFailed {
+            get {
+                return ResourceManager.GetString("Controller_Validate_ValidationFailed", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Cannot execute Controller with a null HttpContext..
+        /// </summary>
+        internal static string ControllerBase_CannotExecuteWithNullHttpContext {
+            get {
+                return ResourceManager.GetString("ControllerBase_CannotExecuteWithNullHttpContext", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to A single instance of controller &apos;{0}&apos; cannot be used to handle multiple requests. If a custom controller factory is in use, make sure that it creates a new instance of the controller for each request..
+        /// </summary>
+        internal static string ControllerBase_CannotHandleMultipleRequests {
+            get {
+                return ResourceManager.GetString("ControllerBase_CannotHandleMultipleRequests", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to An error occurred when trying to create the IControllerFactory &apos;{0}&apos;. Make sure that the controller factory has a public parameterless constructor..
+        /// </summary>
+        internal static string ControllerBuilder_ErrorCreatingControllerFactory {
+            get {
+                return ResourceManager.GetString("ControllerBuilder_ErrorCreatingControllerFactory", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The IControllerFactory &apos;{0}&apos; did not return a controller for the name &apos;{1}&apos;..
+        /// </summary>
+        internal static string ControllerBuilder_FactoryReturnedNull {
+            get {
+                return ResourceManager.GetString("ControllerBuilder_FactoryReturnedNull", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The controller factory type &apos;{0}&apos; must implement the IControllerFactory interface..
+        /// </summary>
+        internal static string ControllerBuilder_MissingIControllerFactory {
+            get {
+                return ResourceManager.GetString("ControllerBuilder_MissingIControllerFactory", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The view found at &apos;{0}&apos; was not created..
+        /// </summary>
+        internal static string CshtmlView_ViewCouldNotBeCreated {
+            get {
+                return ResourceManager.GetString("CshtmlView_ViewCouldNotBeCreated", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The view at &apos;{0}&apos; must derive from WebViewPage, or WebViewPage&lt;TModel&gt;..
+        /// </summary>
+        internal static string CshtmlView_WrongViewBase {
+            get {
+                return ResourceManager.GetString("CshtmlView_WrongViewBase", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to {0} has a DisplayColumn attribute for {1}, but property {1} does not exist..
+        /// </summary>
+        internal static string DataAnnotationsModelMetadataProvider_UnknownProperty {
+            get {
+                return ResourceManager.GetString("DataAnnotationsModelMetadataProvider_UnknownProperty", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to {0} has a DisplayColumn attribute for {1}, but property {1} does not have a public getter..
+        /// </summary>
+        internal static string DataAnnotationsModelMetadataProvider_UnreadableProperty {
+            get {
+                return ResourceManager.GetString("DataAnnotationsModelMetadataProvider_UnreadableProperty", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The type {0} must have a public constructor which accepts three parameters of types {1}, {2}, and {3}.
+        /// </summary>
+        internal static string DataAnnotationsModelValidatorProvider_ConstructorRequirements {
+            get {
+                return ResourceManager.GetString("DataAnnotationsModelValidatorProvider_ConstructorRequirements", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The type {0} must have a public constructor which accepts two parameters of types {1} and {2}..
+        /// </summary>
+        internal static string DataAnnotationsModelValidatorProvider_ValidatableConstructorRequirements {
+            get {
+                return ResourceManager.GetString("DataAnnotationsModelValidatorProvider_ValidatableConstructorRequirements", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Multiple types were found that match the controller named &apos;{0}&apos;. This can happen if the route that services this request does not specify namespaces to search for a controller that matches the request. If this is the case, register this route by calling an overload of the &apos;MapRoute&apos; method that takes a &apos;namespaces&apos; parameter.
+        ///
+        ///The request for &apos;{0}&apos; has found the following matching controllers:{1}.
+        /// </summary>
+        internal static string DefaultControllerFactory_ControllerNameAmbiguous_WithoutRouteUrl {
+            get {
+                return ResourceManager.GetString("DefaultControllerFactory_ControllerNameAmbiguous_WithoutRouteUrl", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Multiple types were found that match the controller named &apos;{0}&apos;. This can happen if the route that services this request (&apos;{1}&apos;) does not specify namespaces to search for a controller that matches the request. If this is the case, register this route by calling an overload of the &apos;MapRoute&apos; method that takes a &apos;namespaces&apos; parameter.
+        ///
+        ///The request for &apos;{0}&apos; has found the following matching controllers:{2}.
+        /// </summary>
+        internal static string DefaultControllerFactory_ControllerNameAmbiguous_WithRouteUrl {
+            get {
+                return ResourceManager.GetString("DefaultControllerFactory_ControllerNameAmbiguous_WithRouteUrl", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to An error occurred when trying to create a controller of type &apos;{0}&apos;. Make sure that the controller has a parameterless public constructor..
+        /// </summary>
+        internal static string DefaultControllerFactory_ErrorCreatingController {
+            get {
+                return ResourceManager.GetString("DefaultControllerFactory_ErrorCreatingController", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The controller for path &apos;{0}&apos; was not found or does not implement IController..
+        /// </summary>
+        internal static string DefaultControllerFactory_NoControllerFound {
+            get {
+                return ResourceManager.GetString("DefaultControllerFactory_NoControllerFound", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The controller type &apos;{0}&apos; must implement IController..
+        /// </summary>
+        internal static string DefaultControllerFactory_TypeDoesNotSubclassControllerBase {
+            get {
+                return ResourceManager.GetString("DefaultControllerFactory_TypeDoesNotSubclassControllerBase", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The value &apos;{0}&apos; is not valid for {1}..
+        /// </summary>
+        internal static string DefaultModelBinder_ValueInvalid {
+            get {
+                return ResourceManager.GetString("DefaultModelBinder_ValueInvalid", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to A value is required..
+        /// </summary>
+        internal static string DefaultModelBinder_ValueRequired {
+            get {
+                return ResourceManager.GetString("DefaultModelBinder_ValueRequired", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The number of ticks for the TimeSpan value must be greater than or equal to 0..
+        /// </summary>
+        internal static string DefaultViewLocationCache_NegativeTimeSpan {
+            get {
+                return ResourceManager.GetString("DefaultViewLocationCache_NegativeTimeSpan", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The type {0} does not appear to implement Microsoft.Practices.ServiceLocation.IServiceLocator..
+        /// </summary>
+        internal static string DependencyResolver_DoesNotImplementICommonServiceLocator {
+            get {
+                return ResourceManager.GetString("DependencyResolver_DoesNotImplementICommonServiceLocator", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The type &apos;{0}&apos; does not inherit from Exception..
+        /// </summary>
+        internal static string ExceptionViewAttribute_NonExceptionType {
+            get {
+                return ResourceManager.GetString("ExceptionViewAttribute_NonExceptionType", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The expression compiler was unable to evaluate the indexer expression &apos;{0}&apos; because it references the model parameter &apos;{1}&apos; which is unavailable..
+        /// </summary>
+        internal static string ExpressionHelper_InvalidIndexerExpression {
+            get {
+                return ResourceManager.GetString("ExpressionHelper_InvalidIndexerExpression", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Order must be greater than or equal to -1..
+        /// </summary>
+        internal static string FilterAttribute_OrderOutOfRange {
+            get {
+                return ResourceManager.GetString("FilterAttribute_OrderOutOfRange", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The GET and POST HTTP methods are not supported..
+        /// </summary>
+        internal static string HtmlHelper_InvalidHttpMethod {
+            get {
+                return ResourceManager.GetString("HtmlHelper_InvalidHttpMethod", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The specified HttpVerbs value is not supported. The supported values are Delete, Head, and Put..
+        /// </summary>
+        internal static string HtmlHelper_InvalidHttpVerb {
+            get {
+                return ResourceManager.GetString("HtmlHelper_InvalidHttpVerb", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to There is no ViewData item of type &apos;{1}&apos; that has the key &apos;{0}&apos;..
+        /// </summary>
+        internal static string HtmlHelper_MissingSelectData {
+            get {
+                return ResourceManager.GetString("HtmlHelper_MissingSelectData", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The value must be greater than or equal to zero..
+        /// </summary>
+        internal static string HtmlHelper_TextAreaParameterOutOfRange {
+            get {
+                return ResourceManager.GetString("HtmlHelper_TextAreaParameterOutOfRange", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Validation parameter names in unobtrusive client validation rules cannot be empty. Client rule type: {0}.
+        /// </summary>
+        internal static string HtmlHelper_ValidationParameterCannotBeEmpty {
+            get {
+                return ResourceManager.GetString("HtmlHelper_ValidationParameterCannotBeEmpty", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Validation parameter names in unobtrusive client validation rules must start with a lowercase letter and consist of only lowercase letters or digits. Validation parameter name: {0}, client rule type: {1}.
+        /// </summary>
+        internal static string HtmlHelper_ValidationParameterMustBeLegal {
+            get {
+                return ResourceManager.GetString("HtmlHelper_ValidationParameterMustBeLegal", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Validation type names in unobtrusive client validation rules cannot be empty. Client rule type: {0}.
+        /// </summary>
+        internal static string HtmlHelper_ValidationTypeCannotBeEmpty {
+            get {
+                return ResourceManager.GetString("HtmlHelper_ValidationTypeCannotBeEmpty", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Validation type names in unobtrusive client validation rules must consist of only lowercase letters. Invalid name: &quot;{0}&quot;, client rule type: {1}.
+        /// </summary>
+        internal static string HtmlHelper_ValidationTypeMustBeLegal {
+            get {
+                return ResourceManager.GetString("HtmlHelper_ValidationTypeMustBeLegal", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Validation type names in unobtrusive client validation rules must be unique. The following validation type was seen more than once: {0}.
+        /// </summary>
+        internal static string HtmlHelper_ValidationTypeMustBeUnique {
+            get {
+                return ResourceManager.GetString("HtmlHelper_ValidationTypeMustBeUnique", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The ViewData item that has the key &apos;{0}&apos; is of type &apos;{1}&apos; but must be of type &apos;{2}&apos;..
+        /// </summary>
+        internal static string HtmlHelper_WrongSelectDataType {
+            get {
+                return ResourceManager.GetString("HtmlHelper_WrongSelectDataType", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet..
+        /// </summary>
+        internal static string JsonRequest_GetNotAllowed {
+            get {
+                return ResourceManager.GetString("JsonRequest_GetNotAllowed", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to An error occurred when trying to create the IModelBinder &apos;{0}&apos;. Make sure that the binder has a public parameterless constructor..
+        /// </summary>
+        internal static string ModelBinderAttribute_ErrorCreatingModelBinder {
+            get {
+                return ResourceManager.GetString("ModelBinderAttribute_ErrorCreatingModelBinder", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The type &apos;{0}&apos; does not implement the IModelBinder interface..
+        /// </summary>
+        internal static string ModelBinderAttribute_TypeNotIModelBinder {
+            get {
+                return ResourceManager.GetString("ModelBinderAttribute_TypeNotIModelBinder", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The type &apos;{0}&apos; contains multiple attributes that inherit from CustomModelBinderAttribute..
+        /// </summary>
+        internal static string ModelBinderDictionary_MultipleAttributes {
+            get {
+                return ResourceManager.GetString("ModelBinderDictionary_MultipleAttributes", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to This property setter is obsolete, because its value is derived from ModelMetadata.Model now..
+        /// </summary>
+        internal static string ModelMetadata_PropertyNotSettable {
+            get {
+                return ResourceManager.GetString("ModelMetadata_PropertyNotSettable", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The &apos;inherits&apos; keyword is not allowed when a &apos;{0}&apos; keyword is used..
+        /// </summary>
+        internal static string MvcRazorCodeParser_CannotHaveModelAndInheritsKeyword {
+            get {
+                return ResourceManager.GetString("MvcRazorCodeParser_CannotHaveModelAndInheritsKeyword", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The &apos;{0}&apos; keyword must be followed by a type name on the same line..
+        /// </summary>
+        internal static string MvcRazorCodeParser_ModelKeywordMustBeFollowedByTypeName {
+            get {
+                return ResourceManager.GetString("MvcRazorCodeParser_ModelKeywordMustBeFollowedByTypeName", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Only one &apos;{0}&apos; statement is allowed in a file..
+        /// </summary>
+        internal static string MvcRazorCodeParser_OnlyOneModelStatementIsAllowed {
+            get {
+                return ResourceManager.GetString("MvcRazorCodeParser_OnlyOneModelStatementIsAllowed", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to OutputCacheAttribute is not allowed on child actions which are children of an already cached child action..
+        /// </summary>
+        internal static string OutputCacheAttribute_CannotNestChildCache {
+            get {
+                return ResourceManager.GetString("OutputCacheAttribute_CannotNestChildCache", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to OutputCacheAttribute for child actions only supports Duration, VaryByCustom, and VaryByParam values. Please do not set CacheProfile, Location, NoStore, SqlDependency, VaryByContentEncoding, or VaryByHeader values for child actions..
+        /// </summary>
+        internal static string OutputCacheAttribute_ChildAction_UnsupportedSetting {
+            get {
+                return ResourceManager.GetString("OutputCacheAttribute_ChildAction_UnsupportedSetting", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Duration must be a positive number..
+        /// </summary>
+        internal static string OutputCacheAttribute_InvalidDuration {
+            get {
+                return ResourceManager.GetString("OutputCacheAttribute_InvalidDuration", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to VaryByParam must be &apos;*&apos;, &apos;none&apos;, or a semicolon-delimited list of keys..
+        /// </summary>
+        internal static string OutputCacheAttribute_InvalidVaryByParam {
+            get {
+                return ResourceManager.GetString("OutputCacheAttribute_InvalidVaryByParam", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The associated metadata type for type &apos;{0}&apos; contains the following unknown properties or fields: {1}. Please make sure that the names of these members match the names of the properties on the main type..
+        /// </summary>
+        internal static string PrivateAssociatedMetadataTypeTypeDescriptor_MetadataTypeContainsUnknownProperties {
+            get {
+                return ResourceManager.GetString("PrivateAssociatedMetadataTypeTypeDescriptor_MetadataTypeContainsUnknownProperties" +
+                        "", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Child actions are not allowed to perform redirect actions..
+        /// </summary>
+        internal static string RedirectAction_CannotRedirectInChildAction {
+            get {
+                return ResourceManager.GetString("RedirectAction_CannotRedirectInChildAction", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Cannot create a descriptor for instance method &apos;{0}&apos; on type &apos;{1}&apos; because the type does not derive from ControllerBase..
+        /// </summary>
+        internal static string ReflectedActionDescriptor_CannotCallInstanceMethodOnNonControllerType {
+            get {
+                return ResourceManager.GetString("ReflectedActionDescriptor_CannotCallInstanceMethodOnNonControllerType", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Cannot call action method &apos;{0}&apos; on controller &apos;{1}&apos; because the parameter &apos;{2}&apos; is passed by reference..
+        /// </summary>
+        internal static string ReflectedActionDescriptor_CannotCallMethodsWithOutOrRefParameters {
+            get {
+                return ResourceManager.GetString("ReflectedActionDescriptor_CannotCallMethodsWithOutOrRefParameters", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Cannot call action method &apos;{0}&apos; on controller &apos;{1}&apos; because the action method is a generic method..
+        /// </summary>
+        internal static string ReflectedActionDescriptor_CannotCallOpenGenericMethods {
+            get {
+                return ResourceManager.GetString("ReflectedActionDescriptor_CannotCallOpenGenericMethods", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Cannot call action method &apos;{0}&apos; on controller &apos;{1}&apos; because the action method is a static method..
+        /// </summary>
+        internal static string ReflectedActionDescriptor_CannotCallStaticMethod {
+            get {
+                return ResourceManager.GetString("ReflectedActionDescriptor_CannotCallStaticMethod", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The parameters dictionary contains a null entry for parameter &apos;{0}&apos; of non-nullable type &apos;{1}&apos; for method &apos;{2}&apos; in &apos;{3}&apos;. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter..
+        /// </summary>
+        internal static string ReflectedActionDescriptor_ParameterCannotBeNull {
+            get {
+                return ResourceManager.GetString("ReflectedActionDescriptor_ParameterCannotBeNull", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The parameters dictionary does not contain an entry for parameter &apos;{0}&apos; of type &apos;{1}&apos; for method &apos;{2}&apos; in &apos;{3}&apos;. The dictionary must contain an entry for each parameter, including parameters that have null values..
+        /// </summary>
+        internal static string ReflectedActionDescriptor_ParameterNotInDictionary {
+            get {
+                return ResourceManager.GetString("ReflectedActionDescriptor_ParameterNotInDictionary", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The parameters dictionary contains an invalid entry for parameter &apos;{0}&apos; for method &apos;{1}&apos; in &apos;{2}&apos;. The dictionary contains a value of type &apos;{3}&apos;, but the parameter requires a value of type &apos;{4}&apos;..
+        /// </summary>
+        internal static string ReflectedActionDescriptor_ParameterValueHasWrongType {
+            get {
+                return ResourceManager.GetString("ReflectedActionDescriptor_ParameterValueHasWrongType", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The asynchronous action method &apos;{0}&apos; cannot be executed synchronously..
+        /// </summary>
+        internal static string ReflectedAsyncActionDescriptor_CannotExecuteSynchronously {
+            get {
+                return ResourceManager.GetString("ReflectedAsyncActionDescriptor_CannotExecuteSynchronously", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The parameter &apos;{0}&apos; on method &apos;{1}&apos; contains multiple attributes that inherit from CustomModelBinderAttribute..
+        /// </summary>
+        internal static string ReflectedParameterBindingInfo_MultipleConverterAttributes {
+            get {
+                return ResourceManager.GetString("ReflectedParameterBindingInfo_MultipleConverterAttributes", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to No url for remote validation could be found..
+        /// </summary>
+        internal static string RemoteAttribute_NoUrlFound {
+            get {
+                return ResourceManager.GetString("RemoteAttribute_NoUrlFound", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to &apos;{0}&apos; is invalid..
+        /// </summary>
+        internal static string RemoteAttribute_RemoteValidationFailed {
+            get {
+                return ResourceManager.GetString("RemoteAttribute_RemoteValidationFailed", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The requested resource can only be accessed via SSL..
+        /// </summary>
+        internal static string RequireHttpsAttribute_MustUseSsl {
+            get {
+                return ResourceManager.GetString("RequireHttpsAttribute_MustUseSsl", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The SessionStateTempDataProvider class requires session state to be enabled..
+        /// </summary>
+        internal static string SessionStateTempDataProvider_SessionStateDisabled {
+            get {
+                return ResourceManager.GetString("SessionStateTempDataProvider_SessionStateDisabled", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to An instance of {0} was found in the resolver as well as a custom registered provider in {1}. Please set only one or the other..
+        /// </summary>
+        internal static string SingleServiceResolver_CannotRegisterTwoInstances {
+            get {
+                return ResourceManager.GetString("SingleServiceResolver_CannotRegisterTwoInstances", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to An operation that crossed a synchronization context failed. See the inner exception for more information..
+        /// </summary>
+        internal static string SynchronizationContextUtil_ExceptionThrown {
+            get {
+                return ResourceManager.GetString("SynchronizationContextUtil_ExceptionThrown", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Unable to locate an appropriate template for type {0}..
+        /// </summary>
+        internal static string TemplateHelpers_NoTemplate {
+            get {
+                return ResourceManager.GetString("TemplateHelpers_NoTemplate", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions..
+        /// </summary>
+        internal static string TemplateHelpers_TemplateLimitations {
+            get {
+                return ResourceManager.GetString("TemplateHelpers_TemplateLimitations", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The Collection template was used with an object of type &apos;{0}&apos;, which does not implement System.IEnumerable..
+        /// </summary>
+        internal static string Templates_TypeMustImplementIEnumerable {
+            get {
+                return ResourceManager.GetString("Templates_TypeMustImplementIEnumerable", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to This file is automatically generated. Please do not modify the contents of this file..
+        /// </summary>
+        internal static string TypeCache_DoNotModify {
+            get {
+                return ResourceManager.GetString("TypeCache_DoNotModify", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The model object inside the metadata claimed to be compatible with {0}, but was actually {1}..
+        /// </summary>
+        internal static string ValidatableObjectAdapter_IncompatibleType {
+            get {
+                return ResourceManager.GetString("ValidatableObjectAdapter_IncompatibleType", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The parameter conversion from type &apos;{0}&apos; to type &apos;{1}&apos; failed. See the inner exception for more information..
+        /// </summary>
+        internal static string ValueProviderResult_ConversionThrew {
+            get {
+                return ResourceManager.GetString("ValueProviderResult_ConversionThrew", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The parameter conversion from type &apos;{0}&apos; to type &apos;{1}&apos; failed because no type converter can convert between these types..
+        /// </summary>
+        internal static string ValueProviderResult_NoConverterExists {
+            get {
+                return ResourceManager.GetString("ValueProviderResult_NoConverterExists", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The model item passed into the dictionary is null, but this dictionary requires a non-null model item of type &apos;{0}&apos;..
+        /// </summary>
+        internal static string ViewDataDictionary_ModelCannotBeNull {
+            get {
+                return ResourceManager.GetString("ViewDataDictionary_ModelCannotBeNull", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The model item passed into the dictionary is of type &apos;{0}&apos;, but this dictionary requires a model item of type &apos;{1}&apos;..
+        /// </summary>
+        internal static string ViewDataDictionary_WrongTModelType {
+            get {
+                return ResourceManager.GetString("ViewDataDictionary_WrongTModelType", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to A ViewMasterPage can be used only with content pages that derive from ViewPage or ViewPage&lt;TModel&gt;..
+        /// </summary>
+        internal static string ViewMasterPage_RequiresViewPage {
+            get {
+                return ResourceManager.GetString("ViewMasterPage_RequiresViewPage", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Execution of the child request failed. Please examine the InnerException for more information..
+        /// </summary>
+        internal static string ViewPageHttpHandlerWrapper_ExceptionOccurred {
+            get {
+                return ResourceManager.GetString("ViewPageHttpHandlerWrapper_ExceptionOccurred", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to A ViewStartPage can be used only with with a page that derives from WebViewPage or another ViewStartPage..
+        /// </summary>
+        internal static string ViewStartPage_RequiresMvcRazorView {
+            get {
+                return ResourceManager.GetString("ViewStartPage_RequiresMvcRazorView", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The ViewUserControl &apos;{0}&apos; cannot find an IViewDataContainer object. The ViewUserControl must be inside a ViewPage, a ViewMasterPage, or another ViewUserControl..
+        /// </summary>
+        internal static string ViewUserControl_RequiresViewDataProvider {
+            get {
+                return ResourceManager.GetString("ViewUserControl_RequiresViewDataProvider", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to A ViewUserControl can be used only in pages that derive from ViewPage or ViewPage&lt;TModel&gt;..
+        /// </summary>
+        internal static string ViewUserControl_RequiresViewPage {
+            get {
+                return ResourceManager.GetString("ViewUserControl_RequiresViewPage", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to A master name cannot be specified when the view is a ViewUserControl..
+        /// </summary>
+        internal static string WebFormViewEngine_UserControlCannotHaveMaster {
+            get {
+                return ResourceManager.GetString("WebFormViewEngine_UserControlCannotHaveMaster", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The view found at &apos;{0}&apos; was not created..
+        /// </summary>
+        internal static string WebFormViewEngine_ViewCouldNotBeCreated {
+            get {
+                return ResourceManager.GetString("WebFormViewEngine_ViewCouldNotBeCreated", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The view at &apos;{0}&apos; must derive from ViewPage, ViewPage&lt;TModel&gt;, ViewUserControl, or ViewUserControl&lt;TModel&gt;..
+        /// </summary>
+        internal static string WebFormViewEngine_WrongViewBase {
+            get {
+                return ResourceManager.GetString("WebFormViewEngine_WrongViewBase", resourceCulture);
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/Resources/MvcResources.resx b/mcs/class/System.Web.Mvc3/Mvc/Resources/MvcResources.resx
new file mode 100644 (file)
index 0000000..32fb5f8
--- /dev/null
@@ -0,0 +1,442 @@
+<?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>
+  <data name="ActionMethodSelector_AmbiguousMatch" xml:space="preserve">
+    <value>The current request for action '{0}' on controller type '{1}' is ambiguous between the following action methods:{2}</value>
+  </data>
+  <data name="Common_NoRouteMatched" xml:space="preserve">
+    <value>No route in the route table matches the supplied values.</value>
+  </data>
+  <data name="Common_NullOrEmpty" xml:space="preserve">
+    <value>Value cannot be null or empty.</value>
+  </data>
+  <data name="Common_PartialViewNotFound" xml:space="preserve">
+    <value>The partial view '{0}' was not found or no view engine supports the searched locations. The following locations were searched:{1}</value>
+  </data>
+  <data name="Common_PropertyCannotBeNullOrEmpty" xml:space="preserve">
+    <value>The property '{0}' cannot be null or empty.</value>
+  </data>
+  <data name="Common_ViewNotFound" xml:space="preserve">
+    <value>The view '{0}' or its master was not found or no view engine supports the searched locations. The following locations were searched:{1}</value>
+  </data>
+  <data name="ControllerBuilder_ErrorCreatingControllerFactory" xml:space="preserve">
+    <value>An error occurred when trying to create the IControllerFactory '{0}'. Make sure that the controller factory has a public parameterless constructor.</value>
+  </data>
+  <data name="ControllerBuilder_FactoryReturnedNull" xml:space="preserve">
+    <value>The IControllerFactory '{0}' did not return a controller for the name '{1}'.</value>
+  </data>
+  <data name="ControllerBuilder_MissingIControllerFactory" xml:space="preserve">
+    <value>The controller factory type '{0}' must implement the IControllerFactory interface.</value>
+  </data>
+  <data name="Controller_UnknownAction" xml:space="preserve">
+    <value>A public action method '{0}' was not found on controller '{1}'.</value>
+  </data>
+  <data name="DefaultControllerFactory_ErrorCreatingController" xml:space="preserve">
+    <value>An error occurred when trying to create a controller of type '{0}'. Make sure that the controller has a parameterless public constructor.</value>
+  </data>
+  <data name="DefaultControllerFactory_NoControllerFound" xml:space="preserve">
+    <value>The controller for path '{0}' was not found or does not implement IController.</value>
+  </data>
+  <data name="DefaultControllerFactory_TypeDoesNotSubclassControllerBase" xml:space="preserve">
+    <value>The controller type '{0}' must implement IController.</value>
+  </data>
+  <data name="ValueProviderResult_ConversionThrew" xml:space="preserve">
+    <value>The parameter conversion from type '{0}' to type '{1}' failed. See the inner exception for more information.</value>
+  </data>
+  <data name="ValueProviderResult_NoConverterExists" xml:space="preserve">
+    <value>The parameter conversion from type '{0}' to type '{1}' failed because no type converter can convert between these types.</value>
+  </data>
+  <data name="ExceptionViewAttribute_NonExceptionType" xml:space="preserve">
+    <value>The type '{0}' does not inherit from Exception.</value>
+  </data>
+  <data name="FilterAttribute_OrderOutOfRange" xml:space="preserve">
+    <value>Order must be greater than or equal to -1.</value>
+  </data>
+  <data name="HtmlHelper_MissingSelectData" xml:space="preserve">
+    <value>There is no ViewData item of type '{1}' that has the key '{0}'.</value>
+  </data>
+  <data name="HtmlHelper_TextAreaParameterOutOfRange" xml:space="preserve">
+    <value>The value must be greater than or equal to zero.</value>
+  </data>
+  <data name="HtmlHelper_WrongSelectDataType" xml:space="preserve">
+    <value>The ViewData item that has the key '{0}' is of type '{1}' but must be of type '{2}'.</value>
+  </data>
+  <data name="ModelBinderAttribute_ErrorCreatingModelBinder" xml:space="preserve">
+    <value>An error occurred when trying to create the IModelBinder '{0}'. Make sure that the binder has a public parameterless constructor.</value>
+  </data>
+  <data name="ModelBinderAttribute_TypeNotIModelBinder" xml:space="preserve">
+    <value>The type '{0}' does not implement the IModelBinder interface.</value>
+  </data>
+  <data name="ModelBinderDictionary_MultipleAttributes" xml:space="preserve">
+    <value>The type '{0}' contains multiple attributes that inherit from CustomModelBinderAttribute.</value>
+  </data>
+  <data name="SessionStateTempDataProvider_SessionStateDisabled" xml:space="preserve">
+    <value>The SessionStateTempDataProvider class requires session state to be enabled.</value>
+  </data>
+  <data name="ViewDataDictionary_WrongTModelType" xml:space="preserve">
+    <value>The model item passed into the dictionary is of type '{0}', but this dictionary requires a model item of type '{1}'.</value>
+  </data>
+  <data name="ViewMasterPage_RequiresViewPage" xml:space="preserve">
+    <value>A ViewMasterPage can be used only with content pages that derive from ViewPage or ViewPage&lt;TModel&gt;.</value>
+  </data>
+  <data name="ViewUserControl_RequiresViewDataProvider" xml:space="preserve">
+    <value>The ViewUserControl '{0}' cannot find an IViewDataContainer object. The ViewUserControl must be inside a ViewPage, a ViewMasterPage, or another ViewUserControl.</value>
+  </data>
+  <data name="ViewUserControl_RequiresViewPage" xml:space="preserve">
+    <value>A ViewUserControl can be used only in pages that derive from ViewPage or ViewPage&lt;TModel&gt;.</value>
+  </data>
+  <data name="WebFormViewEngine_UserControlCannotHaveMaster" xml:space="preserve">
+    <value>A master name cannot be specified when the view is a ViewUserControl.</value>
+  </data>
+  <data name="WebFormViewEngine_ViewCouldNotBeCreated" xml:space="preserve">
+    <value>The view found at '{0}' was not created.</value>
+  </data>
+  <data name="WebFormViewEngine_WrongViewBase" xml:space="preserve">
+    <value>The view at '{0}' must derive from ViewPage, ViewPage&lt;TModel&gt;, ViewUserControl, or ViewUserControl&lt;TModel&gt;.</value>
+  </data>
+  <data name="Common_ValueNotValidForProperty" xml:space="preserve">
+    <value>The value '{0}' is invalid.</value>
+  </data>
+  <data name="ActionMethodSelector_AmbiguousMatchType" xml:space="preserve">
+    <value>{0} on type {1}</value>
+  </data>
+  <data name="Controller_UpdateModel_UpdateUnsuccessful" xml:space="preserve">
+    <value>The model of type '{0}' could not be updated.</value>
+  </data>
+  <data name="DefaultModelBinder_ValueRequired" xml:space="preserve">
+    <value>A value is required.</value>
+  </data>
+  <data name="ReflectedActionDescriptor_ParameterCannotBeNull" xml:space="preserve">
+    <value>The parameters dictionary contains a null entry for parameter '{0}' of non-nullable type '{1}' for method '{2}' in '{3}'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.</value>
+  </data>
+  <data name="ReflectedActionDescriptor_ParameterNotInDictionary" xml:space="preserve">
+    <value>The parameters dictionary does not contain an entry for parameter '{0}' of type '{1}' for method '{2}' in '{3}'. The dictionary must contain an entry for each parameter, including parameters that have null values.</value>
+  </data>
+  <data name="ReflectedActionDescriptor_ParameterValueHasWrongType" xml:space="preserve">
+    <value>The parameters dictionary contains an invalid entry for parameter '{0}' for method '{1}' in '{2}'. The dictionary contains a value of type '{3}', but the parameter requires a value of type '{4}'.</value>
+  </data>
+  <data name="ReflectedParameterBindingInfo_MultipleConverterAttributes" xml:space="preserve">
+    <value>The parameter '{0}' on method '{1}' contains multiple attributes that inherit from CustomModelBinderAttribute.</value>
+  </data>
+  <data name="ReflectedActionDescriptor_CannotCallInstanceMethodOnNonControllerType" xml:space="preserve">
+    <value>Cannot create a descriptor for instance method '{0}' on type '{1}' because the type does not derive from ControllerBase.</value>
+  </data>
+  <data name="ReflectedActionDescriptor_CannotCallMethodsWithOutOrRefParameters" xml:space="preserve">
+    <value>Cannot call action method '{0}' on controller '{1}' because the parameter '{2}' is passed by reference.</value>
+  </data>
+  <data name="ReflectedActionDescriptor_CannotCallOpenGenericMethods" xml:space="preserve">
+    <value>Cannot call action method '{0}' on controller '{1}' because the action method is a generic method.</value>
+  </data>
+  <data name="DefaultViewLocationCache_NegativeTimeSpan" xml:space="preserve">
+    <value>The number of ticks for the TimeSpan value must be greater than or equal to 0.</value>
+  </data>
+  <data name="DefaultModelBinder_ValueInvalid" xml:space="preserve">
+    <value>The value '{0}' is not valid for {1}.</value>
+  </data>
+  <data name="TemplateHelpers_TemplateLimitations" xml:space="preserve">
+    <value>Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.</value>
+  </data>
+  <data name="Common_TriState_False" xml:space="preserve">
+    <value>False</value>
+  </data>
+  <data name="Common_TriState_NotSet" xml:space="preserve">
+    <value>Not Set</value>
+  </data>
+  <data name="Common_TriState_True" xml:space="preserve">
+    <value>True</value>
+  </data>
+  <data name="ControllerBase_CannotHandleMultipleRequests" xml:space="preserve">
+    <value>A single instance of controller '{0}' cannot be used to handle multiple requests. If a custom controller factory is in use, make sure that it creates a new instance of the controller for each request.</value>
+  </data>
+  <data name="Common_PropertyNotFound" xml:space="preserve">
+    <value>The property {0}.{1} could not be found.</value>
+  </data>
+  <data name="DataAnnotationsModelMetadataProvider_UnknownProperty" xml:space="preserve">
+    <value>{0} has a DisplayColumn attribute for {1}, but property {1} does not exist.</value>
+  </data>
+  <data name="DataAnnotationsModelMetadataProvider_UnreadableProperty" xml:space="preserve">
+    <value>{0} has a DisplayColumn attribute for {1}, but property {1} does not have a public getter.</value>
+  </data>
+  <data name="TemplateHelpers_NoTemplate" xml:space="preserve">
+    <value>Unable to locate an appropriate template for type {0}.</value>
+  </data>
+  <data name="RequireHttpsAttribute_MustUseSsl" xml:space="preserve">
+    <value>The requested resource can only be accessed via SSL.</value>
+  </data>
+  <data name="HtmlHelper_InvalidHttpVerb" xml:space="preserve">
+    <value>The specified HttpVerbs value is not supported. The supported values are Delete, Head, and Put.</value>
+  </data>
+  <data name="HtmlHelper_InvalidHttpMethod" xml:space="preserve">
+    <value>The GET and POST HTTP methods are not supported.</value>
+  </data>
+  <data name="JsonRequest_GetNotAllowed" xml:space="preserve">
+    <value>This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet.</value>
+  </data>
+  <data name="ModelMetadata_PropertyNotSettable" xml:space="preserve">
+    <value>This property setter is obsolete, because its value is derived from ModelMetadata.Model now.</value>
+  </data>
+  <data name="ViewDataDictionary_ModelCannotBeNull" xml:space="preserve">
+    <value>The model item passed into the dictionary is null, but this dictionary requires a non-null model item of type '{0}'.</value>
+  </data>
+  <data name="Common_TypeMustDriveFromType" xml:space="preserve">
+    <value>The type {0} must derive from {1}</value>
+  </data>
+  <data name="DataAnnotationsModelValidatorProvider_ConstructorRequirements" xml:space="preserve">
+    <value>The type {0} must have a public constructor which accepts three parameters of types {1}, {2}, and {3}</value>
+  </data>
+  <data name="ViewPageHttpHandlerWrapper_ExceptionOccurred" xml:space="preserve">
+    <value>Execution of the child request failed. Please examine the InnerException for more information.</value>
+  </data>
+  <data name="RedirectAction_CannotRedirectInChildAction" xml:space="preserve">
+    <value>Child actions are not allowed to perform redirect actions.</value>
+  </data>
+  <data name="AsyncCommon_AsyncResultAlreadyConsumed" xml:space="preserve">
+    <value>The provided IAsyncResult has already been consumed.</value>
+  </data>
+  <data name="AsyncCommon_InvalidAsyncResult" xml:space="preserve">
+    <value>The provided IAsyncResult is not valid for this method.</value>
+  </data>
+  <data name="SynchronizationContextUtil_ExceptionThrown" xml:space="preserve">
+    <value>An operation that crossed a synchronization context failed. See the inner exception for more information.</value>
+  </data>
+  <data name="ReflectedAsyncActionDescriptor_CannotExecuteSynchronously" xml:space="preserve">
+    <value>The asynchronous action method '{0}' cannot be executed synchronously.</value>
+  </data>
+  <data name="AsyncCommon_ControllerMustImplementIAsyncManagerContainer" xml:space="preserve">
+    <value>The controller of type '{0}' must subclass AsyncController or implement the IAsyncManagerContainer interface.</value>
+  </data>
+  <data name="AsyncCommon_InvalidTimeout" xml:space="preserve">
+    <value>The timeout value must be non-negative or Timeout.Infinite.</value>
+  </data>
+  <data name="AsyncActionMethodSelector_AmbiguousMethodMatch" xml:space="preserve">
+    <value>Lookup for method '{0}' on controller type '{1}' failed because of an ambiguity between the following methods:{2}</value>
+  </data>
+  <data name="AsyncActionMethodSelector_CouldNotFindMethod" xml:space="preserve">
+    <value>Could not locate a method named '{0}' on controller type {1}.</value>
+  </data>
+  <data name="ChildActionOnlyAttribute_MustBeInChildRequest" xml:space="preserve">
+    <value>The action '{0}' is accessible only by a child request.</value>
+  </data>
+  <data name="Templates_TypeMustImplementIEnumerable" xml:space="preserve">
+    <value>The Collection template was used with an object of type '{0}', which does not implement System.IEnumerable.</value>
+  </data>
+  <data name="TypeCache_DoNotModify" xml:space="preserve">
+    <value>This file is automatically generated. Please do not modify the contents of this file.</value>
+  </data>
+  <data name="PrivateAssociatedMetadataTypeTypeDescriptor_MetadataTypeContainsUnknownProperties" xml:space="preserve">
+    <value>The associated metadata type for type '{0}' contains the following unknown properties or fields: {1}. Please make sure that the names of these members match the names of the properties on the main type.</value>
+  </data>
+  <data name="ClientDataTypeModelValidatorProvider_FieldMustBeNumeric" xml:space="preserve">
+    <value>The field {0} must be a number.</value>
+  </data>
+  <data name="ExpressionHelper_InvalidIndexerExpression" xml:space="preserve">
+    <value>The expression compiler was unable to evaluate the indexer expression '{0}' because it references the model parameter '{1}' which is unavailable.</value>
+  </data>
+  <data name="Controller_Validate_ValidationFailed" xml:space="preserve">
+    <value>The model of type '{0}' is not valid.</value>
+  </data>
+  <data name="DefaultControllerFactory_ControllerNameAmbiguous_WithoutRouteUrl" xml:space="preserve">
+    <value>Multiple types were found that match the controller named '{0}'. This can happen if the route that services this request does not specify namespaces to search for a controller that matches the request. If this is the case, register this route by calling an overload of the 'MapRoute' method that takes a 'namespaces' parameter.
+
+The request for '{0}' has found the following matching controllers:{1}</value>
+  </data>
+  <data name="DefaultControllerFactory_ControllerNameAmbiguous_WithRouteUrl" xml:space="preserve">
+    <value>Multiple types were found that match the controller named '{0}'. This can happen if the route that services this request ('{1}') does not specify namespaces to search for a controller that matches the request. If this is the case, register this route by calling an overload of the 'MapRoute' method that takes a 'namespaces' parameter.
+
+The request for '{0}' has found the following matching controllers:{2}</value>
+  </data>
+  <data name="DataAnnotationsModelValidatorProvider_ValidatableConstructorRequirements" xml:space="preserve">
+    <value>The type {0} must have a public constructor which accepts two parameters of types {1} and {2}.</value>
+  </data>
+  <data name="ValidatableObjectAdapter_IncompatibleType" xml:space="preserve">
+    <value>The model object inside the metadata claimed to be compatible with {0}, but was actually {1}.</value>
+  </data>
+  <data name="CshtmlView_ViewCouldNotBeCreated" xml:space="preserve">
+    <value>The view found at '{0}' was not created.</value>
+  </data>
+  <data name="CshtmlView_WrongViewBase" xml:space="preserve">
+    <value>The view at '{0}' must derive from WebViewPage, or WebViewPage&lt;TModel&gt;.</value>
+  </data>
+  <data name="ReflectedActionDescriptor_CannotCallStaticMethod" xml:space="preserve">
+    <value>Cannot call action method '{0}' on controller '{1}' because the action method is a static method.</value>
+  </data>
+  <data name="MvcRazorCodeParser_ModelKeywordMustBeFollowedByTypeName" xml:space="preserve">
+    <value>The '{0}' keyword must be followed by a type name on the same line.</value>
+  </data>
+  <data name="MvcRazorCodeParser_CannotHaveModelAndInheritsKeyword" xml:space="preserve">
+    <value>The 'inherits' keyword is not allowed when a '{0}' keyword is used.</value>
+  </data>
+  <data name="MvcRazorCodeParser_OnlyOneModelStatementIsAllowed" xml:space="preserve">
+    <value>Only one '{0}' statement is allowed in a file.</value>
+  </data>
+  <data name="SingleServiceResolver_CannotRegisterTwoInstances" xml:space="preserve">
+    <value>An instance of {0} was found in the resolver as well as a custom registered provider in {1}. Please set only one or the other.</value>
+  </data>
+  <data name="DependencyResolver_DoesNotImplementICommonServiceLocator" xml:space="preserve">
+    <value>The type {0} does not appear to implement Microsoft.Practices.ServiceLocation.IServiceLocator.</value>
+  </data>
+  <data name="HtmlHelper_ValidationTypeCannotBeEmpty" xml:space="preserve">
+    <value>Validation type names in unobtrusive client validation rules cannot be empty. Client rule type: {0}</value>
+  </data>
+  <data name="HtmlHelper_ValidationTypeMustBeUnique" xml:space="preserve">
+    <value>Validation type names in unobtrusive client validation rules must be unique. The following validation type was seen more than once: {0}</value>
+  </data>
+  <data name="HtmlHelper_ValidationTypeMustBeLegal" xml:space="preserve">
+    <value>Validation type names in unobtrusive client validation rules must consist of only lowercase letters. Invalid name: "{0}", client rule type: {1}</value>
+  </data>
+  <data name="HtmlHelper_ValidationParameterCannotBeEmpty" xml:space="preserve">
+    <value>Validation parameter names in unobtrusive client validation rules cannot be empty. Client rule type: {0}</value>
+  </data>
+  <data name="HtmlHelper_ValidationParameterMustBeLegal" xml:space="preserve">
+    <value>Validation parameter names in unobtrusive client validation rules must start with a lowercase letter and consist of only lowercase letters or digits. Validation parameter name: {0}, client rule type: {1}</value>
+  </data>
+  <data name="ViewStartPage_RequiresMvcRazorView" xml:space="preserve">
+    <value>A ViewStartPage can be used only with with a page that derives from WebViewPage or another ViewStartPage.</value>
+  </data>
+  <data name="ControllerBase_CannotExecuteWithNullHttpContext" xml:space="preserve">
+    <value>Cannot execute Controller with a null HttpContext.</value>
+  </data>
+  <data name="CompareAttribute_MustMatch" xml:space="preserve">
+    <value>'{0}' and '{1}' do not match.</value>
+  </data>
+  <data name="RemoteAttribute_RemoteValidationFailed" xml:space="preserve">
+    <value>'{0}' is invalid.</value>
+  </data>
+  <data name="RemoteAttribute_NoUrlFound" xml:space="preserve">
+    <value>No url for remote validation could be found.</value>
+  </data>
+  <data name="AuthorizeAttribute_CannotUseWithinChildActionCache" xml:space="preserve">
+    <value>AuthorizeAttribute cannot be used within a child action caching block.</value>
+  </data>
+  <data name="OutputCacheAttribute_InvalidDuration" xml:space="preserve">
+    <value>Duration must be a positive number.</value>
+  </data>
+  <data name="OutputCacheAttribute_InvalidVaryByParam" xml:space="preserve">
+    <value>VaryByParam must be '*', 'none', or a semicolon-delimited list of keys.</value>
+  </data>
+  <data name="OutputCacheAttribute_ChildAction_UnsupportedSetting" xml:space="preserve">
+    <value>OutputCacheAttribute for child actions only supports Duration, VaryByCustom, and VaryByParam values. Please do not set CacheProfile, Location, NoStore, SqlDependency, VaryByContentEncoding, or VaryByHeader values for child actions.</value>
+  </data>
+  <data name="OutputCacheAttribute_CannotNestChildCache" xml:space="preserve">
+    <value>OutputCacheAttribute is not allowed on child actions which are children of an already cached child action.</value>
+  </data>
+  <data name="CompareAttribute_UnknownProperty" xml:space="preserve">
+    <value>Could not find a property named {0}.</value>
+  </data>
+</root>
\ No newline at end of file
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ResultExecutedContext.cs b/mcs/class/System.Web.Mvc3/Mvc/ResultExecutedContext.cs
new file mode 100644 (file)
index 0000000..bc7eeb3
--- /dev/null
@@ -0,0 +1,44 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+
+    public class ResultExecutedContext : ControllerContext {
+
+        // parameterless constructor used for mocking
+        public ResultExecutedContext() {
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", Justification = "The virtual property setters are only to support mocking frameworks, in which case this constructor shouldn't be called anyway.")]
+        public ResultExecutedContext(ControllerContext controllerContext, ActionResult result, bool canceled, Exception exception)
+            : base(controllerContext) {
+            if (result == null) {
+                throw new ArgumentNullException("result");
+            }
+
+            Result = result;
+            Canceled = canceled;
+            Exception = exception;
+        }
+
+        public virtual bool Canceled {
+            get;
+            set;
+        }
+
+        public virtual Exception Exception {
+            get;
+            set;
+        }
+
+        public bool ExceptionHandled {
+            get;
+            set;
+        }
+
+        public virtual ActionResult Result {
+            get;
+            set;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ResultExecutingContext.cs b/mcs/class/System.Web.Mvc3/Mvc/ResultExecutingContext.cs
new file mode 100644 (file)
index 0000000..ab472f1
--- /dev/null
@@ -0,0 +1,32 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+
+    public class ResultExecutingContext : ControllerContext {
+
+        // parameterless constructor used for mocking
+        public ResultExecutingContext() {
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", Justification = "The virtual property setters are only to support mocking frameworks, in which case this constructor shouldn't be called anyway.")]
+        public ResultExecutingContext(ControllerContext controllerContext, ActionResult result)
+            : base(controllerContext) {
+            if (result == null) {
+                throw new ArgumentNullException("result");
+            }
+
+            Result = result;
+        }
+
+        public bool Cancel {
+            get;
+            set;
+        }
+
+        public virtual ActionResult Result {
+            get;
+            set;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/RouteCollectionExtensions.cs b/mcs/class/System.Web.Mvc3/Mvc/RouteCollectionExtensions.cs
new file mode 100644 (file)
index 0000000..6233dd0
--- /dev/null
@@ -0,0 +1,161 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Web.Routing;
+
+    public static class RouteCollectionExtensions {
+
+        // This method returns a new RouteCollection containing only routes that matched a particular area.
+        // The Boolean out parameter is just a flag specifying whether any registered routes were area-aware.
+        private static RouteCollection FilterRouteCollectionByArea(RouteCollection routes, string areaName, out bool usingAreas) {
+            if (areaName == null) {
+                areaName = String.Empty;
+            }
+
+            usingAreas = false;
+            RouteCollection filteredRoutes = new RouteCollection();
+
+            using (routes.GetReadLock()) {
+                foreach (RouteBase route in routes) {
+                    string thisAreaName = AreaHelpers.GetAreaName(route) ?? String.Empty;
+                    usingAreas |= (thisAreaName.Length > 0);
+                    if (String.Equals(thisAreaName, areaName, StringComparison.OrdinalIgnoreCase)) {
+                        filteredRoutes.Add(route);
+                    }
+                }
+            }
+
+            // if areas are not in use, the filtered route collection might be incorrect
+            return (usingAreas) ? filteredRoutes : routes;
+        }
+
+        public static VirtualPathData GetVirtualPathForArea(this RouteCollection routes, RequestContext requestContext, RouteValueDictionary values) {
+            return GetVirtualPathForArea(routes, requestContext, null /* name */, values);
+        }
+
+        public static VirtualPathData GetVirtualPathForArea(this RouteCollection routes, RequestContext requestContext, string name, RouteValueDictionary values) {
+            bool usingAreas; // don't care about this value
+            return GetVirtualPathForArea(routes, requestContext, name, values, out usingAreas);
+        }
+
+        internal static VirtualPathData GetVirtualPathForArea(this RouteCollection routes, RequestContext requestContext, string name, RouteValueDictionary values, out bool usingAreas) {
+            if (routes == null) {
+                throw new ArgumentNullException("routes");
+            }
+
+            if (!String.IsNullOrEmpty(name)) {
+                // the route name is a stronger qualifier than the area name, so just pipe it through
+                usingAreas = false;
+                return routes.GetVirtualPath(requestContext, name, values);
+            }
+
+            string targetArea = null;
+            if (values != null) {
+                object targetAreaRawValue;
+                if (values.TryGetValue("area", out targetAreaRawValue)) {
+                    targetArea = targetAreaRawValue as string;
+                }
+                else {
+                    // set target area to current area
+                    if (requestContext != null) {
+                        targetArea = AreaHelpers.GetAreaName(requestContext.RouteData);
+                    }
+                }
+            }
+
+            // need to apply a correction to the RVD if areas are in use
+            RouteValueDictionary correctedValues = values;
+            RouteCollection filteredRoutes = FilterRouteCollectionByArea(routes, targetArea, out usingAreas);
+            if (usingAreas) {
+                correctedValues = new RouteValueDictionary(values);
+                correctedValues.Remove("area");
+            }
+
+            VirtualPathData vpd = filteredRoutes.GetVirtualPath(requestContext, correctedValues);
+            return vpd;
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#", Justification = "This is not a regular URL as it may contain special routing characters.")]
+        public static void IgnoreRoute(this RouteCollection routes, string url) {
+            IgnoreRoute(routes, url, null /* constraints */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#", Justification = "This is not a regular URL as it may contain special routing characters.")]
+        public static void IgnoreRoute(this RouteCollection routes, string url, object constraints) {
+            if (routes == null) {
+                throw new ArgumentNullException("routes");
+            }
+            if (url == null) {
+                throw new ArgumentNullException("url");
+            }
+
+            IgnoreRouteInternal route = new IgnoreRouteInternal(url) {
+                Constraints = new RouteValueDictionary(constraints)
+            };
+
+            routes.Add(route);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "This is not a regular URL as it may contain special routing characters.")]
+        public static Route MapRoute(this RouteCollection routes, string name, string url) {
+            return MapRoute(routes, name, url, null /* defaults */, (object)null /* constraints */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "This is not a regular URL as it may contain special routing characters.")]
+        public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults) {
+            return MapRoute(routes, name, url, defaults, (object)null /* constraints */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "This is not a regular URL as it may contain special routing characters.")]
+        public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints) {
+            return MapRoute(routes, name, url, defaults, constraints, null /* namespaces */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "This is not a regular URL as it may contain special routing characters.")]
+        public static Route MapRoute(this RouteCollection routes, string name, string url, string[] namespaces) {
+            return MapRoute(routes, name, url, null /* defaults */, null /* constraints */, namespaces);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "This is not a regular URL as it may contain special routing characters.")]
+        public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, string[] namespaces) {
+            return MapRoute(routes, name, url, defaults, null /* constraints */, namespaces);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "This is not a regular URL as it may contain special routing characters.")]
+        public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces) {
+            if (routes == null) {
+                throw new ArgumentNullException("routes");
+            }
+            if (url == null) {
+                throw new ArgumentNullException("url");
+            }
+
+            Route route = new Route(url, new MvcRouteHandler()) {
+                Defaults = new RouteValueDictionary(defaults),
+                Constraints = new RouteValueDictionary(constraints),
+                DataTokens = new RouteValueDictionary()
+            };
+
+            if ((namespaces != null) && (namespaces.Length > 0)) {
+                route.DataTokens["Namespaces"] = namespaces;
+            }
+
+            routes.Add(name, route);
+
+            return route;
+        }
+
+        private sealed class IgnoreRouteInternal : Route {
+            public IgnoreRouteInternal(string url)
+                : base(url, new StopRoutingHandler()) {
+            }
+
+            public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary routeValues) {
+                // Never match during route generation. This avoids the scenario where an IgnoreRoute with
+                // fairly relaxed constraints ends up eagerly matching all generated URLs.
+                return null;
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/RouteDataValueProvider.cs b/mcs/class/System.Web.Mvc3/Mvc/RouteDataValueProvider.cs
new file mode 100644 (file)
index 0000000..5e79a82
--- /dev/null
@@ -0,0 +1,14 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Globalization;
+
+    public sealed class RouteDataValueProvider : DictionaryValueProvider<object> {
+
+        // RouteData should use the invariant culture since it's part of the URL, and the URL should be
+        // interpreted in a uniform fashion regardless of the origin of a particular request.
+        public RouteDataValueProvider(ControllerContext controllerContext)
+            : base(controllerContext.RouteData.Values, CultureInfo.InvariantCulture) {
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/RouteDataValueProviderFactory.cs b/mcs/class/System.Web.Mvc3/Mvc/RouteDataValueProviderFactory.cs
new file mode 100644 (file)
index 0000000..90f0535
--- /dev/null
@@ -0,0 +1,15 @@
+namespace System.Web.Mvc {
+    using System;
+
+    public sealed class RouteDataValueProviderFactory : ValueProviderFactory {
+
+        public override IValueProvider GetValueProvider(ControllerContext controllerContext) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+
+            return new RouteDataValueProvider(controllerContext);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/RouteValuesHelpers.cs b/mcs/class/System.Web.Mvc3/Mvc/RouteValuesHelpers.cs
new file mode 100644 (file)
index 0000000..0bf1406
--- /dev/null
@@ -0,0 +1,49 @@
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+    using System.Web.Routing;
+
+    internal static class RouteValuesHelpers {
+        public static RouteValueDictionary GetRouteValues(RouteValueDictionary routeValues) {
+            return (routeValues != null) ? new RouteValueDictionary(routeValues) : new RouteValueDictionary();
+        }
+
+        public static RouteValueDictionary MergeRouteValues(string actionName, string controllerName, RouteValueDictionary implicitRouteValues, RouteValueDictionary routeValues, bool includeImplicitMvcValues) {
+            // Create a new dictionary containing implicit and auto-generated values
+            RouteValueDictionary mergedRouteValues = new RouteValueDictionary();
+
+            if (includeImplicitMvcValues) {
+                // We only include MVC-specific values like 'controller' and 'action' if we are generating an action link.
+                // If we are generating a route link [as to MapRoute("Foo", "any/url", new { controller = ... })], including
+                // the current controller name will cause the route match to fail if the current controller is not the same
+                // as the destination controller.
+
+                object implicitValue;
+                if (implicitRouteValues != null && implicitRouteValues.TryGetValue("action", out implicitValue)) {
+                    mergedRouteValues["action"] = implicitValue;
+                }
+
+                if (implicitRouteValues != null && implicitRouteValues.TryGetValue("controller", out implicitValue)) {
+                    mergedRouteValues["controller"] = implicitValue;
+                }
+            }
+
+            // Merge values from the user's dictionary/object
+            if (routeValues != null) {
+                foreach (KeyValuePair<string, object> routeElement in GetRouteValues(routeValues)) {
+                    mergedRouteValues[routeElement.Key] = routeElement.Value;
+                }
+            }
+
+            // Merge explicit parameters when not null
+            if (actionName != null) {
+                mergedRouteValues["action"] = actionName;
+            }
+
+            if (controllerName != null) {
+                mergedRouteValues["controller"] = controllerName;
+            }
+
+            return mergedRouteValues;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/SecurityUtil.cs b/mcs/class/System.Web.Mvc3/Mvc/SecurityUtil.cs
new file mode 100644 (file)
index 0000000..bff5346
--- /dev/null
@@ -0,0 +1,66 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Reflection;
+    using System.Security;
+
+    internal static class SecurityUtil {
+
+        private static Action<Action> _callInAppTrustThunk;
+
+        // !! IMPORTANT !!
+        // Do not try to optimize this method or perform any extra caching; doing so could lead to MVC not operating
+        // correctly until the AppDomain is restarted.
+        [SuppressMessage("Microsoft.Security", "CA2107:ReviewDenyAndPermitOnlyUsage",
+            Justification = "This is essentially the same logic as Page.ProcessRequest.")]
+        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes",
+            Justification = "If an exception is thrown, assume we're running in same trust level as the application itself, so we don't need to do anything special.")]
+        private static Action<Action> GetCallInAppTrustThunk() {
+            // do we need to create the thunk?
+            if (_callInAppTrustThunk == null) {
+                try {
+                    if (!typeof(SecurityUtil).Assembly.IsFullyTrusted /* bin-deployed */
+                        || AppDomain.CurrentDomain.IsHomogenous /* .NET 4 CAS model */) {
+                        // we're already running in the application's trust level, so nothing to do
+                        _callInAppTrustThunk = f => f();
+                    }
+                    else {
+                        // legacy CAS model - need to lower own permission level to be compatible with legacy systems
+                        // This is essentially the same logic as Page.ProcessRequest(HttpContext)
+                        NamedPermissionSet namedPermissionSet = (NamedPermissionSet)typeof(HttpRuntime).GetProperty("NamedPermissionSet", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static).GetValue(null, null);
+                        bool disableProcessRequestInApplicationTrust = (bool)typeof(HttpRuntime).GetProperty("DisableProcessRequestInApplicationTrust", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static).GetValue(null, null);
+                        if (namedPermissionSet != null && !disableProcessRequestInApplicationTrust) {
+                            _callInAppTrustThunk = f => {
+                                // lower permissions
+                                namedPermissionSet.PermitOnly();
+                                f();
+                            };
+                        }
+                        else {
+                            // application's trust level is FullTrust, so nothing to do
+                            _callInAppTrustThunk = f => f();
+                        }
+                    }
+                }
+                catch {
+                    // MVC assembly is already running in application trust, so swallow exceptions
+                }
+            }
+
+            // if there was an error, just process transparently
+            return _callInAppTrustThunk ?? (Action<Action>)(f => f());
+        }
+
+        public static TResult ProcessInApplicationTrust<TResult>(Func<TResult> func) {
+            TResult result = default(TResult);
+            ProcessInApplicationTrust(delegate { result = func(); });
+            return result;
+        }
+
+        public static void ProcessInApplicationTrust(Action action) {
+            Action<Action> executor = GetCallInAppTrustThunk();
+            executor(action);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/SelectList.cs b/mcs/class/System.Web.Mvc3/Mvc/SelectList.cs
new file mode 100644 (file)
index 0000000..8b1651a
--- /dev/null
@@ -0,0 +1,34 @@
+namespace System.Web.Mvc {
+    using System.Collections;
+    using System.Diagnostics.CodeAnalysis;
+
+    [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
+    public class SelectList : MultiSelectList {
+
+        public SelectList(IEnumerable items)
+            : this(items, null /* selectedValue */) {
+        }
+
+        public SelectList(IEnumerable items, object selectedValue)
+            : this(items, null /* dataValuefield */, null /* dataTextField */, selectedValue) {
+        }
+
+        public SelectList(IEnumerable items, string dataValueField, string dataTextField)
+            : this(items, dataValueField, dataTextField, null /* selectedValue */) {
+        }
+
+        public SelectList(IEnumerable items, string dataValueField, string dataTextField, object selectedValue)
+            : base(items, dataValueField, dataTextField, ToEnumerable(selectedValue)) {
+            SelectedValue = selectedValue;
+        }
+
+        public object SelectedValue {
+            get;
+            private set;
+        }
+
+        private static IEnumerable ToEnumerable(object selectedValue) {
+            return (selectedValue != null) ? new object[] { selectedValue } : null;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/SelectListItem.cs b/mcs/class/System.Web.Mvc3/Mvc/SelectListItem.cs
new file mode 100644 (file)
index 0000000..786b1de
--- /dev/null
@@ -0,0 +1,20 @@
+namespace System.Web.Mvc {
+
+    public class SelectListItem {
+
+        public bool Selected {
+            get;
+            set;
+        }
+
+        public string Text {
+            get;
+            set;
+        }
+
+        public string Value {
+            get;
+            set;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/SessionStateAttribute.cs b/mcs/class/System.Web.Mvc3/Mvc/SessionStateAttribute.cs
new file mode 100644 (file)
index 0000000..2069350
--- /dev/null
@@ -0,0 +1,17 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Web.SessionState;
+
+    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
+    public sealed class SessionStateAttribute : Attribute {
+
+        public SessionStateAttribute(SessionStateBehavior behavior) {
+            Behavior = behavior;
+        }
+
+        public SessionStateBehavior Behavior {
+            get;
+            private set;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/SessionStateTempDataProvider.cs b/mcs/class/System.Web.Mvc3/Mvc/SessionStateTempDataProvider.cs
new file mode 100644 (file)
index 0000000..cc95a32
--- /dev/null
@@ -0,0 +1,53 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Web.Mvc.Resources;
+
+    public class SessionStateTempDataProvider : ITempDataProvider {
+        internal const string TempDataSessionStateKey = "__ControllerTempData";
+
+        public virtual IDictionary<string, object> LoadTempData(ControllerContext controllerContext) {
+            HttpSessionStateBase session = controllerContext.HttpContext.Session;
+
+            if (session != null) {
+                Dictionary<string, object> tempDataDictionary = session[TempDataSessionStateKey] as Dictionary<string, object>;
+
+                if (tempDataDictionary != null) {
+                    // If we got it from Session, remove it so that no other request gets it
+                    session.Remove(TempDataSessionStateKey);
+                    return tempDataDictionary;
+                }
+            }
+
+            return new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
+        }
+
+        public virtual void SaveTempData(ControllerContext controllerContext, IDictionary<string, object> values) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+
+            HttpSessionStateBase session = controllerContext.HttpContext.Session;
+            bool isDirty = (values != null && values.Count > 0);
+
+            if (session == null) {
+                if (isDirty) {
+                    throw new InvalidOperationException(MvcResources.SessionStateTempDataProvider_SessionStateDisabled);
+                }
+            }
+            else {
+                if (isDirty) {
+                    session[TempDataSessionStateKey] = values;
+                }
+                else {
+                    // Since the default implementation of Remove() (from SessionStateItemCollection) dirties the
+                    // collection, we shouldn't call it unless we really do need to remove the existing key.
+                    if (session[TempDataSessionStateKey] != null) {
+                        session.Remove(TempDataSessionStateKey);
+                    }
+                }
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/SingleServiceResolver.cs b/mcs/class/System.Web.Mvc3/Mvc/SingleServiceResolver.cs
new file mode 100644 (file)
index 0000000..17f55dc
--- /dev/null
@@ -0,0 +1,52 @@
+namespace System.Web.Mvc {
+    using System.Globalization;
+    using System.Web.Mvc.Resources;
+
+    internal class SingleServiceResolver<TService> : IResolver<TService> where TService : class {
+
+        private TService _currentValueFromResolver;
+        private Func<TService> _currentValueThunk;
+        private TService _defaultValue;
+        private Func<IDependencyResolver> _resolverThunk;
+        private string _callerMethodName;
+
+        public SingleServiceResolver(Func<TService> currentValueThunk, TService defaultValue, string callerMethodName) {
+            if (currentValueThunk == null) {
+                throw new ArgumentNullException("currentValueThunk");
+            }
+            if (defaultValue == null) {
+                throw new ArgumentNullException("defaultValue");
+            }
+
+            _resolverThunk = () => DependencyResolver.Current;
+            _currentValueThunk = currentValueThunk;
+            _defaultValue = defaultValue;
+            _callerMethodName = callerMethodName;
+        }
+
+        internal SingleServiceResolver(Func<TService> staticAccessor, TService defaultValue, IDependencyResolver resolver, string callerMethodName)
+            : this(staticAccessor, defaultValue, callerMethodName) {
+            if (resolver != null) {
+                _resolverThunk = () => resolver;
+            }
+        }
+
+        public TService Current {
+            get {
+                if (_resolverThunk != null) {
+                    lock (_currentValueThunk) {
+                        if (_resolverThunk != null) {
+                            _currentValueFromResolver = _resolverThunk().GetService<TService>();
+                            _resolverThunk = null;
+
+                            if (_currentValueFromResolver != null && _currentValueThunk() != null) {
+                                throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, MvcResources.SingleServiceResolver_CannotRegisterTwoInstances, typeof(TService).Name.ToString(), _callerMethodName));
+                            }
+                        }
+                    }
+                }
+                return _currentValueFromResolver ?? _currentValueThunk() ?? _defaultValue;
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/StringLengthAttributeAdapter.cs b/mcs/class/System.Web.Mvc3/Mvc/StringLengthAttributeAdapter.cs
new file mode 100644 (file)
index 0000000..d1af094
--- /dev/null
@@ -0,0 +1,14 @@
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+    using System.ComponentModel.DataAnnotations;
+
+    public class StringLengthAttributeAdapter : DataAnnotationsModelValidator<StringLengthAttribute> {
+        public StringLengthAttributeAdapter(ModelMetadata metadata, ControllerContext context, StringLengthAttribute attribute)
+            : base(metadata, context, attribute) {
+        }
+
+        public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() {
+            return new[] { new ModelClientValidationStringLengthRule(ErrorMessage, Attribute.MinimumLength, Attribute.MaximumLength) };
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/TagBuilderExtensions.cs b/mcs/class/System.Web.Mvc3/Mvc/TagBuilderExtensions.cs
new file mode 100644 (file)
index 0000000..7b87fd5
--- /dev/null
@@ -0,0 +1,10 @@
+namespace System.Web.Mvc {
+    using System.Diagnostics;
+
+    internal static class TagBuilderExtensions {
+        internal static MvcHtmlString ToMvcHtmlString(this TagBuilder tagBuilder, TagRenderMode renderMode) {
+            Debug.Assert(tagBuilder != null);
+            return new MvcHtmlString(tagBuilder.ToString(renderMode));
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/TempDataDictionary.cs b/mcs/class/System.Web.Mvc3/Mvc/TempDataDictionary.cs
new file mode 100644 (file)
index 0000000..257893e
--- /dev/null
@@ -0,0 +1,191 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Linq;
+    using System.Runtime.Serialization;
+
+    public class TempDataDictionary : IDictionary<string, object> {
+        internal const string _tempDataSerializationKey = "__tempData";
+
+        private Dictionary<string, object> _data;
+        private HashSet<string> _initialKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
+        private HashSet<string> _retainedKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
+
+        public TempDataDictionary() {
+            _data = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
+        }
+
+        public int Count {
+            get {
+                return _data.Count;
+            }
+        }
+
+        public ICollection<string> Keys {
+            get {
+                return _data.Keys;
+            }
+        }
+
+        public void Keep() {
+            _retainedKeys.Clear();
+            _retainedKeys.UnionWith(_data.Keys);
+        }
+
+        public void Keep(string key) {
+            _retainedKeys.Add(key);
+        }
+
+        public void Load(ControllerContext controllerContext, ITempDataProvider tempDataProvider) {
+            IDictionary<string, object> providerDictionary = tempDataProvider.LoadTempData(controllerContext);
+            _data = (providerDictionary != null) ? new Dictionary<string, object>(providerDictionary, StringComparer.OrdinalIgnoreCase) :
+                new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
+            _initialKeys = new HashSet<string>(_data.Keys, StringComparer.OrdinalIgnoreCase);
+            _retainedKeys.Clear();
+        }
+
+        public object Peek(string key) {
+            object value;
+            _data.TryGetValue(key, out value);
+            return value;
+        }
+
+        public void Save(ControllerContext controllerContext, ITempDataProvider tempDataProvider) {
+            string[] keysToKeep = _initialKeys.Union(_retainedKeys, StringComparer.OrdinalIgnoreCase).ToArray();
+            string[] keysToRemove = _data.Keys.Except(keysToKeep, StringComparer.OrdinalIgnoreCase).ToArray();
+            foreach (string key in keysToRemove) {
+                _data.Remove(key);
+            }
+            tempDataProvider.SaveTempData(controllerContext, _data);
+        }
+
+        public ICollection<object> Values {
+            get {
+                return _data.Values;
+            }
+        }
+
+        public object this[string key] {
+            get {
+                object value;
+                if (TryGetValue(key, out value)) {
+                    _initialKeys.Remove(key);
+                    return value;
+                }
+                return null;
+            }
+            set {
+                _data[key] = value;
+                _initialKeys.Add(key);
+            }
+        }
+
+        public void Add(string key, object value) {
+            _data.Add(key, value);
+            _initialKeys.Add(key);
+        }
+
+        public void Clear() {
+            _data.Clear();
+            _retainedKeys.Clear();
+            _initialKeys.Clear();
+        }
+
+        public bool ContainsKey(string key) {
+            return _data.ContainsKey(key);
+        }
+
+        public bool ContainsValue(object value) {
+            return _data.ContainsValue(value);
+        }
+
+        public IEnumerator<KeyValuePair<string, object>> GetEnumerator() {
+            return new TempDataDictionaryEnumerator(this);
+        }
+
+        public bool Remove(string key) {
+            _retainedKeys.Remove(key);
+            _initialKeys.Remove(key);
+            return _data.Remove(key);
+        }
+
+        public bool TryGetValue(string key, out object value) {
+            _initialKeys.Remove(key);
+            return _data.TryGetValue(key, out value);
+        }
+
+        #region ICollection<KeyValuePair<string, object>> Implementation
+        bool ICollection<KeyValuePair<string, object>>.IsReadOnly {
+            get {
+                return ((ICollection<KeyValuePair<string, object>>)_data).IsReadOnly;
+            }
+        }
+
+        void ICollection<KeyValuePair<string, object>>.CopyTo(KeyValuePair<string, object>[] array, int index) {
+            ((ICollection<KeyValuePair<string, object>>)_data).CopyTo(array, index);
+        }
+
+        void ICollection<KeyValuePair<string, object>>.Add(KeyValuePair<string, object> keyValuePair) {
+            _initialKeys.Add(keyValuePair.Key);
+            ((ICollection<KeyValuePair<string, object>>)_data).Add(keyValuePair);
+        }
+
+        bool ICollection<KeyValuePair<string, object>>.Contains(KeyValuePair<string, object> keyValuePair) {
+            return ((ICollection<KeyValuePair<string, object>>)_data).Contains(keyValuePair);
+        }
+
+        bool ICollection<KeyValuePair<string, object>>.Remove(KeyValuePair<string, object> keyValuePair) {
+            _initialKeys.Remove(keyValuePair.Key);
+            return ((ICollection<KeyValuePair<string, object>>)_data).Remove(keyValuePair);
+        }
+        #endregion
+
+        #region IEnumerable Implementation
+        IEnumerator IEnumerable.GetEnumerator() {
+            return (IEnumerator)(new TempDataDictionaryEnumerator(this));
+        }
+        #endregion
+
+        private sealed class TempDataDictionaryEnumerator : IEnumerator<KeyValuePair<string, object>> {
+            private IEnumerator<KeyValuePair<string, object>> _enumerator;
+            private TempDataDictionary _tempData;
+
+            public TempDataDictionaryEnumerator(TempDataDictionary tempData) {
+                _tempData = tempData;
+                _enumerator = _tempData._data.GetEnumerator();
+            }
+
+            public KeyValuePair<string, object> Current {
+                get {
+                    KeyValuePair<string, object> kvp = _enumerator.Current;
+                    _tempData._initialKeys.Remove(kvp.Key);
+                    return kvp;
+                }
+            }
+
+            public bool MoveNext() {
+                return _enumerator.MoveNext();
+            }
+
+            public void Reset() {
+                _enumerator.Reset();
+            }
+
+            #region IEnumerator Implementation
+            object IEnumerator.Current {
+                get {
+                    return Current;
+                }
+            }
+            #endregion
+
+            #region IDisposable Implementation
+            void IDisposable.Dispose() {
+                _enumerator.Dispose();
+            }
+            #endregion
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/TemplateInfo.cs b/mcs/class/System.Web.Mvc3/Mvc/TemplateInfo.cs
new file mode 100644 (file)
index 0000000..88cf7a7
--- /dev/null
@@ -0,0 +1,59 @@
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+
+    public class TemplateInfo {
+        private string _htmlFieldPrefix;
+        private object _formattedModelValue;
+        private HashSet<object> _visitedObjects;
+
+        public object FormattedModelValue {
+            get {
+                return _formattedModelValue ?? String.Empty;
+            }
+            set {
+                _formattedModelValue = value;
+            }
+        }
+
+        public string HtmlFieldPrefix {
+            get {
+                return _htmlFieldPrefix ?? String.Empty;
+            }
+            set {
+                _htmlFieldPrefix = value;
+            }
+        }
+
+        public int TemplateDepth {
+            get {
+                return VisitedObjects.Count;
+            }
+        }
+
+        // DDB #224750 - Keep a collection of visited objects to prevent infinite recursion
+        internal HashSet<object> VisitedObjects {
+            get {
+                if (_visitedObjects == null) {
+                    _visitedObjects = new HashSet<object>();
+                }
+                return _visitedObjects;
+            }
+            set {
+                _visitedObjects = value;
+            }
+        }
+
+        public string GetFullHtmlFieldId(string partialFieldName) {
+            return HtmlHelper.GenerateIdFromName(GetFullHtmlFieldName(partialFieldName));
+        }
+
+        public string GetFullHtmlFieldName(string partialFieldName) {
+            // This uses "combine and trim" because either or both of these values might be empty
+            return (HtmlFieldPrefix + "." + (partialFieldName ?? String.Empty)).Trim('.');
+        }
+
+        public bool Visited(ModelMetadata metadata) {
+            return VisitedObjects.Contains(metadata.Model ?? metadata.ModelType);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/TryGetValueDelegate.cs b/mcs/class/System.Web.Mvc3/Mvc/TryGetValueDelegate.cs
new file mode 100644 (file)
index 0000000..f9ee08f
--- /dev/null
@@ -0,0 +1,5 @@
+namespace System.Web.Mvc {
+    using System;
+
+    internal delegate bool TryGetValueDelegate(object dictionary, string key, out object value);
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/TypeCacheSerializer.cs b/mcs/class/System.Web.Mvc3/Mvc/TypeCacheSerializer.cs
new file mode 100644 (file)
index 0000000..00ba819
--- /dev/null
@@ -0,0 +1,115 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.IO;
+    using System.Linq;
+    using System.Reflection;
+    using System.Web.Mvc.Resources;
+    using System.Xml;
+
+    // Processes files with this format:
+    //
+    // <typeCache lastModified=... mvcVersionId=...>
+    //   <assembly name=...>
+    //     <module versionId=...>
+    //       <type>...</type>
+    //     </module>
+    //   </assembly>
+    // </typeCache>
+    //
+    // This is used to store caches of files between AppDomain resets, leading to improved cold boot time
+    // and more efficient use of memory.
+
+    internal sealed class TypeCacheSerializer {
+
+        private static readonly Guid _mvcVersionId = typeof(TypeCacheSerializer).Module.ModuleVersionId;
+
+        // used for unit testing
+
+        private DateTime CurrentDate {
+            get {
+                return CurrentDateOverride ?? DateTime.Now;
+            }
+        }
+
+        internal DateTime? CurrentDateOverride {
+            get;
+            set;
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "This is an instance method for consistency with the SerializeTypes() method.")]
+        public List<Type> DeserializeTypes(TextReader input) {
+            XmlDocument doc = new XmlDocument();
+            doc.Load(input);
+            XmlElement rootElement = doc.DocumentElement;
+
+            Guid readMvcVersionId = new Guid(rootElement.Attributes["mvcVersionId"].Value);
+            if (readMvcVersionId != _mvcVersionId) {
+                // The cache is outdated because the cache file was produced by a different version
+                // of MVC.
+                return null;
+            }
+
+            List<Type> deserializedTypes = new List<Type>();
+            foreach (XmlNode assemblyNode in rootElement.ChildNodes) {
+                string assemblyName = assemblyNode.Attributes["name"].Value;
+                Assembly assembly = Assembly.Load(assemblyName);
+
+                foreach (XmlNode moduleNode in assemblyNode.ChildNodes) {
+                    Guid moduleVersionId = new Guid(moduleNode.Attributes["versionId"].Value);
+
+                    foreach (XmlNode typeNode in moduleNode.ChildNodes) {
+                        string typeName = typeNode.InnerText;
+                        Type type = assembly.GetType(typeName);
+                        if (type == null || type.Module.ModuleVersionId != moduleVersionId) {
+                            // The cache is outdated because we couldn't find a previously recorded
+                            // type or the type's containing module was modified.
+                            return null;
+                        }
+                        else {
+                            deserializedTypes.Add(type);
+                        }
+                    }
+                }
+            }
+
+            return deserializedTypes;
+        }
+
+        public void SerializeTypes(IEnumerable<Type> types, TextWriter output) {
+            var groupedByAssembly = from type in types
+                                    group type by type.Module into groupedByModule
+                                    group groupedByModule by groupedByModule.Key.Assembly;
+
+            XmlDocument doc = new XmlDocument();
+            doc.AppendChild(doc.CreateComment(MvcResources.TypeCache_DoNotModify));
+
+            XmlElement typeCacheElement = doc.CreateElement("typeCache");
+            doc.AppendChild(typeCacheElement);
+            typeCacheElement.SetAttribute("lastModified", CurrentDate.ToString());
+            typeCacheElement.SetAttribute("mvcVersionId", _mvcVersionId.ToString());
+
+            foreach (var assemblyGroup in groupedByAssembly) {
+                XmlElement assemblyElement = doc.CreateElement("assembly");
+                typeCacheElement.AppendChild(assemblyElement);
+                assemblyElement.SetAttribute("name", assemblyGroup.Key.FullName);
+
+                foreach (var moduleGroup in assemblyGroup) {
+                    XmlElement moduleElement = doc.CreateElement("module");
+                    assemblyElement.AppendChild(moduleElement);
+                    moduleElement.SetAttribute("versionId", moduleGroup.Key.ModuleVersionId.ToString());
+
+                    foreach (Type type in moduleGroup) {
+                        XmlElement typeElement = doc.CreateElement("type");
+                        moduleElement.AppendChild(typeElement);
+                        typeElement.AppendChild(doc.CreateTextNode(type.FullName));
+                    }
+                }
+            }
+
+            doc.Save(output);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/TypeCacheUtil.cs b/mcs/class/System.Web.Mvc3/Mvc/TypeCacheUtil.cs
new file mode 100644 (file)
index 0000000..3bd97f5
--- /dev/null
@@ -0,0 +1,87 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.IO;
+    using System.Linq;
+    using System.Reflection;
+
+    internal static class TypeCacheUtil {
+
+        private static IEnumerable<Type> FilterTypesInAssemblies(IBuildManager buildManager, Predicate<Type> predicate) {
+            // Go through all assemblies referenced by the application and search for types matching a predicate
+            IEnumerable<Type> typesSoFar = Type.EmptyTypes;
+
+            ICollection assemblies = buildManager.GetReferencedAssemblies();
+            foreach (Assembly assembly in assemblies) {
+                Type[] typesInAsm;
+                try {
+                    typesInAsm = assembly.GetTypes();
+                }
+                catch (ReflectionTypeLoadException ex) {
+                    typesInAsm = ex.Types;
+                }
+                typesSoFar = typesSoFar.Concat(typesInAsm);
+            }
+            return typesSoFar.Where(type => TypeIsPublicClass(type) && predicate(type));
+        }
+
+        public static List<Type> GetFilteredTypesFromAssemblies(string cacheName, Predicate<Type> predicate, IBuildManager buildManager) {
+            TypeCacheSerializer serializer = new TypeCacheSerializer();
+
+            // first, try reading from the cache on disk
+            List<Type> matchingTypes = ReadTypesFromCache(cacheName, predicate, buildManager, serializer);
+            if (matchingTypes != null) {
+                return matchingTypes;
+            }
+
+            // if reading from the cache failed, enumerate over every assembly looking for a matching type
+            matchingTypes = FilterTypesInAssemblies(buildManager, predicate).ToList();
+
+            // finally, save the cache back to disk
+            SaveTypesToCache(cacheName, matchingTypes, buildManager, serializer);
+
+            return matchingTypes;
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Cache failures are not fatal, and the code should continue executing normally.")]
+        internal static List<Type> ReadTypesFromCache(string cacheName, Predicate<Type> predicate, IBuildManager buildManager, TypeCacheSerializer serializer) {
+            try {
+                Stream stream = buildManager.ReadCachedFile(cacheName);
+                if (stream != null) {
+                    using (StreamReader reader = new StreamReader(stream)) {
+                        List<Type> deserializedTypes = serializer.DeserializeTypes(reader);
+                        if (deserializedTypes != null && deserializedTypes.All(type => TypeIsPublicClass(type) && predicate(type))) {
+                            // If all read types still match the predicate, success!
+                            return deserializedTypes;
+                        }
+                    }
+                }
+            }
+            catch {
+            }
+
+            return null;
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Cache failures are not fatal, and the code should continue executing normally.")]
+        internal static void SaveTypesToCache(string cacheName, IList<Type> matchingTypes, IBuildManager buildManager, TypeCacheSerializer serializer) {
+            try {
+                Stream stream = buildManager.CreateCachedFile(cacheName);
+                if (stream != null) {
+                    using (StreamWriter writer = new StreamWriter(stream)) {
+                        serializer.SerializeTypes(matchingTypes, writer);
+                    }
+                }
+            }
+            catch {
+            }
+        }
+
+        private static bool TypeIsPublicClass(Type type) {
+            return (type != null && type.IsPublic && type.IsClass && !type.IsAbstract);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/TypeDescriptorHelper.cs b/mcs/class/System.Web.Mvc3/Mvc/TypeDescriptorHelper.cs
new file mode 100644 (file)
index 0000000..4b128b0
--- /dev/null
@@ -0,0 +1,13 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.ComponentModel;
+    using System.ComponentModel.DataAnnotations;
+
+    internal static class TypeDescriptorHelper {
+
+        public static ICustomTypeDescriptor Get(Type type) {
+            return new AssociatedMetadataTypeTypeDescriptionProvider(type).GetTypeDescriptor(type);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/TypeHelpers.cs b/mcs/class/System.Web.Mvc3/Mvc/TypeHelpers.cs
new file mode 100644 (file)
index 0000000..90ebcbe
--- /dev/null
@@ -0,0 +1,126 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Linq;
+    using System.Reflection;
+    using System.Threading;
+
+    internal static class TypeHelpers {
+
+        private static readonly Dictionary<Type, TryGetValueDelegate> _tryGetValueDelegateCache = new Dictionary<Type, TryGetValueDelegate>();
+        private static readonly ReaderWriterLockSlim _tryGetValueDelegateCacheLock = new ReaderWriterLockSlim();
+
+        private static readonly MethodInfo _strongTryGetValueImplInfo = typeof(TypeHelpers).GetMethod("StrongTryGetValueImpl", BindingFlags.NonPublic | BindingFlags.Static);
+
+        public static readonly Assembly MsCorLibAssembly = typeof(string).Assembly;
+        public static readonly Assembly MvcAssembly = typeof(Controller).Assembly;
+        public static readonly Assembly SystemWebAssembly = typeof(HttpContext).Assembly;
+
+        // method is used primarily for lighting up new .NET Framework features even if MVC targets the previous version
+        // thisParameter is the 'this' parameter if target method is instance method, should be null for static method
+        public static TDelegate CreateDelegate<TDelegate>(Assembly assembly, string typeName, string methodName, object thisParameter) where TDelegate : class {
+            // ensure target type exists
+            Type targetType = assembly.GetType(typeName, false /* throwOnError */);
+            if (targetType == null) {
+                return null;
+            }
+
+            return CreateDelegate<TDelegate>(targetType, methodName, thisParameter);
+        }
+
+        public static TDelegate CreateDelegate<TDelegate>(Type targetType, string methodName, object thisParameter) where TDelegate : class {
+            // ensure target method exists
+            ParameterInfo[] delegateParameters = typeof(TDelegate).GetMethod("Invoke").GetParameters();
+            Type[] argumentTypes = Array.ConvertAll(delegateParameters, pInfo => pInfo.ParameterType);
+            MethodInfo targetMethod = targetType.GetMethod(methodName, argumentTypes);
+            if (targetMethod == null) {
+                return null;
+            }
+
+            TDelegate d = Delegate.CreateDelegate(typeof(TDelegate), thisParameter, targetMethod, false /* throwOnBindFailure */) as TDelegate;
+            return d;
+        }
+
+        public static TryGetValueDelegate CreateTryGetValueDelegate(Type targetType) {
+            TryGetValueDelegate result;
+
+            _tryGetValueDelegateCacheLock.EnterReadLock();
+            try {
+                if (_tryGetValueDelegateCache.TryGetValue(targetType, out result)) {
+                    return result;
+                }
+            }
+            finally {
+                _tryGetValueDelegateCacheLock.ExitReadLock();
+            }
+
+            Type dictionaryType = ExtractGenericInterface(targetType, typeof(IDictionary<,>));
+
+            // just wrap a call to the underlying IDictionary<TKey, TValue>.TryGetValue() where string can be cast to TKey
+            if (dictionaryType != null) {
+                Type[] typeArguments = dictionaryType.GetGenericArguments();
+                Type keyType = typeArguments[0];
+                Type returnType = typeArguments[1];
+
+                if (keyType.IsAssignableFrom(typeof(string))) {
+                    MethodInfo strongImplInfo = _strongTryGetValueImplInfo.MakeGenericMethod(keyType, returnType);
+                    result = (TryGetValueDelegate)Delegate.CreateDelegate(typeof(TryGetValueDelegate), strongImplInfo);
+                }
+            }
+
+            // wrap a call to the underlying IDictionary.Item()
+            if (result == null && typeof(IDictionary).IsAssignableFrom(targetType)) {
+                result = TryGetValueFromNonGenericDictionary;
+            }
+
+            _tryGetValueDelegateCacheLock.EnterWriteLock();
+            try {
+                _tryGetValueDelegateCache[targetType] = result;
+            }
+            finally {
+                _tryGetValueDelegateCacheLock.ExitWriteLock();
+            }
+
+            return result;
+        }
+
+        public static Type ExtractGenericInterface(Type queryType, Type interfaceType) {
+            Func<Type, bool> matchesInterface = t => t.IsGenericType && t.GetGenericTypeDefinition() == interfaceType;
+            return (matchesInterface(queryType)) ? queryType : queryType.GetInterfaces().FirstOrDefault(matchesInterface);
+        }
+
+        public static object GetDefaultValue(Type type) {
+            return (TypeAllowsNullValue(type)) ? null : Activator.CreateInstance(type);
+        }
+
+        public static bool IsCompatibleObject<T>(object value) {
+            return (value is T || (value == null && TypeAllowsNullValue(typeof(T))));
+        }
+
+        public static bool IsNullableValueType(Type type) {
+            return Nullable.GetUnderlyingType(type) != null;
+        }
+
+        private static bool StrongTryGetValueImpl<TKey, TValue>(object dictionary, string key, out object value) {
+            IDictionary<TKey, TValue> strongDict = (IDictionary<TKey, TValue>)dictionary;
+
+            TValue strongValue;
+            bool retVal = strongDict.TryGetValue((TKey)(object)key, out strongValue);
+            value = strongValue;
+            return retVal;
+        }
+
+        private static bool TryGetValueFromNonGenericDictionary(object dictionary, string key, out object value) {
+            IDictionary weakDict = (IDictionary)dictionary;
+
+            bool containsKey = weakDict.Contains(key);
+            value = (containsKey) ? weakDict[key] : null;
+            return containsKey;
+        }
+
+        public static bool TypeAllowsNullValue(Type type) {
+            return (!type.IsValueType || IsNullableValueType(type));
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/UnvalidatedRequestValuesAccessor.cs b/mcs/class/System.Web.Mvc3/Mvc/UnvalidatedRequestValuesAccessor.cs
new file mode 100644 (file)
index 0000000..660ab22
--- /dev/null
@@ -0,0 +1,6 @@
+namespace System.Web.Mvc {
+    using System;
+
+    internal delegate IUnvalidatedRequestValues UnvalidatedRequestValuesAccessor(ControllerContext controllerContext);
+
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/UnvalidatedRequestValuesWrapper.cs b/mcs/class/System.Web.Mvc3/Mvc/UnvalidatedRequestValuesWrapper.cs
new file mode 100644 (file)
index 0000000..90b5493
--- /dev/null
@@ -0,0 +1,28 @@
+namespace System.Web.Mvc {
+    using System.Collections.Specialized;
+    using System.Web.Helpers;
+
+    // Concrete implementation for the IUnvalidatedRequestValues helper interface
+
+    internal sealed class UnvalidatedRequestValuesWrapper : IUnvalidatedRequestValues {
+
+        private readonly UnvalidatedRequestValues _unvalidatedValues;
+
+        public UnvalidatedRequestValuesWrapper(UnvalidatedRequestValues unvalidatedValues) {
+            _unvalidatedValues = unvalidatedValues;
+        }
+
+        public NameValueCollection Form {
+            get { return _unvalidatedValues.Form; }
+        }
+
+        public NameValueCollection QueryString {
+            get { return _unvalidatedValues.QueryString; }
+        }
+
+        public string this[string key] {
+            get { return _unvalidatedValues[key]; }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/UrlHelper.cs b/mcs/class/System.Web.Mvc3/Mvc/UrlHelper.cs
new file mode 100644 (file)
index 0000000..0e16cc2
--- /dev/null
@@ -0,0 +1,189 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Web.Mvc.Resources;
+    using System.Web.Routing;
+
+    public class UrlHelper {
+        public UrlHelper(RequestContext requestContext)
+            : this(requestContext, RouteTable.Routes) {
+        }
+
+        public UrlHelper(RequestContext requestContext, RouteCollection routeCollection) {
+            if (requestContext == null) {
+                throw new ArgumentNullException("requestContext");
+            }
+            if (routeCollection == null) {
+                throw new ArgumentNullException("routeCollection");
+            }
+            RequestContext = requestContext;
+            RouteCollection = routeCollection;
+        }
+
+        public RequestContext RequestContext {
+            get;
+            private set;
+        }
+
+        public RouteCollection RouteCollection {
+            get;
+            private set;
+        }
+
+        public string Action(string actionName) {
+            return GenerateUrl(null /* routeName */, actionName, null, (RouteValueDictionary)null /* routeValues */);
+        }
+
+        public string Action(string actionName, object routeValues) {
+            return GenerateUrl(null /* routeName */, actionName, null /* controllerName */, new RouteValueDictionary(routeValues));
+        }
+
+        public string Action(string actionName, RouteValueDictionary routeValues) {
+            return GenerateUrl(null /* routeName */, actionName, null /* controllerName */, routeValues);
+        }
+
+        public string Action(string actionName, string controllerName) {
+            return GenerateUrl(null /* routeName */, actionName, controllerName, (RouteValueDictionary)null /* routeValues */);
+        }
+
+        public string Action(string actionName, string controllerName, object routeValues) {
+            return GenerateUrl(null /* routeName */, actionName, controllerName, new RouteValueDictionary(routeValues));
+        }
+
+        public string Action(string actionName, string controllerName, RouteValueDictionary routeValues) {
+            return GenerateUrl(null /* routeName */, actionName, controllerName, routeValues);
+        }
+
+        public string Action(string actionName, string controllerName, object routeValues, string protocol) {
+            return GenerateUrl(null /* routeName */, actionName, controllerName, protocol, null /* hostName */, null /* fragment */, new RouteValueDictionary(routeValues), RouteCollection, RequestContext, true /* includeImplicitMvcValues */);
+        }
+
+        public string Action(string actionName, string controllerName, RouteValueDictionary routeValues, string protocol, string hostName) {
+            return GenerateUrl(null /* routeName */, actionName, controllerName, protocol, hostName, null /* fragment */, routeValues, RouteCollection, RequestContext, true /* includeImplicitMvcValues */);
+        }
+
+        public string Content(string contentPath) {
+            return GenerateContentUrl(contentPath, RequestContext.HttpContext);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings", Justification = "As the return value will used only for rendering, string return value is more appropriate.")]
+        public static string GenerateContentUrl(string contentPath, HttpContextBase httpContext) {
+            if (String.IsNullOrEmpty(contentPath)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "contentPath");
+            }
+
+            if (httpContext == null) {
+                throw new ArgumentNullException("httpContext");
+            }
+
+            if (contentPath[0] == '~') {
+                return PathHelpers.GenerateClientUrl(httpContext, contentPath);
+            }
+            else {
+                return contentPath;
+            }
+        }
+
+        //REVIEW: Should we have an overload that takes Uri?
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", Justification = "Needs to take same parameters as HttpUtility.UrlEncode()")]
+        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "For consistency, all helpers are instance methods.")]
+        public string Encode(string url) {
+            return HttpUtility.UrlEncode(url);
+        }
+
+        private string GenerateUrl(string routeName, string actionName, string controllerName, RouteValueDictionary routeValues) {
+            return GenerateUrl(routeName, actionName, controllerName, routeValues, RouteCollection, RequestContext, true /* includeImplicitMvcValues */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings", Justification = "As the return value will used only for rendering, string return value is more appropriate.")]
+        public static string GenerateUrl(string routeName, string actionName, string controllerName, string protocol, string hostName, string fragment, RouteValueDictionary routeValues, RouteCollection routeCollection, RequestContext requestContext, bool includeImplicitMvcValues) {
+            string url = GenerateUrl(routeName, actionName, controllerName, routeValues, routeCollection, requestContext, includeImplicitMvcValues);
+
+            if (url != null) {
+                if (!String.IsNullOrEmpty(fragment)) {
+                    url = url + "#" + fragment;
+                }
+
+                if (!String.IsNullOrEmpty(protocol) || !String.IsNullOrEmpty(hostName)) {
+                    Uri requestUrl = requestContext.HttpContext.Request.Url;
+                    protocol = (!String.IsNullOrEmpty(protocol)) ? protocol : Uri.UriSchemeHttp;
+                    hostName = (!String.IsNullOrEmpty(hostName)) ? hostName : requestUrl.Host;
+
+                    string port = String.Empty;
+                    string requestProtocol = requestUrl.Scheme;
+
+                    if (String.Equals(protocol, requestProtocol, StringComparison.OrdinalIgnoreCase)) {
+                        port = requestUrl.IsDefaultPort ? String.Empty : (":" + Convert.ToString(requestUrl.Port, CultureInfo.InvariantCulture));
+                    }
+
+                    url = protocol + Uri.SchemeDelimiter + hostName + port + url;
+                }
+            }
+
+            return url;
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings", Justification = "As the return value will used only for rendering, string return value is more appropriate.")]
+        public static string GenerateUrl(string routeName, string actionName, string controllerName, RouteValueDictionary routeValues, RouteCollection routeCollection, RequestContext requestContext, bool includeImplicitMvcValues) {
+            if (routeCollection == null) {
+                throw new ArgumentNullException("routeCollection");
+            }
+
+            if (requestContext == null) {
+                throw new ArgumentNullException("requestContext");
+            }
+
+            RouteValueDictionary mergedRouteValues = RouteValuesHelpers.MergeRouteValues(actionName, controllerName, requestContext.RouteData.Values, routeValues, includeImplicitMvcValues);
+
+            VirtualPathData vpd = routeCollection.GetVirtualPathForArea(requestContext, routeName, mergedRouteValues);
+            if (vpd == null) {
+                return null;
+            }
+
+            string modifiedUrl = PathHelpers.GenerateClientUrl(requestContext.HttpContext, vpd.VirtualPath);
+            return modifiedUrl;
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "0#", Justification = "Response.Redirect() takes its URI as a string parameter.")]
+        public bool IsLocalUrl(string url) {
+            // TODO this should call the System.Web.dll API once it gets added to the framework and MVC takes a dependency on it.
+            return System.Web.WebPages.RequestExtensions.IsUrlLocalToHost(RequestContext.HttpContext.Request, url);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings", Justification = "As the return value will used only for rendering, string return value is more appropriate.")]
+        public string RouteUrl(object routeValues) {
+            return RouteUrl(null /* routeName */, routeValues);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings", Justification = "As the return value will used only for rendering, string return value is more appropriate.")]
+        public string RouteUrl(RouteValueDictionary routeValues) {
+            return RouteUrl(null /* routeName */, routeValues);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings", Justification = "As the return value will used only for rendering, string return value is more appropriate.")]
+        public string RouteUrl(string routeName) {
+            return RouteUrl(routeName, (object)null /* routeValues */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings", Justification = "As the return value will used only for rendering, string return value is more appropriate.")]
+        public string RouteUrl(string routeName, object routeValues) {
+            return RouteUrl(routeName, routeValues, null /* protocol */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings", Justification = "As the return value will used only for rendering, string return value is more appropriate.")]
+        public string RouteUrl(string routeName, RouteValueDictionary routeValues) {
+            return RouteUrl(routeName, routeValues, null /* protocol */, null /* hostName */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings", Justification = "As the return value will used only for rendering, string return value is more appropriate.")]
+        public string RouteUrl(string routeName, object routeValues, string protocol) {
+            return GenerateUrl(routeName, null /* actionName */, null /* controllerName */, protocol, null /* hostName */, null /* fragment */, new RouteValueDictionary(routeValues), RouteCollection, RequestContext, false /* includeImplicitMvcValues */);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings", Justification = "As the return value will used only for rendering, string return value is more appropriate.")]
+        public string RouteUrl(string routeName, RouteValueDictionary routeValues, string protocol, string hostName) {
+            return GenerateUrl(routeName, null /* actionName */, null /* controllerName */, protocol, hostName, null /* fragment */, routeValues, RouteCollection, RequestContext, false /* includeImplicitMvcValues */);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/UrlParameter.cs b/mcs/class/System.Web.Mvc3/Mvc/UrlParameter.cs
new file mode 100644 (file)
index 0000000..73ca5ce
--- /dev/null
@@ -0,0 +1,17 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+
+    public sealed class UrlParameter {
+
+        [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "This type is immutable.")]
+        public static readonly UrlParameter Optional = new UrlParameter();
+
+        // singleton constructor
+        private UrlParameter() { }
+
+        public override string ToString() {
+            return String.Empty;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/UrlRewriterHelper.cs b/mcs/class/System.Web.Mvc3/Mvc/UrlRewriterHelper.cs
new file mode 100644 (file)
index 0000000..8d0d5b8
--- /dev/null
@@ -0,0 +1,37 @@
+namespace System.Web.Mvc {
+    using System.Collections.Specialized;
+
+    internal class UrlRewriterHelper {
+        private const string _urlWasRewrittenServerVar = "IIS_WasUrlRewritten";
+        private const string _urlRewriterEnabledServerVar = "IIS_UrlRewriteModule";
+
+        private object _lockObject = new object();
+        private bool _urlRewriterIsTurnedOnValue;
+        private bool _urlRewriterIsTurnedOnCalculated = false;
+
+        private static bool WasThisRequestRewritten(HttpContextBase httpContext) {
+            NameValueCollection serverVars = httpContext.Request.ServerVariables;
+            bool requestWasRewritten = (serverVars != null && serverVars[_urlWasRewrittenServerVar] != null);
+            return requestWasRewritten;
+        }
+
+        private bool IsUrlRewriterTurnedOn(HttpContextBase httpContext) {
+            // Need to do double-check locking because a single instance of this class is shared in the entire app domain (see PathHelpers)
+            if (!_urlRewriterIsTurnedOnCalculated) {
+                lock (_lockObject) {
+                    if (!_urlRewriterIsTurnedOnCalculated) {
+                        NameValueCollection serverVars = httpContext.Request.ServerVariables;
+                        bool urlRewriterIsEnabled = (serverVars != null && serverVars[_urlRewriterEnabledServerVar] != null);
+                        _urlRewriterIsTurnedOnValue = urlRewriterIsEnabled;
+                        _urlRewriterIsTurnedOnCalculated = true;
+                    }
+                }
+            }
+            return _urlRewriterIsTurnedOnValue;
+        }
+
+        public virtual bool WasRequestRewritten(HttpContextBase httpContext) {
+            return IsUrlRewriterTurnedOn(httpContext) && WasThisRequestRewritten(httpContext);
+        }
+    }
+}
\ No newline at end of file
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ValidatableObjectAdapter.cs b/mcs/class/System.Web.Mvc3/Mvc/ValidatableObjectAdapter.cs
new file mode 100644 (file)
index 0000000..fbccc6d
--- /dev/null
@@ -0,0 +1,54 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.ComponentModel.DataAnnotations;
+    using System.Globalization;
+    using System.Linq;
+    using System.Web.Mvc.Resources;
+
+    public class ValidatableObjectAdapter : ModelValidator {
+        public ValidatableObjectAdapter(ModelMetadata metadata, ControllerContext context)
+            : base(metadata, context) {
+        }
+
+        public override IEnumerable<ModelValidationResult> Validate(object container) {
+            // NOTE: Container is never used here, because IValidatableObject doesn't give you
+            // any way to get access to your container.
+
+            object model = Metadata.Model;
+            if (model == null) {
+                return Enumerable.Empty<ModelValidationResult>();
+            }
+
+            IValidatableObject validatable = model as IValidatableObject;
+            if (validatable == null) {
+                throw new InvalidOperationException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.ValidatableObjectAdapter_IncompatibleType,
+                        typeof(IValidatableObject).FullName,
+                        model.GetType().FullName
+                    )
+                );
+            }
+
+            ValidationContext validationContext = new ValidationContext(validatable, null, null);
+            return ConvertResults(validatable.Validate(validationContext));
+        }
+
+        private IEnumerable<ModelValidationResult> ConvertResults(IEnumerable<ValidationResult> results) {
+            foreach (ValidationResult result in results) {
+                if (result != ValidationResult.Success) {
+                    if (result.MemberNames == null || !result.MemberNames.Any()) {
+                        yield return new ModelValidationResult { Message = result.ErrorMessage };
+                    }
+                    else {
+                        foreach (string memberName in result.MemberNames) {
+                            yield return new ModelValidationResult { Message = result.ErrorMessage, MemberName = memberName };
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ValidateAntiForgeryTokenAttribute.cs b/mcs/class/System.Web.Mvc3/Mvc/ValidateAntiForgeryTokenAttribute.cs
new file mode 100644 (file)
index 0000000..4bd7874
--- /dev/null
@@ -0,0 +1,43 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics;
+    using System.Web;
+    using System.Web.Helpers;
+
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
+    public sealed class ValidateAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter {
+
+        private string _salt;
+
+        public string Salt {
+            get {
+                return _salt ?? String.Empty;
+            }
+            set {
+                _salt = value;
+            }
+        }
+
+        internal Action<HttpContextBase, string> ValidateAction {
+            get;
+            private set;
+        }
+
+        public ValidateAntiForgeryTokenAttribute()
+            : this(AntiForgery.Validate) {
+        }
+
+        internal ValidateAntiForgeryTokenAttribute(Action<HttpContextBase,string> validateAction) {
+            Debug.Assert(validateAction != null);
+            ValidateAction = validateAction;
+        }
+
+        public void OnAuthorization(AuthorizationContext filterContext) {
+            if (filterContext == null) {
+                throw new ArgumentNullException("filterContext");
+            }
+
+            ValidateAction(filterContext.HttpContext, Salt);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ValidateInputAttribute.cs b/mcs/class/System.Web.Mvc3/Mvc/ValidateInputAttribute.cs
new file mode 100644 (file)
index 0000000..96a6c18
--- /dev/null
@@ -0,0 +1,27 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+
+    [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes", Justification = "No compelling performance reason to seal this type.")]
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
+    public class ValidateInputAttribute : FilterAttribute, IAuthorizationFilter {
+
+        public ValidateInputAttribute(bool enableValidation) {
+            EnableValidation = enableValidation;
+        }
+
+        public bool EnableValidation {
+            get;
+            private set;
+        }
+
+        public virtual void OnAuthorization(AuthorizationContext filterContext) {
+            if (filterContext == null) {
+                throw new ArgumentNullException("filterContext");
+            }
+
+            filterContext.Controller.ValidateRequest = EnableValidation;
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ValueProviderCollection.cs b/mcs/class/System.Web.Mvc3/Mvc/ValueProviderCollection.cs
new file mode 100644 (file)
index 0000000..3bd7944
--- /dev/null
@@ -0,0 +1,55 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Collections.ObjectModel;
+    using System.Linq;
+
+    public class ValueProviderCollection : Collection<IValueProvider>, IValueProvider, IUnvalidatedValueProvider {
+
+        public ValueProviderCollection() {
+        }
+
+        public ValueProviderCollection(IList<IValueProvider> list)
+            : base(list) {
+        }
+
+        public virtual bool ContainsPrefix(string prefix) {
+            return this.Any(vp => vp.ContainsPrefix(prefix));
+        }
+
+        public virtual ValueProviderResult GetValue(string key) {
+            return GetValue(key, skipValidation: false);
+        }
+
+        public virtual ValueProviderResult GetValue(string key, bool skipValidation) {
+            return (from provider in this
+                    let result = GetValueFromProvider(provider, key, skipValidation)
+                    where result != null
+                    select result).FirstOrDefault();
+        }
+
+        internal static ValueProviderResult GetValueFromProvider(IValueProvider provider, string key, bool skipValidation) {
+            // Since IUnvalidatedValueProvider is a superset of IValueProvider, it's always OK to use the
+            // IUnvalidatedValueProvider-supplied members if they're present. Otherwise just call the
+            // normal IValueProvider members.
+
+            IUnvalidatedValueProvider unvalidatedProvider = provider as IUnvalidatedValueProvider;
+            return (unvalidatedProvider != null) ? unvalidatedProvider.GetValue(key, skipValidation) : provider.GetValue(key);
+        }
+
+        protected override void InsertItem(int index, IValueProvider item) {
+            if (item == null) {
+                throw new ArgumentNullException("item");
+            }
+            base.InsertItem(index, item);
+        }
+
+        protected override void SetItem(int index, IValueProvider item) {
+            if (item == null) {
+                throw new ArgumentNullException("item");
+            }
+            base.SetItem(index, item);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ValueProviderDictionary.cs b/mcs/class/System.Web.Mvc3/Mvc/ValueProviderDictionary.cs
new file mode 100644 (file)
index 0000000..60f7e23
--- /dev/null
@@ -0,0 +1,194 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Collections.Specialized;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Web.Routing;
+
+    [Obsolete("The recommended alternative is to use one of the specific ValueProvider types, such as FormValueProvider.")]
+    public class ValueProviderDictionary : IDictionary<string, ValueProviderResult>, IValueProvider {
+
+        private readonly Dictionary<string, ValueProviderResult> _dictionary = new Dictionary<string, ValueProviderResult>(StringComparer.OrdinalIgnoreCase);
+
+        public ValueProviderDictionary(ControllerContext controllerContext) {
+            ControllerContext = controllerContext;
+            if (controllerContext != null) {
+                PopulateDictionary();
+            }
+        }
+
+        public ControllerContext ControllerContext {
+            get;
+            private set;
+        }
+
+        public int Count {
+            get {
+                return ((ICollection<KeyValuePair<string, ValueProviderResult>>)Dictionary).Count;
+            }
+        }
+
+        internal Dictionary<string, ValueProviderResult> Dictionary {
+            get {
+                return _dictionary;
+            }
+        }
+
+        public bool IsReadOnly {
+            get {
+                return ((ICollection<KeyValuePair<string, ValueProviderResult>>)Dictionary).IsReadOnly;
+            }
+        }
+
+        public ICollection<string> Keys {
+            get {
+                return Dictionary.Keys;
+            }
+        }
+
+        public ValueProviderResult this[string key] {
+            get {
+                ValueProviderResult result;
+                Dictionary.TryGetValue(key, out result);
+                return result;
+            }
+            set {
+                Dictionary[key] = value;
+            }
+        }
+
+        public ICollection<ValueProviderResult> Values {
+            get {
+                return Dictionary.Values;
+            }
+        }
+
+        public void Add(KeyValuePair<string, ValueProviderResult> item) {
+            ((ICollection<KeyValuePair<string, ValueProviderResult>>)Dictionary).Add(item);
+        }
+
+        public void Add(string key, object value) {
+            string attemptedValue = Convert.ToString(value, CultureInfo.InvariantCulture);
+            ValueProviderResult vpResult = new ValueProviderResult(value, attemptedValue, CultureInfo.InvariantCulture);
+            Add(key, vpResult);
+        }
+
+        public void Add(string key, ValueProviderResult value) {
+            Dictionary.Add(key, value);
+        }
+
+        private void AddToDictionaryIfNotPresent(string key, ValueProviderResult result) {
+            if (!String.IsNullOrEmpty(key)) {
+                if (!Dictionary.ContainsKey(key)) {
+                    Dictionary.Add(key, result);
+                }
+            }
+        }
+
+        public void Clear() {
+            ((ICollection<KeyValuePair<string, ValueProviderResult>>)Dictionary).Clear();
+        }
+
+        public bool Contains(KeyValuePair<string, ValueProviderResult> item) {
+            return ((ICollection<KeyValuePair<string, ValueProviderResult>>)Dictionary).Contains(item);
+        }
+
+        public bool ContainsKey(string key) {
+            return Dictionary.ContainsKey(key);
+        }
+
+        public void CopyTo(KeyValuePair<string, ValueProviderResult>[] array, int arrayIndex) {
+            ((ICollection<KeyValuePair<string, ValueProviderResult>>)Dictionary).CopyTo(array, arrayIndex);
+        }
+
+        public IEnumerator<KeyValuePair<string, ValueProviderResult>> GetEnumerator() {
+            return ((IEnumerable<KeyValuePair<string, ValueProviderResult>>)Dictionary).GetEnumerator();
+        }
+
+        private void PopulateDictionary() {
+            CultureInfo currentCulture = CultureInfo.CurrentCulture;
+            CultureInfo invariantCulture = CultureInfo.InvariantCulture;
+
+            // We use this order of precedence to populate the dictionary:
+            // 1. Request form submission (should be culture-aware)
+            // 2. Values from the RouteData (could be from the typed-in URL or from the route's default values)
+            // 3. URI query string
+
+            NameValueCollection form = ControllerContext.HttpContext.Request.Form;
+            if (form != null) {
+                string[] keys = form.AllKeys;
+                foreach (string key in keys) {
+                    string[] rawValue = form.GetValues(key);
+                    string attemptedValue = form[key];
+                    ValueProviderResult result = new ValueProviderResult(rawValue, attemptedValue, currentCulture);
+                    AddToDictionaryIfNotPresent(key, result);
+                }
+            }
+
+            RouteValueDictionary routeValues = ControllerContext.RouteData.Values;
+            if (routeValues != null) {
+                foreach (var kvp in routeValues) {
+                    string key = kvp.Key;
+                    object rawValue = kvp.Value;
+                    string attemptedValue = Convert.ToString(rawValue, invariantCulture);
+                    ValueProviderResult result = new ValueProviderResult(rawValue, attemptedValue, invariantCulture);
+                    AddToDictionaryIfNotPresent(key, result);
+                }
+            }
+
+            NameValueCollection queryString = ControllerContext.HttpContext.Request.QueryString;
+            if (queryString != null) {
+                string[] keys = queryString.AllKeys;
+                foreach (string key in keys) {
+                    string[] rawValue = queryString.GetValues(key);
+                    string attemptedValue = queryString[key];
+                    ValueProviderResult result = new ValueProviderResult(rawValue, attemptedValue, invariantCulture);
+                    AddToDictionaryIfNotPresent(key, result);
+                }
+            }
+        }
+
+        public bool Remove(KeyValuePair<string, ValueProviderResult> item) {
+            return ((ICollection<KeyValuePair<string, ValueProviderResult>>)Dictionary).Remove(item);
+        }
+
+        public bool Remove(string key) {
+            return Dictionary.Remove(key);
+        }
+
+        public bool TryGetValue(string key, out ValueProviderResult value) {
+            return Dictionary.TryGetValue(key, out value);
+        }
+
+        #region IEnumerable Members
+        IEnumerator IEnumerable.GetEnumerator() {
+            return ((IEnumerable)Dictionary).GetEnumerator();
+        }
+        #endregion
+
+        #region IValueProvider Members
+        [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Justification = "The declaring type is obsolete, so there is little benefit to exposing this as a virtual method.")]
+        bool IValueProvider.ContainsPrefix(string prefix) {
+            if (prefix == null) {
+                throw new ArgumentNullException("prefix");
+            }
+
+            return ValueProviderUtil.CollectionContainsPrefix(Keys, prefix);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Justification = "The declaring type is obsolete, so there is little benefit to exposing this as a virtual method.")]
+        ValueProviderResult IValueProvider.GetValue(string key) {
+            if (key == null) {
+                throw new ArgumentNullException("key");
+            }
+
+            ValueProviderResult vpResult;
+            TryGetValue(key, out vpResult);
+            return vpResult;
+        }
+        #endregion
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ValueProviderFactories.cs b/mcs/class/System.Web.Mvc3/Mvc/ValueProviderFactories.cs
new file mode 100644 (file)
index 0000000..bf9df94
--- /dev/null
@@ -0,0 +1,22 @@
+namespace System.Web.Mvc {
+    using System;
+
+    public static class ValueProviderFactories {
+
+        private static readonly ValueProviderFactoryCollection _factories = new ValueProviderFactoryCollection() {
+            new ChildActionValueProviderFactory(),
+            new FormValueProviderFactory(),
+            new JsonValueProviderFactory(),
+            new RouteDataValueProviderFactory(),
+            new QueryStringValueProviderFactory(),
+            new HttpFileCollectionValueProviderFactory(),
+        };
+
+        public static ValueProviderFactoryCollection Factories {
+            get {
+                return _factories;
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ValueProviderFactory.cs b/mcs/class/System.Web.Mvc3/Mvc/ValueProviderFactory.cs
new file mode 100644 (file)
index 0000000..52d4fac
--- /dev/null
@@ -0,0 +1,7 @@
+namespace System.Web.Mvc {
+    using System;
+
+    public abstract class ValueProviderFactory {
+        public abstract IValueProvider GetValueProvider(ControllerContext controllerContext);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ValueProviderFactoryCollection.cs b/mcs/class/System.Web.Mvc3/Mvc/ValueProviderFactoryCollection.cs
new file mode 100644 (file)
index 0000000..14a1dbf
--- /dev/null
@@ -0,0 +1,51 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Collections.ObjectModel;
+    using System.Linq;
+
+    public class ValueProviderFactoryCollection : Collection<ValueProviderFactory> {
+        private IResolver<IEnumerable<ValueProviderFactory>> _serviceResolver;
+
+        public ValueProviderFactoryCollection() {
+            _serviceResolver = new MultiServiceResolver<ValueProviderFactory>(() => Items);
+        }
+
+        public ValueProviderFactoryCollection(IList<ValueProviderFactory> list)
+            : base(list) {
+            _serviceResolver = new MultiServiceResolver<ValueProviderFactory>(() => Items);
+        }
+
+        internal ValueProviderFactoryCollection(IResolver<IEnumerable<ValueProviderFactory>> serviceResolver, params ValueProviderFactory[] valueProviderFactories)
+            : base(valueProviderFactories) {
+            _serviceResolver = serviceResolver ?? new MultiServiceResolver<ValueProviderFactory>(
+                   () => Items
+                   );
+        }
+
+        public IValueProvider GetValueProvider(ControllerContext controllerContext) {
+            var valueProviders = from factory in _serviceResolver.Current
+                                 let valueProvider = factory.GetValueProvider(controllerContext)
+                                 where valueProvider != null
+                                 select valueProvider;
+
+            return new ValueProviderCollection(valueProviders.ToList());
+        }
+
+
+        protected override void InsertItem(int index, ValueProviderFactory item) {
+            if (item == null) {
+                throw new ArgumentNullException("item");
+            }
+            base.InsertItem(index, item);
+        }
+
+        protected override void SetItem(int index, ValueProviderFactory item) {
+            if (item == null) {
+                throw new ArgumentNullException("item");
+            }
+            base.SetItem(index, item);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ValueProviderResult.cs b/mcs/class/System.Web.Mvc3/Mvc/ValueProviderResult.cs
new file mode 100644 (file)
index 0000000..6c36dc2
--- /dev/null
@@ -0,0 +1,135 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections;
+    using System.ComponentModel;
+    using System.Globalization;
+    using System.Web.Mvc.Resources;
+
+    [Serializable]
+    public class ValueProviderResult {
+
+        private static readonly CultureInfo _staticCulture = CultureInfo.InvariantCulture;
+        private CultureInfo _instanceCulture;
+
+        // default constructor so that subclassed types can set the properties themselves
+        protected ValueProviderResult() {
+        }
+
+        public ValueProviderResult(object rawValue, string attemptedValue, CultureInfo culture) {
+            RawValue = rawValue;
+            AttemptedValue = attemptedValue;
+            Culture = culture;
+        }
+
+        public string AttemptedValue {
+            get;
+            protected set;
+        }
+
+        public CultureInfo Culture {
+            get {
+                if (_instanceCulture == null) {
+                    _instanceCulture = _staticCulture;
+                }
+                return _instanceCulture;
+            }
+            protected set {
+                _instanceCulture = value;
+            }
+        }
+
+        public object RawValue {
+            get;
+            protected set;
+        }
+
+        private static object ConvertSimpleType(CultureInfo culture, object value, Type destinationType) {
+            if (value == null || destinationType.IsInstanceOfType(value)) {
+                return value;
+            }
+
+            // if this is a user-input value but the user didn't type anything, return no value
+            string valueAsString = value as string;
+            if (valueAsString != null && valueAsString.Trim().Length == 0) {
+                return null;
+            }
+
+            TypeConverter converter = TypeDescriptor.GetConverter(destinationType);
+            bool canConvertFrom = converter.CanConvertFrom(value.GetType());
+            if (!canConvertFrom) {
+                converter = TypeDescriptor.GetConverter(value.GetType());
+            }
+            if (!(canConvertFrom || converter.CanConvertTo(destinationType))) {
+                string message = String.Format(CultureInfo.CurrentCulture, MvcResources.ValueProviderResult_NoConverterExists,
+                    value.GetType().FullName, destinationType.FullName);
+                throw new InvalidOperationException(message);
+            }
+
+            try {
+                object convertedValue = (canConvertFrom) ?
+                     converter.ConvertFrom(null /* context */, culture, value) :
+                     converter.ConvertTo(null /* context */, culture, value, destinationType);
+                return convertedValue;
+            }
+            catch (Exception ex) {
+                string message = String.Format(CultureInfo.CurrentCulture, MvcResources.ValueProviderResult_ConversionThrew,
+                    value.GetType().FullName, destinationType.FullName);
+                throw new InvalidOperationException(message, ex);
+            }
+        }
+
+        public object ConvertTo(Type type) {
+            return ConvertTo(type, null /* culture */);
+        }
+
+        public virtual object ConvertTo(Type type, CultureInfo culture) {
+            if (type == null) {
+                throw new ArgumentNullException("type");
+            }
+
+            CultureInfo cultureToUse = culture ?? Culture;
+            return UnwrapPossibleArrayType(cultureToUse, RawValue, type);
+        }
+
+        private static object UnwrapPossibleArrayType(CultureInfo culture, object value, Type destinationType) {
+            if (value == null || destinationType.IsInstanceOfType(value)) {
+                return value;
+            }
+
+            // array conversion results in four cases, as below
+            Array valueAsArray = value as Array;
+            if (destinationType.IsArray) {
+                Type destinationElementType = destinationType.GetElementType();
+                if (valueAsArray != null) {
+                    // case 1: both destination + source type are arrays, so convert each element
+                    IList converted = Array.CreateInstance(destinationElementType, valueAsArray.Length);
+                    for (int i = 0; i < valueAsArray.Length; i++) {
+                        converted[i] = ConvertSimpleType(culture, valueAsArray.GetValue(i), destinationElementType);
+                    }
+                    return converted;
+                }
+                else {
+                    // case 2: destination type is array but source is single element, so wrap element in array + convert
+                    object element = ConvertSimpleType(culture, value, destinationElementType);
+                    IList converted = Array.CreateInstance(destinationElementType, 1);
+                    converted[0] = element;
+                    return converted;
+                }
+            }
+            else if (valueAsArray != null) {
+                // case 3: destination type is single element but source is array, so extract first element + convert
+                if (valueAsArray.Length > 0) {
+                    value = valueAsArray.GetValue(0);
+                    return ConvertSimpleType(culture, value, destinationType);
+                }
+                else {
+                    // case 3(a): source is empty array, so can't perform conversion
+                    return null;
+                }
+            }
+            // case 4: both destination + source type are single elements, so convert
+            return ConvertSimpleType(culture, value, destinationType);
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ValueProviderUtil.cs b/mcs/class/System.Web.Mvc3/Mvc/ValueProviderUtil.cs
new file mode 100644 (file)
index 0000000..09e0e38
--- /dev/null
@@ -0,0 +1,51 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Linq;
+
+    internal static class ValueProviderUtil {
+
+        // Given "foo.bar[baz].quux", this method will return:
+        // - "foo.bar[baz].quux"
+        // - "foo.bar[baz]"
+        // - "foo.bar"
+        // - "foo"
+        public static IEnumerable<string> GetPrefixes(string key) {
+            yield return key;
+            for (int i = key.Length - 1; i >= 0; i--) {
+                switch (key[i]) {
+                    case '.':
+                    case '[':
+                        yield return key.Substring(0, i);
+                        break;
+                }
+            }
+        }
+
+        public static bool CollectionContainsPrefix(IEnumerable<string> collection, string prefix) {
+            foreach (string key in collection) {
+                if (key != null) {
+                    if (prefix.Length == 0) {
+                        return true; // shortcut - non-null key matches empty prefix
+                    }
+
+                    if (key.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) {
+                        if (key.Length == prefix.Length) {
+                            return true; // exact match
+                        }
+                        else {
+                            switch (key[prefix.Length]) {
+                                case '.': // known separator characters
+                                case '[':
+                                    return true;
+                            }
+                        }
+                    }
+                }
+            }
+
+            return false; // nothing found
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ViewContext.cs b/mcs/class/System.Web.Mvc3/Mvc/ViewContext.cs
new file mode 100644 (file)
index 0000000..fc68729
--- /dev/null
@@ -0,0 +1,259 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.IO;
+    using System.Web.WebPages.Scope;
+
+    public class ViewContext : ControllerContext {
+
+        private const string _clientValidationScript = @"<script type=""text/javascript"">
+//<![CDATA[
+if (!window.mvcClientValidationMetadata) {{ window.mvcClientValidationMetadata = []; }}
+window.mvcClientValidationMetadata.push({0});
+//]]>
+</script>";
+
+        internal static readonly string ClientValidationKeyName = "ClientValidationEnabled";
+        internal static readonly string UnobtrusiveJavaScriptKeyName = "UnobtrusiveJavaScriptEnabled";
+
+        // Some values have to be stored in HttpContext.Items in order to be propagated between calls
+        // to RenderPartial(), RenderAction(), etc.
+        private static readonly object _formContextKey = new object();
+        private static readonly object _lastFormNumKey = new object();
+
+        private Func<IDictionary<object, object>> _scopeThunk;
+        private IDictionary<object, object> _transientScope;
+
+        private Func<string> _formIdGenerator;
+
+        // parameterless constructor used for mocking
+        public ViewContext() {
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", Justification = "The virtual property setters are only to support mocking frameworks, in which case this constructor shouldn't be called anyway.")]
+        public ViewContext(ControllerContext controllerContext, IView view, ViewDataDictionary viewData, TempDataDictionary tempData, TextWriter writer)
+            : base(controllerContext) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+            if (view == null) {
+                throw new ArgumentNullException("view");
+            }
+            if (viewData == null) {
+                throw new ArgumentNullException("viewData");
+            }
+            if (tempData == null) {
+                throw new ArgumentNullException("tempData");
+            }
+            if (writer == null) {
+                throw new ArgumentNullException("writer");
+            }
+
+            View = view;
+            ViewData = viewData;
+            Writer = writer;
+            TempData = tempData;
+        }
+
+        public virtual bool ClientValidationEnabled {
+            get {
+                return GetClientValidationEnabled(Scope, HttpContext);
+            }
+            set {
+                SetClientValidationEnabled(value, Scope, HttpContext);
+            }
+        }
+
+        public virtual FormContext FormContext {
+            get {
+                return HttpContext.Items[_formContextKey] as FormContext;
+            }
+            set {
+                HttpContext.Items[_formContextKey] = value;
+            }
+        }
+
+        internal Func<string> FormIdGenerator {
+            get {
+                if (_formIdGenerator == null) {
+                    _formIdGenerator = DefaultFormIdGenerator;
+                }
+                return _formIdGenerator;
+            }
+            set {
+                _formIdGenerator = value;
+            }
+        }
+
+        internal static Func<IDictionary<object, object>> GlobalScopeThunk {
+            get;
+            set;
+        }
+
+        private IDictionary<object, object> Scope {
+            get {
+                if (ScopeThunk != null) {
+                    return ScopeThunk();
+                }
+                if (_transientScope == null) {
+                    _transientScope = new Dictionary<object, object>();
+                }
+                return _transientScope;
+            }
+        }
+
+        internal Func<IDictionary<object, object>> ScopeThunk {
+            get {
+                return _scopeThunk ?? GlobalScopeThunk;
+            }
+            set {
+                _scopeThunk = value;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "The property setter is only here to support mocking this type and should not be called at runtime.")]
+        public virtual TempDataDictionary TempData {
+            get;
+            set;
+        }
+
+        public virtual bool UnobtrusiveJavaScriptEnabled {
+            get {
+                return GetUnobtrusiveJavaScriptEnabled(Scope, HttpContext);
+            }
+            set {
+                SetUnobtrusiveJavaScriptEnabled(value, Scope, HttpContext);
+            }
+        }
+
+        public virtual IView View {
+            get;
+            set;
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "The property setter is only here to support mocking this type and should not be called at runtime.")]
+        public virtual ViewDataDictionary ViewData {
+            get;
+            set;
+        }
+
+        public virtual TextWriter Writer {
+            get;
+            set;
+        }
+
+        private string DefaultFormIdGenerator() {
+            int formNum = IncrementFormCount(HttpContext.Items);
+            return String.Format(CultureInfo.InvariantCulture, "form{0}", formNum);
+        }
+
+        internal static bool GetClientValidationEnabled(IDictionary<object, object> scope = null, HttpContextBase httpContext = null) {
+            return ScopeCache.Get(scope, httpContext).ClientValidationEnabled;
+        }
+
+        internal FormContext GetFormContextForClientValidation() {
+            return (ClientValidationEnabled) ? FormContext : null;
+        }
+
+        internal static bool GetUnobtrusiveJavaScriptEnabled(IDictionary<object, object> scope = null, HttpContextBase httpContext = null) {
+            return ScopeCache.Get(scope, httpContext).UnobtrusiveJavaScriptEnabled;
+        }
+
+        private static int IncrementFormCount(IDictionary items) {
+            object lastFormNum = items[_lastFormNumKey];
+            int newFormNum = (lastFormNum != null) ? ((int)lastFormNum) + 1 : 0;
+            items[_lastFormNumKey] = newFormNum;
+            return newFormNum;
+        }
+
+        public void OutputClientValidation() {
+            FormContext formContext = GetFormContextForClientValidation();
+            if (formContext == null || UnobtrusiveJavaScriptEnabled) {
+                return; // do nothing
+            }
+
+            string scriptWithCorrectNewLines = _clientValidationScript.Replace("\r\n", Environment.NewLine);
+            string validationJson = formContext.GetJsonValidationMetadata();
+            string formatted = String.Format(CultureInfo.InvariantCulture, scriptWithCorrectNewLines, validationJson);
+
+            Writer.Write(formatted);
+            FormContext = null;
+        }
+
+        internal static void SetClientValidationEnabled(bool enabled, IDictionary<object, object> scope = null, HttpContextBase httpContext = null) {
+            ScopeCache.Get(scope, httpContext).ClientValidationEnabled = enabled;
+        }
+
+        internal static void SetUnobtrusiveJavaScriptEnabled(bool enabled, IDictionary<object, object> scope = null, HttpContextBase httpContext = null) {
+            ScopeCache.Get(scope, httpContext).UnobtrusiveJavaScriptEnabled = enabled;
+        }
+
+        private static TValue ScopeGet<TValue>(IDictionary<object, object> scope, string name, TValue defaultValue = default(TValue)) {
+            object result;
+            if (scope.TryGetValue(name, out result)) {
+                return (TValue)Convert.ChangeType(result, typeof(TValue), CultureInfo.InvariantCulture);
+            }
+            return defaultValue;
+        }
+
+        private sealed class ScopeCache {
+            private static readonly object _cacheKey = new object();
+            private bool _clientValidationEnabled;
+            private IDictionary<object, object> _scope;
+            private bool _unobtrusiveJavaScriptEnabled;
+
+            private ScopeCache(IDictionary<object, object> scope) {
+                _scope = scope;
+
+                _clientValidationEnabled = ScopeGet(scope, ClientValidationKeyName, false);
+                _unobtrusiveJavaScriptEnabled = ScopeGet(scope, UnobtrusiveJavaScriptKeyName, false);
+            }
+
+            public bool ClientValidationEnabled {
+                get {
+                    return _clientValidationEnabled;
+                }
+                set {
+                    _clientValidationEnabled = value;
+                    _scope[ClientValidationKeyName] = value;
+                }
+            }
+
+            public bool UnobtrusiveJavaScriptEnabled {
+                get {
+                    return _unobtrusiveJavaScriptEnabled;
+                }
+                set {
+                    _unobtrusiveJavaScriptEnabled = value;
+                    _scope[UnobtrusiveJavaScriptKeyName] = value;
+                }
+            }
+
+            public static ScopeCache Get(IDictionary<object, object> scope, HttpContextBase httpContext) {
+                if (httpContext == null && System.Web.HttpContext.Current != null) {
+                    httpContext = new HttpContextWrapper(System.Web.HttpContext.Current);
+                }
+
+                ScopeCache result = null;
+                scope = scope ?? ScopeStorage.CurrentScope;
+
+                if (httpContext != null) {
+                    result = httpContext.Items[_cacheKey] as ScopeCache;
+                }
+
+                if (result == null || result._scope != scope) {
+                    result = new ScopeCache(scope);
+
+                    if (httpContext != null) {
+                        httpContext.Items[_cacheKey] = result;
+                    }
+                }
+
+                return result;
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ViewDataDictionary.cs b/mcs/class/System.Web.Mvc3/Mvc/ViewDataDictionary.cs
new file mode 100644 (file)
index 0000000..576280e
--- /dev/null
@@ -0,0 +1,340 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.ComponentModel;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Reflection;
+    using System.Web.Mvc.Resources;
+
+    // TODO: Unit test ModelState interaction with VDD
+
+    public class ViewDataDictionary : IDictionary<string, object> {
+
+        private readonly Dictionary<string, object> _innerDictionary = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
+        private object _model;
+        private ModelMetadata _modelMetadata;
+        private readonly ModelStateDictionary _modelState = new ModelStateDictionary();
+        private TemplateInfo _templateMetadata;
+
+        public ViewDataDictionary()
+            : this((object)null) {
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", Justification = "See note on SetModel() method.")]
+        public ViewDataDictionary(object model) {
+            Model = model;
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", Justification = "See note on SetModel() method.")]
+        public ViewDataDictionary(ViewDataDictionary dictionary) {
+            if (dictionary == null) {
+                throw new ArgumentNullException("dictionary");
+            }
+
+            foreach (var entry in dictionary) {
+                _innerDictionary.Add(entry.Key, entry.Value);
+            }
+            foreach (var entry in dictionary.ModelState) {
+                ModelState.Add(entry.Key, entry.Value);
+            }
+
+            Model = dictionary.Model;
+            TemplateInfo = dictionary.TemplateInfo;
+
+            // PERF: Don't unnecessarily instantiate the model metadata
+            _modelMetadata = dictionary._modelMetadata;
+        }
+
+        public int Count {
+            get {
+                return _innerDictionary.Count;
+            }
+        }
+
+        public bool IsReadOnly {
+            get {
+                return ((IDictionary<string, object>)_innerDictionary).IsReadOnly;
+            }
+        }
+
+        public ICollection<string> Keys {
+            get {
+                return _innerDictionary.Keys;
+            }
+        }
+
+        public object Model {
+            get {
+                return _model;
+            }
+            set {
+                _modelMetadata = null;
+                SetModel(value);
+            }
+        }
+
+        public virtual ModelMetadata ModelMetadata {
+            get {
+                if (_modelMetadata == null && _model != null) {
+                    _modelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => _model, _model.GetType());
+                }
+                return _modelMetadata;
+            }
+            set {
+                _modelMetadata = value;
+            }
+        }
+
+        public ModelStateDictionary ModelState {
+            get {
+                return _modelState;
+            }
+        }
+
+        public object this[string key] {
+            get {
+                object value;
+                _innerDictionary.TryGetValue(key, out value);
+                return value;
+            }
+            set {
+                _innerDictionary[key] = value;
+            }
+        }
+
+        public TemplateInfo TemplateInfo {
+            get {
+                if (_templateMetadata == null) {
+                    _templateMetadata = new TemplateInfo();
+                }
+                return _templateMetadata;
+            }
+            set {
+                _templateMetadata = value;
+            }
+        }
+
+        public ICollection<object> Values {
+            get {
+                return _innerDictionary.Values;
+            }
+        }
+
+        public void Add(KeyValuePair<string, object> item) {
+            ((IDictionary<string, object>)_innerDictionary).Add(item);
+        }
+
+        public void Add(string key, object value) {
+            _innerDictionary.Add(key, value);
+        }
+
+        public void Clear() {
+            _innerDictionary.Clear();
+        }
+
+        public bool Contains(KeyValuePair<string, object> item) {
+            return ((IDictionary<string, object>)_innerDictionary).Contains(item);
+        }
+
+        public bool ContainsKey(string key) {
+            return _innerDictionary.ContainsKey(key);
+        }
+
+        public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex) {
+            ((IDictionary<string, object>)_innerDictionary).CopyTo(array, arrayIndex);
+        }
+
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Eval", Justification = "Commonly used shorthand for Evaluate.")]
+        public object Eval(string expression) {
+            ViewDataInfo info = GetViewDataInfo(expression);
+            return (info != null) ? info.Value : null;
+        }
+
+        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Eval", Justification = "Commonly used shorthand for Evaluate.")]
+        public string Eval(string expression, string format) {
+            object value = Eval(expression);
+
+            if (value == null) {
+                return String.Empty;
+            }
+
+            if (String.IsNullOrEmpty(format)) {
+                return Convert.ToString(value, CultureInfo.CurrentCulture);
+            }
+            else {
+                return String.Format(CultureInfo.CurrentCulture, format, value);
+            }
+        }
+
+        public IEnumerator<KeyValuePair<string, object>> GetEnumerator() {
+            return _innerDictionary.GetEnumerator();
+        }
+
+        public ViewDataInfo GetViewDataInfo(string expression) {
+            if (String.IsNullOrEmpty(expression)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "expression");
+            }
+
+            return ViewDataEvaluator.Eval(this, expression);
+        }
+
+        public bool Remove(KeyValuePair<string, object> item) {
+            return ((IDictionary<string, object>)_innerDictionary).Remove(item);
+        }
+
+        public bool Remove(string key) {
+            return _innerDictionary.Remove(key);
+        }
+
+        // This method will execute before the derived type's instance constructor executes. Derived types must
+        // be aware of this and should plan accordingly. For example, the logic in SetModel() should be simple
+        // enough so as not to depend on the "this" pointer referencing a fully constructed object.
+        protected virtual void SetModel(object value) {
+            _model = value;
+        }
+
+        public bool TryGetValue(string key, out object value) {
+            return _innerDictionary.TryGetValue(key, out value);
+        }
+
+        internal static class ViewDataEvaluator {
+
+            public static ViewDataInfo Eval(ViewDataDictionary vdd, string expression) {
+                //Given an expression "foo.bar.baz" we look up the following (pseudocode):
+                //  this["foo.bar.baz.quux"]
+                //  this["foo.bar.baz"]["quux"]
+                //  this["foo.bar"]["baz.quux]
+                //  this["foo.bar"]["baz"]["quux"]
+                //  this["foo"]["bar.baz.quux"]
+                //  this["foo"]["bar.baz"]["quux"]
+                //  this["foo"]["bar"]["baz.quux"]
+                //  this["foo"]["bar"]["baz"]["quux"]
+
+                ViewDataInfo evaluated = EvalComplexExpression(vdd, expression);
+                return evaluated;
+            }
+
+            private static ViewDataInfo EvalComplexExpression(object indexableObject, string expression) {
+                foreach (ExpressionPair expressionPair in GetRightToLeftExpressions(expression)) {
+                    string subExpression = expressionPair.Left;
+                    string postExpression = expressionPair.Right;
+
+                    ViewDataInfo subTargetInfo = GetPropertyValue(indexableObject, subExpression);
+                    if (subTargetInfo != null) {
+                        if (String.IsNullOrEmpty(postExpression)) {
+                            return subTargetInfo;
+                        }
+
+                        if (subTargetInfo.Value != null) {
+                            ViewDataInfo potential = EvalComplexExpression(subTargetInfo.Value, postExpression);
+                            if (potential != null) {
+                                return potential;
+                            }
+                        }
+                    }
+                }
+                return null;
+            }
+
+            private static IEnumerable<ExpressionPair> GetRightToLeftExpressions(string expression) {
+                // Produces an enumeration of all the combinations of complex property names
+                // given a complex expression. See the list above for an example of the result
+                // of the enumeration.
+
+                yield return new ExpressionPair(expression, String.Empty);
+
+                int lastDot = expression.LastIndexOf('.');
+
+                string subExpression = expression;
+                string postExpression = string.Empty;
+
+                while (lastDot > -1) {
+                    subExpression = expression.Substring(0, lastDot);
+                    postExpression = expression.Substring(lastDot + 1);
+                    yield return new ExpressionPair(subExpression, postExpression);
+
+                    lastDot = subExpression.LastIndexOf('.');
+                }
+            }
+
+            private static ViewDataInfo GetIndexedPropertyValue(object indexableObject, string key) {
+                IDictionary<string, object> dict = indexableObject as IDictionary<string, object>;
+                object value = null;
+                bool success = false;
+
+                if (dict != null) {
+                    success = dict.TryGetValue(key, out value);
+                }
+                else {
+                    TryGetValueDelegate tgvDel = TypeHelpers.CreateTryGetValueDelegate(indexableObject.GetType());
+                    if (tgvDel != null) {
+                        success = tgvDel(indexableObject, key, out value);
+                    }
+                }
+
+                if (success) {
+                    return new ViewDataInfo() {
+                        Container = indexableObject,
+                        Value = value
+                    };
+                }
+
+                return null;
+            }
+
+            private static ViewDataInfo GetPropertyValue(object container, string propertyName) {
+                // This method handles one "segment" of a complex property expression
+
+                // First, we try to evaluate the property based on its indexer
+                ViewDataInfo value = GetIndexedPropertyValue(container, propertyName);
+                if (value != null) {
+                    return value;
+                }
+
+                // If the indexer didn't return anything useful, continue...
+
+                // If the container is a ViewDataDictionary then treat its Model property
+                // as the container instead of the ViewDataDictionary itself.
+                ViewDataDictionary vdd = container as ViewDataDictionary;
+                if (vdd != null) {
+                    container = vdd.Model;
+                }
+
+                // If the container is null, we're out of options
+                if (container == null) {
+                    return null;
+                }
+
+                // Second, we try to use PropertyDescriptors and treat the expression as a property name
+                PropertyDescriptor descriptor = TypeDescriptor.GetProperties(container).Find(propertyName, true);
+                if (descriptor == null) {
+                    return null;
+                }
+
+                return new ViewDataInfo(() => descriptor.GetValue(container)) {
+                    Container = container,
+                    PropertyDescriptor = descriptor
+                };
+            }
+
+            private struct ExpressionPair {
+                public readonly string Left;
+                public readonly string Right;
+
+                public ExpressionPair(string left, string right) {
+                    Left = left;
+                    Right = right;
+                }
+            }
+        }
+
+        #region IEnumerable Members
+        IEnumerator IEnumerable.GetEnumerator() {
+            return ((IEnumerable)_innerDictionary).GetEnumerator();
+        }
+        #endregion
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ViewDataDictionary`1.cs b/mcs/class/System.Web.Mvc3/Mvc/ViewDataDictionary`1.cs
new file mode 100644 (file)
index 0000000..3c9c9c4
--- /dev/null
@@ -0,0 +1,54 @@
+namespace System.Web.Mvc {
+    using System;
+
+    public class ViewDataDictionary<TModel> : ViewDataDictionary {
+        public ViewDataDictionary() :
+            base(default(TModel)) {
+        }
+
+        public ViewDataDictionary(TModel model) :
+            base(model) {
+        }
+
+        public ViewDataDictionary(ViewDataDictionary viewDataDictionary) :
+            base(viewDataDictionary) {
+        }
+
+        public new TModel Model {
+            get {
+                return (TModel)base.Model;
+            }
+            set {
+                SetModel(value);
+            }
+        }
+
+        public override ModelMetadata ModelMetadata {
+            get {
+                ModelMetadata result = base.ModelMetadata;
+                if (result == null) {
+                    result = base.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(TModel));
+                }
+                return result;
+            }
+            set {
+                base.ModelMetadata = value;
+            }
+        }
+
+        protected override void SetModel(object value) {
+            bool castWillSucceed = TypeHelpers.IsCompatibleObject<TModel>(value);
+
+            if (castWillSucceed) {
+                base.SetModel((TModel)value);
+            }
+            else {
+                InvalidOperationException exception = (value != null)
+                    ? Error.ViewDataDictionary_WrongTModelType(value.GetType(), typeof(TModel))
+                    : Error.ViewDataDictionary_ModelCannotBeNull(typeof(TModel));
+                throw exception;
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ViewDataInfo.cs b/mcs/class/System.Web.Mvc3/Mvc/ViewDataInfo.cs
new file mode 100644 (file)
index 0000000..31e0201
--- /dev/null
@@ -0,0 +1,43 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.ComponentModel;
+
+    public class ViewDataInfo {
+
+        private object _value;
+        private Func<object> _valueAccessor;
+
+        public ViewDataInfo() {
+        }
+
+        public ViewDataInfo(Func<object> valueAccessor) {
+            _valueAccessor = valueAccessor;
+        }
+
+        public object Container {
+            get;
+            set;
+        }
+
+        public PropertyDescriptor PropertyDescriptor {
+            get;
+            set;
+        }
+
+        public object Value {
+            get {
+                if (_valueAccessor != null) {
+                    _value = _valueAccessor();
+                    _valueAccessor = null;
+                }
+
+                return _value;
+            }
+            set {
+                _value = value;
+                _valueAccessor = null;
+            }
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ViewEngineCollection.cs b/mcs/class/System.Web.Mvc3/Mvc/ViewEngineCollection.cs
new file mode 100644 (file)
index 0000000..e394c67
--- /dev/null
@@ -0,0 +1,112 @@
+namespace System.Web.Mvc {
+    using System.Collections.Generic;
+    using System.Collections.ObjectModel;
+    using System.Linq;
+    using System.Web.Mvc.Resources;
+
+    public class ViewEngineCollection : Collection<IViewEngine> {
+        private IResolver<IEnumerable<IViewEngine>> _serviceResolver;
+
+        public ViewEngineCollection() {
+            _serviceResolver = new MultiServiceResolver<IViewEngine>(() => Items);
+        }
+
+        public ViewEngineCollection(IList<IViewEngine> list)
+            : base(list) {
+            _serviceResolver = new MultiServiceResolver<IViewEngine>(() => Items);
+        }
+
+        internal ViewEngineCollection(IResolver<IEnumerable<IViewEngine>> serviceResolver, params IViewEngine[] engines)
+            : base(engines) {
+            _serviceResolver = serviceResolver ?? new MultiServiceResolver<IViewEngine>(
+                () => Items
+                );
+        }
+        private IEnumerable<IViewEngine> CombinedItems {
+            get {
+                return _serviceResolver.Current;
+            }
+        }
+
+        protected override void InsertItem(int index, IViewEngine item) {
+            if (item == null) {
+                throw new ArgumentNullException("item");
+            }
+            base.InsertItem(index, item);
+        }
+
+        protected override void SetItem(int index, IViewEngine item) {
+            if (item == null) {
+                throw new ArgumentNullException("item");
+            }
+            base.SetItem(index, item);
+        }
+
+        private ViewEngineResult Find(Func<IViewEngine, ViewEngineResult> cacheLocator, Func<IViewEngine, ViewEngineResult> locator) {
+            // First, look up using the cacheLocator and do not track the searched paths in non-matching view engines
+            // Then, look up using the normal locator and track the searched paths so that an error view engine can be returned
+            return Find(cacheLocator, trackSearchedPaths: false)
+                ?? Find(locator, trackSearchedPaths: true);
+        }
+
+        private ViewEngineResult Find(Func<IViewEngine, ViewEngineResult> lookup, bool trackSearchedPaths) {
+            // Returns
+            //    1st result
+            // OR list of searched paths (if trackSearchedPaths == true)
+            // OR null
+            ViewEngineResult result;
+
+            List<string> searched = null;
+            if (trackSearchedPaths) {
+                searched = new List<string>();
+            }
+
+            foreach (IViewEngine engine in CombinedItems) {
+                if (engine != null) {
+                    result = lookup(engine);
+
+                    if (result.View != null) {
+                        return result;
+                    }
+
+                    if (trackSearchedPaths) {
+                        searched.AddRange(result.SearchedLocations);
+                    }
+                }
+            }
+
+            if (trackSearchedPaths) {
+                // Remove duplicate search paths since multiple view engines could have potentially looked at the same path
+                return new ViewEngineResult(searched.Distinct().ToList());
+            }
+            else {
+                return null;
+            }
+        }
+
+
+        public virtual ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+            if (string.IsNullOrEmpty(partialViewName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "partialViewName");
+            }
+
+            return Find(e => e.FindPartialView(controllerContext, partialViewName, true),
+                        e => e.FindPartialView(controllerContext, partialViewName, false));
+        }
+
+        public virtual ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+            if (string.IsNullOrEmpty(viewName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "viewName");
+            }
+
+            return Find(e => e.FindView(controllerContext, viewName, masterName, true),
+                        e => e.FindView(controllerContext, viewName, masterName, false));
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ViewEngineResult.cs b/mcs/class/System.Web.Mvc3/Mvc/ViewEngineResult.cs
new file mode 100644 (file)
index 0000000..ef69d19
--- /dev/null
@@ -0,0 +1,42 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+
+    public class ViewEngineResult {
+
+        public ViewEngineResult(IEnumerable<string> searchedLocations) {
+            if (searchedLocations == null) {
+                throw new ArgumentNullException("searchedLocations");
+            }
+
+            SearchedLocations = searchedLocations;
+        }
+
+        public ViewEngineResult(IView view, IViewEngine viewEngine) {
+            if (view == null) {
+                throw new ArgumentNullException("view");
+            }
+            if (viewEngine == null) {
+                throw new ArgumentNullException("viewEngine");
+            }
+
+            View = view;
+            ViewEngine = viewEngine;
+        }
+
+        public IEnumerable<string> SearchedLocations {
+            get;
+            private set;
+        }
+
+        public IView View {
+            get;
+            private set;
+        }
+
+        public IViewEngine ViewEngine {
+            get;
+            private set;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ViewEngines.cs b/mcs/class/System.Web.Mvc3/Mvc/ViewEngines.cs
new file mode 100644 (file)
index 0000000..a71969f
--- /dev/null
@@ -0,0 +1,16 @@
+namespace System.Web.Mvc {
+
+    public static class ViewEngines {
+
+        private readonly static ViewEngineCollection _engines = new ViewEngineCollection {
+            new WebFormViewEngine(),
+            new RazorViewEngine(),
+        };
+
+        public static ViewEngineCollection Engines {
+            get {
+                return _engines;
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ViewMasterPage.cs b/mcs/class/System.Web.Mvc3/Mvc/ViewMasterPage.cs
new file mode 100644 (file)
index 0000000..903ccca
--- /dev/null
@@ -0,0 +1,72 @@
+namespace System.Web.Mvc {
+    using System.Globalization;
+    using System.Web.Mvc.Resources;
+    using System.Web.UI;
+
+    [FileLevelControlBuilder(typeof(ViewMasterPageControlBuilder))]
+    public class ViewMasterPage : MasterPage {
+        public AjaxHelper<object> Ajax {
+            get {
+                return ViewPage.Ajax;
+            }
+        }
+
+        public HtmlHelper<object> Html {
+            get {
+                return ViewPage.Html;
+            }
+        }
+
+        public object Model {
+            get {
+                return ViewData.Model;
+            }
+        }
+
+        public TempDataDictionary TempData {
+            get {
+                return ViewPage.TempData;
+            }
+        }
+
+        public UrlHelper Url {
+            get {
+                return ViewPage.Url;
+            }
+        }
+
+        public dynamic ViewBag {
+            get {
+                return ViewPage.ViewBag;
+            }
+        }
+
+        public ViewContext ViewContext {
+            get {
+                return ViewPage.ViewContext;
+            }
+        }
+
+        public ViewDataDictionary ViewData {
+            get {
+                return ViewPage.ViewData;
+            }
+        }
+
+        internal ViewPage ViewPage {
+            get {
+                ViewPage viewPage = Page as ViewPage;
+                if (viewPage == null) {
+                    throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, MvcResources.ViewMasterPage_RequiresViewPage));
+                }
+                return viewPage;
+            }
+        }
+
+        public HtmlTextWriter Writer {
+            get {
+                return ViewPage.Writer;
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ViewMasterPageControlBuilder.cs b/mcs/class/System.Web.Mvc3/Mvc/ViewMasterPageControlBuilder.cs
new file mode 100644 (file)
index 0000000..c0b3e68
--- /dev/null
@@ -0,0 +1,17 @@
+namespace System.Web.Mvc {
+    using System.CodeDom;
+    using System.Web.UI;
+
+    internal sealed class ViewMasterPageControlBuilder : FileLevelMasterPageControlBuilder, IMvcControlBuilder {
+        public string Inherits {
+            get;
+            set;
+        }
+
+        public override void ProcessGeneratedCode(CodeCompileUnit codeCompileUnit, CodeTypeDeclaration baseType, CodeTypeDeclaration derivedType, CodeMemberMethod buildMethod, CodeMemberMethod dataBindingMethod) {
+            if (!String.IsNullOrWhiteSpace(Inherits)) {
+                derivedType.BaseTypes[0] = new CodeTypeReference(Inherits);
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ViewMasterPage`1.cs b/mcs/class/System.Web.Mvc3/Mvc/ViewMasterPage`1.cs
new file mode 100644 (file)
index 0000000..f05663a
--- /dev/null
@@ -0,0 +1,41 @@
+namespace System.Web.Mvc {
+
+    public class ViewMasterPage<TModel> : ViewMasterPage {
+        private AjaxHelper<TModel> _ajaxHelper;
+        private HtmlHelper<TModel> _htmlHelper;
+        private ViewDataDictionary<TModel> _viewData;
+
+        public new AjaxHelper<TModel> Ajax {
+            get {
+                if (_ajaxHelper == null) {
+                    _ajaxHelper = new AjaxHelper<TModel>(ViewContext, ViewPage);
+                }
+                return _ajaxHelper;
+            }
+        }
+
+        public new HtmlHelper<TModel> Html {
+            get {
+                if (_htmlHelper == null) {
+                    _htmlHelper = new HtmlHelper<TModel>(ViewContext, ViewPage);
+                }
+                return _htmlHelper;
+            }
+        }
+
+        public new TModel Model {
+            get {
+                return ViewData.Model;
+            }
+        }
+
+        public new ViewDataDictionary<TModel> ViewData {
+            get {
+                if (_viewData == null) {
+                    _viewData = new ViewDataDictionary<TModel>(ViewPage.ViewData);
+                }
+                return _viewData;
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ViewPage.cs b/mcs/class/System.Web.Mvc3/Mvc/ViewPage.cs
new file mode 100644 (file)
index 0000000..5d696d8
--- /dev/null
@@ -0,0 +1,386 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.IO;
+    using System.Text;
+    using System.Web;
+    using System.Web.UI;
+
+    [FileLevelControlBuilder(typeof(ViewPageControlBuilder))]
+    public class ViewPage : Page, IViewDataContainer {
+
+        private DynamicViewDataDictionary _dynamicViewData;
+        private string _masterLocation;
+        [ThreadStatic]
+        private static int _nextId;
+        private ViewDataDictionary _viewData;
+
+        public AjaxHelper<object> Ajax {
+            get;
+            set;
+        }
+
+        public HtmlHelper<object> Html {
+            get;
+            set;
+        }
+
+        public string MasterLocation {
+            get {
+                return _masterLocation ?? String.Empty;
+            }
+            set {
+                _masterLocation = value;
+            }
+        }
+
+        public object Model {
+            get {
+                return ViewData.Model;
+            }
+        }
+
+        public TempDataDictionary TempData {
+            get {
+                return ViewContext.TempData;
+            }
+        }
+
+        public UrlHelper Url {
+            get;
+            set;
+        }
+
+        public dynamic ViewBag {
+            get {
+                if (_dynamicViewData == null) {
+                    _dynamicViewData = new DynamicViewDataDictionary(() => ViewData);
+                }
+                return _dynamicViewData;
+            }
+        }
+
+        public ViewContext ViewContext {
+            get;
+            set;
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "This is the mechanism by which the ViewPage gets its ViewDataDictionary object.")]
+        public ViewDataDictionary ViewData {
+            get {
+                if (_viewData == null) {
+                    SetViewData(new ViewDataDictionary());
+                }
+                return _viewData;
+            }
+            set {
+                SetViewData(value);
+            }
+        }
+
+        public HtmlTextWriter Writer {
+            get;
+            private set;
+        }
+
+        public virtual void InitHelpers() {
+            Ajax = new AjaxHelper<object>(ViewContext, this);
+            Html = new HtmlHelper<object>(ViewContext, this);
+            Url = new UrlHelper(ViewContext.RequestContext);
+        }
+
+        internal static string NextId() {
+            return (++_nextId).ToString(CultureInfo.InvariantCulture);
+        }
+
+        protected override void OnPreInit(EventArgs e) {
+            base.OnPreInit(e);
+
+            if (!String.IsNullOrEmpty(MasterLocation)) {
+                MasterPageFile = MasterLocation;
+            }
+        }
+
+        public override void ProcessRequest(HttpContext context) {
+            // Tracing requires IDs to be unique.
+            ID = NextId();
+
+            base.ProcessRequest(context);
+        }
+
+        protected override void Render(HtmlTextWriter writer) {
+            Writer = writer;
+            try {
+                base.Render(writer);
+            }
+            finally {
+                Writer = null;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "The object is disposed in the finally block of the method")]
+        public virtual void RenderView(ViewContext viewContext) {
+            ViewContext = viewContext;
+            InitHelpers();
+
+            bool createdSwitchWriter = false;
+            SwitchWriter switchWriter = viewContext.HttpContext.Response.Output as SwitchWriter;
+
+            try {
+                if (switchWriter == null) {
+                    switchWriter = new SwitchWriter();
+                    createdSwitchWriter = true;
+                }
+
+                using (switchWriter.Scope(viewContext.Writer)) {
+                    if (createdSwitchWriter) {
+                        // It's safe to reset the _nextId within a Server.Execute() since it pushes a new TraceContext onto
+                        // the stack, so there won't be an ID conflict.
+                        int originalNextId = _nextId;
+                        try {
+                            _nextId = 0;
+                            viewContext.HttpContext.Server.Execute(HttpHandlerUtil.WrapForServerExecute(this), switchWriter, true /* preserveForm */);
+                        }
+                        finally {
+                            // Restore the original _nextId in case this isn't actually the outermost view, since resetting
+                            // the _nextId may now cause trace ID conflicts in the outer view.
+                            _nextId = originalNextId;
+                        }
+                    }
+                    else {
+                        ProcessRequest(HttpContext.Current);
+                    }
+                }
+            }
+            finally {
+                if (createdSwitchWriter) {
+                    switchWriter.Dispose();
+                }
+            }
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "textWriter", Justification = "This method existed in MVC 1.0 and has been deprecated.")]
+        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "This method existed in MVC 1.0 and has been deprecated.")]
+        [Obsolete("The TextWriter is now provided by the ViewContext object passed to the RenderView method.", true /* error */)]
+        public void SetTextWriter(TextWriter textWriter) {
+            // this is now a no-op
+        }
+
+        protected virtual void SetViewData(ViewDataDictionary viewData) {
+            _viewData = viewData;
+        }
+
+        internal class SwitchWriter : TextWriter {
+            public SwitchWriter()
+                : base(CultureInfo.CurrentCulture) {
+            }
+
+            public override Encoding Encoding {
+                get {
+                    return InnerWriter.Encoding;
+                }
+            }
+
+            public override IFormatProvider FormatProvider {
+                get {
+                    return InnerWriter.FormatProvider;
+                }
+            }
+
+            internal TextWriter InnerWriter {
+                get;
+                set;
+            }
+
+            public override string NewLine {
+                get {
+                    return InnerWriter.NewLine;
+                }
+                set {
+                    InnerWriter.NewLine = value;
+                }
+            }
+
+            public override void Close() {
+                InnerWriter.Close();
+            }
+
+            public override void Flush() {
+                InnerWriter.Flush();
+            }
+
+            public IDisposable Scope(TextWriter writer) {
+                WriterScope scope = new WriterScope(this, InnerWriter);
+
+                try {
+                    if (writer != this) {
+                        InnerWriter = writer;
+                    }
+
+                    return scope;
+                }
+                catch {
+                    scope.Dispose();
+                    throw;
+                }
+            }
+
+            public override void Write(bool value) {
+                InnerWriter.Write(value);
+            }
+
+            public override void Write(char value) {
+                InnerWriter.Write(value);
+            }
+
+            public override void Write(char[] buffer) {
+                InnerWriter.Write(buffer);
+            }
+
+            public override void Write(char[] buffer, int index, int count) {
+                InnerWriter.Write(buffer, index, count);
+            }
+
+            public override void Write(decimal value) {
+                InnerWriter.Write(value);
+            }
+
+            public override void Write(double value) {
+                InnerWriter.Write(value);
+            }
+
+            public override void Write(float value) {
+                InnerWriter.Write(value);
+            }
+
+            public override void Write(int value) {
+                InnerWriter.Write(value);
+            }
+
+            public override void Write(long value) {
+                InnerWriter.Write(value);
+            }
+
+            public override void Write(object value) {
+                InnerWriter.Write(value);
+            }
+
+            public override void Write(string format, object arg0) {
+                InnerWriter.Write(format, arg0);
+            }
+
+            public override void Write(string format, object arg0, object arg1) {
+                InnerWriter.Write(format, arg0, arg1);
+            }
+
+            public override void Write(string format, object arg0, object arg1, object arg2) {
+                InnerWriter.Write(format, arg0, arg1, arg2);
+            }
+
+            public override void Write(string format, params object[] arg) {
+                InnerWriter.Write(format, arg);
+            }
+
+            public override void Write(string value) {
+                InnerWriter.Write(value);
+            }
+
+            public override void Write(uint value) {
+                InnerWriter.Write(value);
+            }
+
+            public override void Write(ulong value) {
+                InnerWriter.Write(value);
+            }
+
+            public override void WriteLine() {
+                InnerWriter.WriteLine();
+            }
+
+            public override void WriteLine(bool value) {
+                InnerWriter.WriteLine(value);
+            }
+
+            public override void WriteLine(char value) {
+                InnerWriter.WriteLine(value);
+            }
+
+            public override void WriteLine(char[] buffer) {
+                InnerWriter.WriteLine(buffer);
+            }
+
+            public override void WriteLine(char[] buffer, int index, int count) {
+                InnerWriter.WriteLine(buffer, index, count);
+            }
+
+            public override void WriteLine(decimal value) {
+                InnerWriter.WriteLine(value);
+            }
+
+            public override void WriteLine(double value) {
+                InnerWriter.WriteLine(value);
+            }
+
+            public override void WriteLine(float value) {
+                InnerWriter.WriteLine(value);
+            }
+
+            public override void WriteLine(int value) {
+                InnerWriter.WriteLine(value);
+            }
+
+            public override void WriteLine(long value) {
+                InnerWriter.WriteLine(value);
+            }
+
+            public override void WriteLine(object value) {
+                InnerWriter.WriteLine(value);
+            }
+
+            public override void WriteLine(string format, object arg0) {
+                InnerWriter.WriteLine(format, arg0);
+            }
+
+            public override void WriteLine(string format, object arg0, object arg1) {
+                InnerWriter.WriteLine(format, arg0, arg1);
+            }
+
+            public override void WriteLine(string format, object arg0, object arg1, object arg2) {
+                InnerWriter.WriteLine(format, arg0, arg1, arg2);
+            }
+
+            public override void WriteLine(string format, params object[] arg) {
+                InnerWriter.WriteLine(format, arg);
+            }
+
+            public override void WriteLine(string value) {
+                InnerWriter.WriteLine(value);
+            }
+
+            public override void WriteLine(uint value) {
+                InnerWriter.WriteLine(value);
+            }
+
+            public override void WriteLine(ulong value) {
+                InnerWriter.WriteLine(value);
+            }
+
+            private sealed class WriterScope : IDisposable {
+                private SwitchWriter _switchWriter;
+                private TextWriter _writerToRestore;
+
+                public WriterScope(SwitchWriter switchWriter, TextWriter writerToRestore) {
+                    _switchWriter = switchWriter;
+                    _writerToRestore = writerToRestore;
+                }
+
+                public void Dispose() {
+                    _switchWriter.InnerWriter = _writerToRestore;
+                }
+            }
+
+        }
+
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ViewPageControlBuilder.cs b/mcs/class/System.Web.Mvc3/Mvc/ViewPageControlBuilder.cs
new file mode 100644 (file)
index 0000000..1fab076
--- /dev/null
@@ -0,0 +1,17 @@
+namespace System.Web.Mvc {
+    using System.CodeDom;
+    using System.Web.UI;
+
+    internal sealed class ViewPageControlBuilder : FileLevelPageControlBuilder, IMvcControlBuilder {
+        public string Inherits {
+            get;
+            set;
+        }
+
+        public override void ProcessGeneratedCode(CodeCompileUnit codeCompileUnit, CodeTypeDeclaration baseType, CodeTypeDeclaration derivedType, CodeMemberMethod buildMethod, CodeMemberMethod dataBindingMethod) {
+            if (!String.IsNullOrWhiteSpace(Inherits)) {
+                derivedType.BaseTypes[0] = new CodeTypeReference(Inherits);
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ViewPage`1.cs b/mcs/class/System.Web.Mvc3/Mvc/ViewPage`1.cs
new file mode 100644 (file)
index 0000000..dbcd562
--- /dev/null
@@ -0,0 +1,50 @@
+namespace System.Web.Mvc {
+    using System.Diagnostics.CodeAnalysis;
+
+    public class ViewPage<TModel> : ViewPage {
+
+        private ViewDataDictionary<TModel> _viewData;
+
+        public new AjaxHelper<TModel> Ajax {
+            get;
+            set;
+        }
+
+        public new HtmlHelper<TModel> Html {
+            get;
+            set;
+        }
+
+        public new TModel Model {
+            get {
+                return ViewData.Model;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
+        public new ViewDataDictionary<TModel> ViewData {
+            get {
+                if (_viewData == null) {
+                    SetViewData(new ViewDataDictionary<TModel>());
+                }
+                return _viewData;
+            }
+            set {
+                SetViewData(value);
+            }
+        }
+
+        public override void InitHelpers() {
+            base.InitHelpers();
+
+            Ajax = new AjaxHelper<TModel>(ViewContext, this);
+            Html = new HtmlHelper<TModel>(ViewContext, this);
+        }
+
+        protected override void SetViewData(ViewDataDictionary viewData) {
+            _viewData = new ViewDataDictionary<TModel>(viewData);
+
+            base.SetViewData(_viewData);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ViewResult.cs b/mcs/class/System.Web.Mvc3/Mvc/ViewResult.cs
new file mode 100644 (file)
index 0000000..9a464ea
--- /dev/null
@@ -0,0 +1,35 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Globalization;
+    using System.Text;
+    using System.Web.Mvc.Resources;
+
+    public class ViewResult : ViewResultBase {
+        private string _masterName;
+
+        public string MasterName {
+            get {
+                return _masterName ?? String.Empty;
+            }
+            set {
+                _masterName = value;
+            }
+        }
+
+        protected override ViewEngineResult FindView(ControllerContext context) {
+            ViewEngineResult result = ViewEngineCollection.FindView(context, ViewName, MasterName);
+            if (result.View != null) {
+                return result;
+            }
+
+            // we need to generate an exception containing all the locations we searched
+            StringBuilder locationsText = new StringBuilder();
+            foreach (string location in result.SearchedLocations) {
+                locationsText.AppendLine();
+                locationsText.Append(location);
+            }
+            throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
+                MvcResources.Common_ViewNotFound, ViewName, locationsText));
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ViewResultBase.cs b/mcs/class/System.Web.Mvc3/Mvc/ViewResultBase.cs
new file mode 100644 (file)
index 0000000..627bca4
--- /dev/null
@@ -0,0 +1,104 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.IO;
+
+    public abstract class ViewResultBase : ActionResult {
+        private DynamicViewDataDictionary _dynamicViewData;
+        private TempDataDictionary _tempData;
+        private ViewDataDictionary _viewData;
+        private ViewEngineCollection _viewEngineCollection;
+        private string _viewName;
+
+        public object Model {
+            get {
+                return ViewData.Model;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "This entire type is meant to be mutable.")]
+        public TempDataDictionary TempData {
+            get {
+                if (_tempData == null) {
+                    _tempData = new TempDataDictionary();
+                }
+                return _tempData;
+            }
+            set {
+                _tempData = value;
+            }
+        }
+
+        public IView View {
+            get;
+            set;
+        }
+
+        public dynamic ViewBag {
+            get {
+                if (_dynamicViewData == null) {
+                    _dynamicViewData = new DynamicViewDataDictionary(() => ViewData);
+                }
+                return _dynamicViewData;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "This entire type is meant to be mutable.")]
+        public ViewDataDictionary ViewData {
+            get {
+                if (_viewData == null) {
+                    _viewData = new ViewDataDictionary();
+                }
+                return _viewData;
+            }
+            set {
+                _viewData = value;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "This entire type is meant to be mutable.")]
+        public ViewEngineCollection ViewEngineCollection {
+            get {
+                return _viewEngineCollection ?? ViewEngines.Engines;
+            }
+            set {
+                _viewEngineCollection = value;
+            }
+        }
+
+        public string ViewName {
+            get {
+                return _viewName ?? String.Empty;
+            }
+            set {
+                _viewName = value;
+            }
+        }
+
+        public override void ExecuteResult(ControllerContext context) {
+            if (context == null) {
+                throw new ArgumentNullException("context");
+            }
+            if (String.IsNullOrEmpty(ViewName)) {
+                ViewName = context.RouteData.GetRequiredString("action");
+            }
+
+            ViewEngineResult result = null;
+
+            if (View == null) {
+                result = FindView(context);
+                View = result.View;
+            }
+
+            TextWriter writer = context.HttpContext.Response.Output;
+            ViewContext viewContext = new ViewContext(context, View, ViewData, TempData, writer);
+            View.Render(viewContext, writer);
+
+            if (result != null) {
+                result.ViewEngine.ReleaseView(context, View);
+            }
+        }
+
+        protected abstract ViewEngineResult FindView(ControllerContext context);
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ViewStartPage.cs b/mcs/class/System.Web.Mvc3/Mvc/ViewStartPage.cs
new file mode 100644 (file)
index 0000000..a1f79fc
--- /dev/null
@@ -0,0 +1,40 @@
+namespace System.Web.Mvc {
+    using System.Web.Mvc.Resources;
+    using System.Web.WebPages;
+
+    public abstract class ViewStartPage : StartPage, IViewStartPageChild {
+        private IViewStartPageChild _viewStartPageChild;
+
+        public HtmlHelper<object> Html {
+            get {
+                return ViewStartPageChild.Html;
+            }
+        }
+
+        public UrlHelper Url {
+            get {
+                return ViewStartPageChild.Url;
+            }
+        }
+
+        public ViewContext ViewContext {
+            get {
+                return ViewStartPageChild.ViewContext;
+            }
+        }
+
+        internal IViewStartPageChild ViewStartPageChild {
+            get {
+                if (_viewStartPageChild == null) {
+                    IViewStartPageChild child = base.ChildPage as IViewStartPageChild;
+                    if (child == null) {
+                        throw new InvalidOperationException(MvcResources.ViewStartPage_RequiresMvcRazorView);
+                    }
+                    _viewStartPageChild = child;
+                }
+
+                return _viewStartPageChild;
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ViewTemplateUserControl.cs b/mcs/class/System.Web.Mvc3/Mvc/ViewTemplateUserControl.cs
new file mode 100644 (file)
index 0000000..e6c33cb
--- /dev/null
@@ -0,0 +1,3 @@
+namespace System.Web.Mvc {
+    public class ViewTemplateUserControl : ViewTemplateUserControl<object> { }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ViewTemplateUserControl`1.cs b/mcs/class/System.Web.Mvc3/Mvc/ViewTemplateUserControl`1.cs
new file mode 100644 (file)
index 0000000..f17b0ae
--- /dev/null
@@ -0,0 +1,7 @@
+namespace System.Web.Mvc {
+    public class ViewTemplateUserControl<TModel> : ViewUserControl<TModel> {
+        protected string FormattedModelValue {
+            get { return ViewData.TemplateInfo.FormattedModelValue.ToString(); }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ViewType.cs b/mcs/class/System.Web.Mvc3/Mvc/ViewType.cs
new file mode 100644 (file)
index 0000000..9bdcf54
--- /dev/null
@@ -0,0 +1,20 @@
+namespace System.Web.Mvc {
+    using System.ComponentModel;
+    using System.Web.UI;
+
+    [ControlBuilder(typeof(ViewTypeControlBuilder))]
+    [NonVisualControl]
+    public class ViewType : Control {
+        private string _typeName;
+
+        [DefaultValue("")]
+        public string TypeName {
+            get {
+                return _typeName ?? String.Empty;
+            }
+            set {
+                _typeName = value;
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ViewTypeControlBuilder.cs b/mcs/class/System.Web.Mvc3/Mvc/ViewTypeControlBuilder.cs
new file mode 100644 (file)
index 0000000..50080dd
--- /dev/null
@@ -0,0 +1,27 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.CodeDom;
+    using System.Collections;
+    using System.Web.UI;
+
+    internal sealed class ViewTypeControlBuilder : ControlBuilder {
+        private string _typeName;
+
+        public override void Init(TemplateParser parser, ControlBuilder parentBuilder, Type type, string tagName, string id, IDictionary attribs) {
+            base.Init(parser, parentBuilder, type, tagName, id, attribs);
+
+            _typeName = (string)attribs["typename"];
+        }
+
+        public override void ProcessGeneratedCode(
+            CodeCompileUnit codeCompileUnit,
+            CodeTypeDeclaration baseType,
+            CodeTypeDeclaration derivedType,
+            CodeMemberMethod buildMethod,
+            CodeMemberMethod dataBindingMethod) {
+
+            // Override the view's base type with the explicit base type
+            derivedType.BaseTypes[0] = new CodeTypeReference(_typeName);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ViewTypeParserFilter.cs b/mcs/class/System.Web.Mvc3/Mvc/ViewTypeParserFilter.cs
new file mode 100644 (file)
index 0000000..2357352
--- /dev/null
@@ -0,0 +1,102 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Web.UI;
+
+    internal class ViewTypeParserFilter : PageParserFilter {
+
+        private static Dictionary<string, Type> _directiveBaseTypeMappings = new Dictionary<string, Type> {
+            { "page",    typeof(ViewPage)        },
+            { "control", typeof(ViewUserControl) },
+            { "master",  typeof(ViewMasterPage)  },
+        };
+
+        private string _inherits;
+
+        [SuppressMessage("Microsoft.Security", "CA2141:TransparentMethodsMustNotSatisfyLinkDemandsFxCopRule", Justification = "System.Web.Mvc is SecurityTransparent and requires medium trust to run, so this downstream link demand is fine")]
+        public ViewTypeParserFilter() {
+        }
+
+        [SuppressMessage("Microsoft.Security", "CA2141:TransparentMethodsMustNotSatisfyLinkDemandsFxCopRule", Justification = "System.Web.Mvc is SecurityTransparent and requires medium trust to run, so this downstream link demand is fine")]
+        public override void PreprocessDirective(string directiveName, IDictionary attributes) {
+            base.PreprocessDirective(directiveName, attributes);
+
+            Type baseType;
+            if (_directiveBaseTypeMappings.TryGetValue(directiveName, out baseType)) {
+                string inheritsAttribute = attributes["inherits"] as string;
+
+                // Since the ASP.NET page parser doesn't understand native generic syntax, we
+                // need to swap out whatever the user provided with the default base type for
+                // the given directive (page vs. control vs. master). We stash the old value
+                // and swap it back in inside the control builder. Our "is this generic?"
+                // check here really only works for C# and VB.NET, since we're checking for
+                // < or ( in the type name.
+                //
+                // We only change generic directives, because doing so breaks back-compat
+                // for property setters on @Page, @Control, and @Master directives. The user
+                // can work around this breaking behavior by using a non-generic inherits
+                // directive, or by using the CLR syntax for generic type names.
+
+                if (inheritsAttribute != null && inheritsAttribute.IndexOfAny(new[] { '<', '(' }) > 0) {
+                    attributes["inherits"] = baseType.FullName;
+                    _inherits = inheritsAttribute;
+                }
+            }
+        }
+
+        [SuppressMessage("Microsoft.Security", "CA2141:TransparentMethodsMustNotSatisfyLinkDemandsFxCopRule", Justification = "System.Web.Mvc is SecurityTransparent and requires medium trust to run, so this downstream link demand is fine")]
+        public override void ParseComplete(ControlBuilder rootBuilder) {
+            base.ParseComplete(rootBuilder);
+
+            IMvcControlBuilder builder = rootBuilder as IMvcControlBuilder;
+            if (builder != null) {
+                builder.Inherits = _inherits;
+            }
+        }
+
+        // Everything else in this class is unrelated to our 'inherits' handling.
+        // Since PageParserFilter blocks everything by default, we need to unblock it
+
+        public override bool AllowCode {
+            get {
+                return true;
+            }
+        }
+
+        public override bool AllowBaseType(Type baseType) {
+            return true;
+        }
+
+        public override bool AllowControl(Type controlType, ControlBuilder builder) {
+            return true;
+        }
+
+        public override bool AllowVirtualReference(string referenceVirtualPath, VirtualReferenceType referenceType) {
+            return true;
+        }
+
+        public override bool AllowServerSideInclude(string includeVirtualPath) {
+            return true;
+        }
+
+        public override int NumberOfControlsAllowed {
+            get {
+                return -1;
+            }
+        }
+
+        public override int NumberOfDirectDependenciesAllowed {
+            get {
+                return -1;
+            }
+        }
+
+        public override int TotalNumberOfDependenciesAllowed {
+            get {
+                return -1;
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ViewUserControl.cs b/mcs/class/System.Web.Mvc3/Mvc/ViewUserControl.cs
new file mode 100644 (file)
index 0000000..0bc59c5
--- /dev/null
@@ -0,0 +1,195 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.ComponentModel;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.IO;
+    using System.Web.Mvc.Resources;
+    using System.Web.UI;
+
+    [FileLevelControlBuilder(typeof(ViewUserControlControlBuilder))]
+    public class ViewUserControl : UserControl, IViewDataContainer {
+        private AjaxHelper<object> _ajaxHelper;
+        private DynamicViewDataDictionary _dynamicViewData;
+        private HtmlHelper<object> _htmlHelper;
+        private ViewContext _viewContext;
+        private ViewDataDictionary _viewData;
+        private string _viewDataKey;
+
+        public AjaxHelper<object> Ajax {
+            get {
+                if (_ajaxHelper == null) {
+                    _ajaxHelper = new AjaxHelper<object>(ViewContext, this);
+                }
+                return _ajaxHelper;
+            }
+        }
+
+        public HtmlHelper<object> Html {
+            get {
+                if (_htmlHelper == null) {
+                    _htmlHelper = new HtmlHelper<object>(ViewContext, this);
+                }
+                return _htmlHelper;
+            }
+        }
+
+        public object Model {
+            get {
+                return ViewData.Model;
+            }
+        }
+
+        public TempDataDictionary TempData {
+            get {
+                return ViewPage.TempData;
+            }
+        }
+
+        public UrlHelper Url {
+            get {
+                return ViewPage.Url;
+            }
+        }
+
+        public dynamic ViewBag {
+            get {
+                if (_dynamicViewData == null) {
+                    _dynamicViewData = new DynamicViewDataDictionary(() => ViewData);
+                }
+                return _dynamicViewData;
+            }
+        }
+
+        [Browsable(false)]
+        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+        public ViewContext ViewContext {
+            get {
+                return _viewContext ?? ViewPage.ViewContext;
+            }
+            set {
+                _viewContext = value;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "This is the mechanism by which the ViewUserControl gets its ViewDataDictionary object.")]
+        [Browsable(false)]
+        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+        public ViewDataDictionary ViewData {
+            get {
+                EnsureViewData();
+                return _viewData;
+            }
+            set {
+                SetViewData(value);
+            }
+        }
+
+        [DefaultValue("")]
+        public string ViewDataKey {
+            get {
+                return _viewDataKey ?? String.Empty;
+            }
+            set {
+                _viewDataKey = value;
+            }
+        }
+
+        internal ViewPage ViewPage {
+            get {
+                ViewPage viewPage = Page as ViewPage;
+                if (viewPage == null) {
+                    throw new InvalidOperationException(MvcResources.ViewUserControl_RequiresViewPage);
+                }
+                return viewPage;
+            }
+        }
+
+        public HtmlTextWriter Writer {
+            get {
+                return ViewPage.Writer;
+            }
+        }
+
+        protected virtual void SetViewData(ViewDataDictionary viewData) {
+            _viewData = viewData;
+        }
+
+        protected void EnsureViewData() {
+            if (_viewData != null) {
+                return;
+            }
+
+            // Get the ViewData for this ViewUserControl, optionally using the specified ViewDataKey
+            IViewDataContainer vdc = GetViewDataContainer(this);
+            if (vdc == null) {
+                throw new InvalidOperationException(
+                    String.Format(
+                        CultureInfo.CurrentCulture,
+                        MvcResources.ViewUserControl_RequiresViewDataProvider,
+                        AppRelativeVirtualPath));
+            }
+
+            ViewDataDictionary myViewData = vdc.ViewData;
+
+            // If we have a ViewDataKey, try to extract the ViewData from the dictionary, otherwise
+            // return the container's ViewData.
+            if (!String.IsNullOrEmpty(ViewDataKey)) {
+                object target = myViewData.Eval(ViewDataKey);
+                myViewData = target as ViewDataDictionary ?? new ViewDataDictionary(myViewData) { Model = target };
+            }
+
+            SetViewData(myViewData);
+        }
+
+        private static IViewDataContainer GetViewDataContainer(Control control) {
+            // Walk up the control hierarchy until we find someone that implements IViewDataContainer
+            while (control != null) {
+                control = control.Parent;
+                IViewDataContainer vdc = control as IViewDataContainer;
+                if (vdc != null) {
+                    return vdc;
+                }
+            }
+            return null;
+        }
+
+        public virtual void RenderView(ViewContext viewContext) {
+            using (ViewUserControlContainerPage containerPage = new ViewUserControlContainerPage(this)) {
+                RenderViewAndRestoreContentType(containerPage, viewContext);
+            }
+        }
+
+        internal static void RenderViewAndRestoreContentType(ViewPage containerPage, ViewContext viewContext) {
+            // We need to restore the Content-Type since Page.SetIntrinsics() will reset it. It's not possible
+            // to work around the call to SetIntrinsics() since the control's render method requires the
+            // containing page's Response property to be non-null, and SetIntrinsics() is the only way to set
+            // this.
+            string savedContentType = viewContext.HttpContext.Response.ContentType;
+            containerPage.RenderView(viewContext);
+            viewContext.HttpContext.Response.ContentType = savedContentType;
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "textWriter", Justification = "This method existed in MVC 1.0 and has been deprecated.")]
+        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "This method existed in MVC 1.0 and has been deprecated.")]
+        [Obsolete("The TextWriter is now provided by the ViewContext object passed to the RenderView method.", true /* error */)]
+        public void SetTextWriter(TextWriter textWriter) {
+            // this is now a no-op
+        }
+
+        private sealed class ViewUserControlContainerPage : ViewPage {
+            private readonly ViewUserControl _userControl;
+
+            public ViewUserControlContainerPage(ViewUserControl userControl) {
+                _userControl = userControl;
+            }
+
+            public override void ProcessRequest(HttpContext context) {
+                _userControl.ID = ViewPage.NextId();
+                Controls.Add(_userControl);
+
+                base.ProcessRequest(context);
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ViewUserControlControlBuilder.cs b/mcs/class/System.Web.Mvc3/Mvc/ViewUserControlControlBuilder.cs
new file mode 100644 (file)
index 0000000..a608561
--- /dev/null
@@ -0,0 +1,17 @@
+namespace System.Web.Mvc {
+    using System.CodeDom;
+    using System.Web.UI;
+
+    internal sealed class ViewUserControlControlBuilder : FileLevelUserControlBuilder, IMvcControlBuilder {
+        public string Inherits {
+            get;
+            set;
+        }
+
+        public override void ProcessGeneratedCode(CodeCompileUnit codeCompileUnit, CodeTypeDeclaration baseType, CodeTypeDeclaration derivedType, CodeMemberMethod buildMethod, CodeMemberMethod dataBindingMethod) {
+            if (!String.IsNullOrWhiteSpace(Inherits)) {
+                derivedType.BaseTypes[0] = new CodeTypeReference(Inherits);
+            }
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/ViewUserControl`1.cs b/mcs/class/System.Web.Mvc3/Mvc/ViewUserControl`1.cs
new file mode 100644 (file)
index 0000000..ee81f34
--- /dev/null
@@ -0,0 +1,50 @@
+namespace System.Web.Mvc {
+    using System.Diagnostics.CodeAnalysis;
+
+    public class ViewUserControl<TModel> : ViewUserControl {
+        private AjaxHelper<TModel> _ajaxHelper;
+        private HtmlHelper<TModel> _htmlHelper;
+        private ViewDataDictionary<TModel> _viewData;
+
+        public new AjaxHelper<TModel> Ajax {
+            get {
+                if (_ajaxHelper == null) {
+                    _ajaxHelper = new AjaxHelper<TModel>(ViewContext, this);
+                }
+                return _ajaxHelper;
+            }
+        }
+
+        public new HtmlHelper<TModel> Html {
+            get {
+                if (_htmlHelper == null) {
+                    _htmlHelper = new HtmlHelper<TModel>(ViewContext, this);
+                }
+                return _htmlHelper;
+            }
+        }
+
+        public new TModel Model {
+            get {
+                return ViewData.Model;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
+        public new ViewDataDictionary<TModel> ViewData {
+            get {
+                EnsureViewData();
+                return _viewData;
+            }
+            set {
+                SetViewData(value);
+            }
+        }
+
+        protected override void SetViewData(ViewDataDictionary viewData) {
+            _viewData = new ViewDataDictionary<TModel>(viewData);
+
+            base.SetViewData(_viewData);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/VirtualPathProviderViewEngine.cs b/mcs/class/System.Web.Mvc3/Mvc/VirtualPathProviderViewEngine.cs
new file mode 100644 (file)
index 0000000..b989aaf
--- /dev/null
@@ -0,0 +1,273 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Linq;
+    using System.Web;
+    using System.Web.Hosting;
+    using System.Web.Mvc.Resources;
+
+    public abstract class VirtualPathProviderViewEngine : IViewEngine {
+        // format is ":ViewCacheEntry:{cacheType}:{prefix}:{name}:{controllerName}:{areaName}:"
+        private const string _cacheKeyFormat = ":ViewCacheEntry:{0}:{1}:{2}:{3}:{4}:";
+        private const string _cacheKeyPrefix_Master = "Master";
+        private const string _cacheKeyPrefix_Partial = "Partial";
+        private const string _cacheKeyPrefix_View = "View";
+        private static readonly string[] _emptyLocations = new string[0];
+
+        private VirtualPathProvider _vpp;
+        internal Func<string, string> GetExtensionThunk = VirtualPathUtility.GetExtension;
+
+        [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
+        public string[] AreaMasterLocationFormats {
+            get;
+            set;
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
+        public string[] AreaPartialViewLocationFormats {
+            get;
+            set;
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
+        public string[] AreaViewLocationFormats {
+            get;
+            set;
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
+        public string[] FileExtensions {
+            get;
+            set;
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
+        public string[] MasterLocationFormats {
+            get;
+            set;
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
+        public string[] PartialViewLocationFormats {
+            get;
+            set;
+        }
+
+        public IViewLocationCache ViewLocationCache {
+            get;
+            set;
+        }
+
+        [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
+        public string[] ViewLocationFormats {
+            get;
+            set;
+        }
+
+        protected VirtualPathProvider VirtualPathProvider {
+            get {
+                if (_vpp == null) {
+                    _vpp = HostingEnvironment.VirtualPathProvider;
+                }
+                return _vpp;
+            }
+            set {
+                _vpp = value;
+            }
+        }
+
+        protected VirtualPathProviderViewEngine() {
+            if (HttpContext.Current == null || HttpContext.Current.IsDebuggingEnabled) {
+                ViewLocationCache = DefaultViewLocationCache.Null;
+            }
+            else {
+                ViewLocationCache = new DefaultViewLocationCache();
+            }
+        }
+
+        private string CreateCacheKey(string prefix, string name, string controllerName, string areaName) {
+            return String.Format(CultureInfo.InvariantCulture, _cacheKeyFormat,
+                GetType().AssemblyQualifiedName, prefix, name, controllerName, areaName);
+        }
+
+        protected abstract IView CreatePartialView(ControllerContext controllerContext, string partialPath);
+
+        protected abstract IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath);
+
+        protected virtual bool FileExists(ControllerContext controllerContext, string virtualPath) {
+            return VirtualPathProvider.FileExists(virtualPath);
+        }
+
+        public virtual ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+            if (String.IsNullOrEmpty(partialViewName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "partialViewName");
+            }
+
+            string[] searched;
+            string controllerName = controllerContext.RouteData.GetRequiredString("controller");
+            string partialPath = GetPath(controllerContext, PartialViewLocationFormats, AreaPartialViewLocationFormats, "PartialViewLocationFormats", partialViewName, controllerName, _cacheKeyPrefix_Partial, useCache, out searched);
+
+            if (String.IsNullOrEmpty(partialPath)) {
+                return new ViewEngineResult(searched);
+            }
+
+            return new ViewEngineResult(CreatePartialView(controllerContext, partialPath), this);
+        }
+
+        public virtual ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache) {
+            if (controllerContext == null) {
+                throw new ArgumentNullException("controllerContext");
+            }
+            if (String.IsNullOrEmpty(viewName)) {
+                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "viewName");
+            }
+
+            string[] viewLocationsSearched;
+            string[] masterLocationsSearched;
+
+            string controllerName = controllerContext.RouteData.GetRequiredString("controller");
+            string viewPath = GetPath(controllerContext, ViewLocationFormats, AreaViewLocationFormats, "ViewLocationFormats", viewName, controllerName, _cacheKeyPrefix_View, useCache, out viewLocationsSearched);
+            string masterPath = GetPath(controllerContext, MasterLocationFormats, AreaMasterLocationFormats, "MasterLocationFormats", masterName, controllerName, _cacheKeyPrefix_Master, useCache, out masterLocationsSearched);
+
+            if (String.IsNullOrEmpty(viewPath) || (String.IsNullOrEmpty(masterPath) && !String.IsNullOrEmpty(masterName))) {
+                return new ViewEngineResult(viewLocationsSearched.Union(masterLocationsSearched));
+            }
+
+            return new ViewEngineResult(CreateView(controllerContext, viewPath, masterPath), this);
+        }
+
+        private string GetPath(ControllerContext controllerContext, string[] locations, string[] areaLocations, string locationsPropertyName, string name, string controllerName, string cacheKeyPrefix, bool useCache, out string[] searchedLocations) {
+            searchedLocations = _emptyLocations;
+
+            if (String.IsNullOrEmpty(name)) {
+                return String.Empty;
+            }
+
+            string areaName = AreaHelpers.GetAreaName(controllerContext.RouteData);
+            bool usingAreas = !String.IsNullOrEmpty(areaName);
+            List<ViewLocation> viewLocations = GetViewLocations(locations, (usingAreas) ? areaLocations : null);
+
+            if (viewLocations.Count == 0) {
+                throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
+                    MvcResources.Common_PropertyCannotBeNullOrEmpty, locationsPropertyName));
+            }
+
+            bool nameRepresentsPath = IsSpecificPath(name);
+            string cacheKey = CreateCacheKey(cacheKeyPrefix, name, (nameRepresentsPath) ? String.Empty : controllerName, areaName);
+
+            if (useCache) {
+                return ViewLocationCache.GetViewLocation(controllerContext.HttpContext, cacheKey);
+            }
+
+            return (nameRepresentsPath) ?
+                GetPathFromSpecificName(controllerContext, name, cacheKey, ref searchedLocations) :
+                GetPathFromGeneralName(controllerContext, viewLocations, name, controllerName, areaName, cacheKey, ref searchedLocations);
+        }
+
+        private string GetPathFromGeneralName(ControllerContext controllerContext, List<ViewLocation> locations, string name, string controllerName, string areaName, string cacheKey, ref string[] searchedLocations) {
+            string result = String.Empty;
+            searchedLocations = new string[locations.Count];
+
+            for (int i = 0; i < locations.Count; i++) {
+                ViewLocation location = locations[i];
+                string virtualPath = location.Format(name, controllerName, areaName);
+
+                if (FileExists(controllerContext, virtualPath)) {
+                    searchedLocations = _emptyLocations;
+                    result = virtualPath;
+                    ViewLocationCache.InsertViewLocation(controllerContext.HttpContext, cacheKey, result);
+                    break;
+                }
+
+                searchedLocations[i] = virtualPath;
+            }
+
+            return result;
+        }
+
+        private string GetPathFromSpecificName(ControllerContext controllerContext, string name, string cacheKey, ref string[] searchedLocations) {
+            string result = name;
+
+            if (!(FilePathIsSupported(name) && FileExists(controllerContext, name))) {
+                result = String.Empty;
+                searchedLocations = new[] { name };
+            }
+
+            ViewLocationCache.InsertViewLocation(controllerContext.HttpContext, cacheKey, result);
+            return result;
+        }
+
+        private bool FilePathIsSupported(string virtualPath) {
+            if (FileExtensions == null) {
+                // legacy behavior for custom ViewEngine that might not set the FileExtensions property
+                return true;
+            }
+            else {
+                // get rid of the '.' because the FileExtensions property expects extensions withouth a dot.
+                string extension = GetExtensionThunk(virtualPath).TrimStart('.');
+                return FileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase);
+            }
+        }
+
+        private static List<ViewLocation> GetViewLocations(string[] viewLocationFormats, string[] areaViewLocationFormats) {
+            List<ViewLocation> allLocations = new List<ViewLocation>();
+
+            if (areaViewLocationFormats != null) {
+                foreach (string areaViewLocationFormat in areaViewLocationFormats) {
+                    allLocations.Add(new AreaAwareViewLocation(areaViewLocationFormat));
+                }
+            }
+
+            if (viewLocationFormats != null) {
+                foreach (string viewLocationFormat in viewLocationFormats) {
+                    allLocations.Add(new ViewLocation(viewLocationFormat));
+                }
+            }
+
+            return allLocations;
+        }
+
+        private static bool IsSpecificPath(string name) {
+            char c = name[0];
+            return (c == '~' || c == '/');
+        }
+
+        public virtual void ReleaseView(ControllerContext controllerContext, IView view) {
+            IDisposable disposable = view as IDisposable;
+            if (disposable != null) {
+                disposable.Dispose();
+            }
+        }
+
+        private class ViewLocation {
+
+            protected string _virtualPathFormatString;
+
+            public ViewLocation(string virtualPathFormatString) {
+                _virtualPathFormatString = virtualPathFormatString;
+            }
+
+            public virtual string Format(string viewName, string controllerName, string areaName) {
+                return String.Format(CultureInfo.InvariantCulture, _virtualPathFormatString, viewName, controllerName);
+            }
+
+        }
+
+        private class AreaAwareViewLocation : ViewLocation {
+
+            public AreaAwareViewLocation(string virtualPathFormatString)
+                : base(virtualPathFormatString) {
+            }
+
+            public override string Format(string viewName, string controllerName, string areaName) {
+                return String.Format(CultureInfo.InvariantCulture, _virtualPathFormatString, viewName, controllerName, areaName);
+            }
+
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/WebFormView.cs b/mcs/class/System.Web.Mvc3/Mvc/WebFormView.cs
new file mode 100644 (file)
index 0000000..a380574
--- /dev/null
@@ -0,0 +1,66 @@
+namespace System.Web.Mvc {
+    using System;
+    using System.Globalization;
+    using System.IO;
+    using System.Web.Mvc.Resources;
+
+    public class WebFormView : BuildManagerCompiledView {
+
+        public WebFormView(ControllerContext controllerContext, string viewPath)
+            : this(controllerContext, viewPath, null, null) {
+        }
+
+        public WebFormView(ControllerContext controllerContext, string viewPath, string masterPath)
+            : this(controllerContext, viewPath, masterPath, null) {
+        }
+
+        public WebFormView(ControllerContext controllerContext, string viewPath, string masterPath, IViewPageActivator viewPageActivator)
+            : base(controllerContext, viewPath, viewPageActivator) {
+            MasterPath = masterPath ?? String.Empty;
+        }
+
+        public string MasterPath {
+            get;
+            private set;
+        }
+
+        protected override void RenderView(ViewContext viewContext, TextWriter writer, object instance) {
+
+            ViewPage viewPage = instance as ViewPage;
+            if (viewPage != null) {
+                RenderViewPage(viewContext, viewPage);
+                return;
+            }
+
+            ViewUserControl viewUserControl = instance as ViewUserControl;
+            if (viewUserControl != null) {
+                RenderViewUserControl(viewContext, viewUserControl);
+                return;
+            }
+
+            throw new InvalidOperationException(
+                String.Format(
+                    CultureInfo.CurrentCulture,
+                    MvcResources.WebFormViewEngine_WrongViewBase,
+                    ViewPath));
+        }
+
+        private void RenderViewPage(ViewContext context, ViewPage page) {
+            if (!String.IsNullOrEmpty(MasterPath)) {
+                page.MasterLocation = MasterPath;
+            }
+
+            page.ViewData = context.ViewData;
+            page.RenderView(context);
+        }
+
+        private void RenderViewUserControl(ViewContext context, ViewUserControl control) {
+            if (!String.IsNullOrEmpty(MasterPath)) {
+                throw new InvalidOperationException(MvcResources.WebFormViewEngine_UserControlCannotHaveMaster);
+            }
+
+            control.ViewData = context.ViewData;
+            control.RenderView(context);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/WebFormViewEngine.cs b/mcs/class/System.Web.Mvc3/Mvc/WebFormViewEngine.cs
new file mode 100644 (file)
index 0000000..1b115ec
--- /dev/null
@@ -0,0 +1,52 @@
+namespace System.Web.Mvc {
+    public class WebFormViewEngine : BuildManagerViewEngine {
+
+        public WebFormViewEngine()
+            : this(null) {
+        }
+
+        public WebFormViewEngine(IViewPageActivator viewPageActivator)
+            :base(viewPageActivator){
+            MasterLocationFormats = new[] {
+                "~/Views/{1}/{0}.master",
+                "~/Views/Shared/{0}.master"
+            };
+
+            AreaMasterLocationFormats = new[] {
+                "~/Areas/{2}/Views/{1}/{0}.master",
+                "~/Areas/{2}/Views/Shared/{0}.master",
+            };
+
+            ViewLocationFormats = new[] {
+                "~/Views/{1}/{0}.aspx",
+                "~/Views/{1}/{0}.ascx",
+                "~/Views/Shared/{0}.aspx",
+                "~/Views/Shared/{0}.ascx"
+            };
+
+            AreaViewLocationFormats = new[] {
+                "~/Areas/{2}/Views/{1}/{0}.aspx",
+                "~/Areas/{2}/Views/{1}/{0}.ascx",
+                "~/Areas/{2}/Views/Shared/{0}.aspx",
+                "~/Areas/{2}/Views/Shared/{0}.ascx",
+            };
+
+            PartialViewLocationFormats = ViewLocationFormats;
+            AreaPartialViewLocationFormats = AreaViewLocationFormats;
+
+            FileExtensions = new[] {
+                "aspx",
+                "ascx",
+                "master",
+            };
+        }
+
+        protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath) {
+            return new WebFormView(controllerContext, partialPath, null, ViewPageActivator);
+        }
+
+        protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath) {
+            return new WebFormView(controllerContext, viewPath, masterPath, ViewPageActivator);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/WebViewPage.cs b/mcs/class/System.Web.Mvc3/Mvc/WebViewPage.cs
new file mode 100644 (file)
index 0000000..0ed9d30
--- /dev/null
@@ -0,0 +1,116 @@
+namespace System.Web.Mvc {
+    using System.Diagnostics.CodeAnalysis;
+    using System.Globalization;
+    using System.Web.Mvc.Resources;
+    using System.Web.WebPages;
+
+    public abstract class WebViewPage : WebPageBase, IViewDataContainer, IViewStartPageChild {
+
+        private ViewDataDictionary _viewData;
+        private DynamicViewDataDictionary _dynamicViewData;
+        private HttpContextBase _context;
+
+        public AjaxHelper<object> Ajax {
+            get;
+            set;
+        }
+
+        public override HttpContextBase Context {
+            // REVIEW why are we forced to override this?
+            get {
+                return _context ?? ViewContext.HttpContext;
+            }
+            set {
+                _context = value;
+            }
+        }
+
+        public HtmlHelper<object> Html {
+            get;
+            set;
+        }
+
+        public object Model {
+            get {
+                return ViewData.Model;
+            }
+        }
+
+        internal string OverridenLayoutPath { get; set; }
+
+        public TempDataDictionary TempData {
+            get {
+                return ViewContext.TempData;
+            }
+        }
+
+        public UrlHelper Url {
+            get;
+            set;
+        }
+
+        public dynamic ViewBag {
+            get {
+                if (_dynamicViewData == null) {
+                    _dynamicViewData = new DynamicViewDataDictionary(() => ViewData);
+                }
+                return _dynamicViewData;
+            }
+        }
+
+        public ViewContext ViewContext {
+            get;
+            set;
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "This is the mechanism by which the ViewPage gets its ViewDataDictionary object.")]
+        public ViewDataDictionary ViewData {
+            get {
+                if (_viewData == null) {
+                    SetViewData(new ViewDataDictionary());
+                }
+                return _viewData;
+            }
+            set {
+                SetViewData(value);
+            }
+        }
+
+        protected override void ConfigurePage(WebPageBase parentPage) {
+            var baseViewPage = parentPage as WebViewPage;
+            if (baseViewPage == null) {
+                // TODO : review if this check is even necessary.
+                // When this method is called by the framework parentPage should already be an instance of WebViewPage
+                // Need to review what happens if this method gets called in Plan9 pointing at an MVC view
+                throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, MvcResources.CshtmlView_WrongViewBase, parentPage.VirtualPath));
+            }
+
+            // Set ViewContext and ViewData here so that the layout page inherits ViewData from the main page
+            ViewContext = baseViewPage.ViewContext;
+            ViewData = baseViewPage.ViewData;
+            InitHelpers();
+        }
+
+        public override void ExecutePageHierarchy() {
+            // Change the Writer so that things like Html.BeginForm work correctly
+            ViewContext.Writer = Output;
+
+            base.ExecutePageHierarchy();
+
+            // Overwrite LayoutPage so that returning a view with a custom master page works.
+            if (!String.IsNullOrEmpty(OverridenLayoutPath)) {
+                Layout = OverridenLayoutPath;
+            }
+        }
+
+        public virtual void InitHelpers() {
+            Ajax = new AjaxHelper<object>(ViewContext, this);
+            Html = new HtmlHelper<object>(ViewContext, this);
+            Url = new UrlHelper(ViewContext.RequestContext);
+        }
+
+        protected virtual void SetViewData(ViewDataDictionary viewData) {
+            _viewData = viewData;
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Mvc/WebViewPage`1.cs b/mcs/class/System.Web.Mvc3/Mvc/WebViewPage`1.cs
new file mode 100644 (file)
index 0000000..873b47b
--- /dev/null
@@ -0,0 +1,49 @@
+namespace System.Web.Mvc {
+    using System.Diagnostics.CodeAnalysis;
+
+    public abstract class WebViewPage<TModel> : WebViewPage {
+        private ViewDataDictionary<TModel> _viewData;
+
+        public new AjaxHelper<TModel> Ajax {
+            get;
+            set;
+        }
+
+        public new HtmlHelper<TModel> Html {
+            get;
+            set;
+        }
+
+        public new TModel Model {
+            get {
+                return ViewData.Model;
+            }
+        }
+
+        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "This is the mechanism by which the ViewPage gets its ViewDataDictionary object.")]
+        public new ViewDataDictionary<TModel> ViewData {
+            get {
+                if (_viewData == null) {
+                    SetViewData(new ViewDataDictionary<TModel>());
+                }
+                return _viewData;
+            }
+            set {
+                SetViewData(value);
+            }
+        }
+
+        public override void InitHelpers() {
+            base.InitHelpers();
+
+            Ajax = new AjaxHelper<TModel>(ViewContext, this);
+            Html = new HtmlHelper<TModel>(ViewContext, this);
+        }
+
+        protected override void SetViewData(ViewDataDictionary viewData) {
+            _viewData = new ViewDataDictionary<TModel>(viewData);
+
+            base.SetViewData(_viewData);
+        }
+    }
+}
diff --git a/mcs/class/System.Web.Mvc3/Properties/AssemblyInfo.cs b/mcs/class/System.Web.Mvc3/Properties/AssemblyInfo.cs
new file mode 100644 (file)
index 0000000..6875085
--- /dev/null
@@ -0,0 +1,27 @@
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Security;
+using System.Web;
+
+[assembly: AssemblyTitle("System.Web.Mvc.dll")]
+[assembly: AssemblyDescription("System.Web.Mvc.dll")]
+[assembly: ComVisible(false)]
+[assembly: Guid("4b5f4208-c6b0-4c37-9a41-63325ffa52ad")]
+#if !CODE_COVERAGE
+[assembly: AllowPartiallyTrustedCallers]
+[assembly: SecurityTransparent]
+#endif
+[assembly: CLSCompliant(true)]
+#if !MONO
+[assembly: InternalsVisibleTo("System.Web.Mvc.Test")]
+#endif
+
+[assembly: PreApplicationStartMethod(typeof(System.Web.Mvc.PreApplicationStartCode), "Start")]
+
+[assembly: TypeForwardedTo(typeof(System.Web.Mvc.TagBuilder))]
+[assembly: TypeForwardedTo(typeof(System.Web.Mvc.TagRenderMode))]
+[assembly: TypeForwardedTo(typeof(System.Web.Mvc.HttpAntiForgeryException))]
+
diff --git a/mcs/class/System.Web.Mvc3/System.Web.Mvc.csproj b/mcs/class/System.Web.Mvc3/System.Web.Mvc.csproj
new file mode 100644 (file)
index 0000000..c134594
--- /dev/null
@@ -0,0 +1,471 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <PropertyGroup>\r
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>\r
+    <ProductVersion>9.0.30729</ProductVersion>\r
+    <SchemaVersion>2.0</SchemaVersion>\r
+    <ProjectGuid>{3D3FFD8A-624D-4E9B-954B-E1C105507975}</ProjectGuid>\r
+    <OutputType>Library</OutputType>\r
+    <AppDesignerFolder>Properties</AppDesignerFolder>\r
+    <RootNamespace>System.Web</RootNamespace>\r
+    <AssemblyName>System.Web.Mvc</AssemblyName>\r
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>\r
+    <FileAlignment>512</FileAlignment>\r
+    <ErrorReport>prompt</ErrorReport>\r
+    <WarningLevel>4</WarningLevel>\r
+    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>\r
+    <BaseAddress>1609891840</BaseAddress>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">\r
+    <DebugSymbols>true</DebugSymbols>\r
+    <DebugType>full</DebugType>\r
+    <Optimize>false</Optimize>\r
+    <OutputPath>..\..\bin\Debug\</OutputPath>\r
+    <DefineConstants>DEBUG;TRACE</DefineConstants>\r
+    <CodeAnalysisRuleSet>..\FxCopRules.ruleset</CodeAnalysisRuleSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">\r
+    <DebugType>pdbonly</DebugType>\r
+    <Optimize>true</Optimize>\r
+    <OutputPath>..\..\bin\Release\</OutputPath>\r
+    <DefineConstants>TRACE</DefineConstants>\r
+    <CodeAnalysisRuleSet>..\FxCopRules.ruleset</CodeAnalysisRuleSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'FxCop|AnyCPU'">\r
+    <DebugType>pdbonly</DebugType>\r
+    <Optimize>true</Optimize>\r
+    <OutputPath>..\..\bin\FxCop\</OutputPath>\r
+    <DefineConstants>TRACE;CODE_ANALYSIS</DefineConstants>\r
+    <CodeAnalysisRuleSet>..\FxCopRules.ruleset</CodeAnalysisRuleSet>\r
+    <RunCodeAnalysis>true</RunCodeAnalysis>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'CodeCoverage|AnyCPU'">\r
+    <DebugSymbols>true</DebugSymbols>\r
+    <OutputPath>..\..\bin\CodeCoverage\</OutputPath>\r
+    <DefineConstants>TRACE;DEBUG;CODE_COVERAGE</DefineConstants>\r
+    <DebugType>full</DebugType>\r
+    <CodeAnalysisRuleSet>..\FxCopRules.ruleset</CodeAnalysisRuleSet>\r
+  </PropertyGroup>\r
+  <ItemGroup>\r
+    <Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">\r
+      <SpecificVersion>False</SpecificVersion>\r
+      <HintPath>..\..\..\webpages\ReferenceAssemblies\Microsoft.Web.Infrastructure.dll</HintPath>\r
+    </Reference>\r
+    <Reference Include="System" />\r
+    <Reference Include="System.ComponentModel.DataAnnotations" />\r
+    <Reference Include="System.configuration" />\r
+    <Reference Include="System.Core" />\r
+    <Reference Include="System.Data.Entity" />\r
+    <Reference Include="System.Data.Linq" />\r
+    <Reference Include="System.Runtime.Caching" />\r
+    <Reference Include="System.Web" />\r
+    <Reference Include="System.Data" />\r
+    <Reference Include="System.Web.Abstractions" />\r
+    <Reference Include="System.Web.Extensions" />\r
+    <Reference Include="System.Web.Routing" />\r
+    <Reference Include="System.Xml" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <Compile Include="..\GlobalAssemblyInfo.cs">\r
+      <Link>Properties\GlobalAssemblyInfo.cs</Link>\r
+    </Compile>\r
+    <Compile Include="Mvc\AdditionalMetaDataAttribute.cs" />\r
+    <Compile Include="Mvc\BuildManagerCompiledView.cs" />\r
+    <Compile Include="Mvc\BuildManagerViewEngine.cs" />\r
+    <Compile Include="Mvc\CompareAttribute.cs" />\r
+    <Compile Include="Mvc\ChildActionValueProvider.cs" />\r
+    <Compile Include="Mvc\ChildActionValueProviderFactory.cs" />\r
+    <Compile Include="Mvc\DataTypeUtil.cs" />\r
+    <Compile Include="Mvc\ReflectedAttributeCache.cs" />\r
+    <Compile Include="Mvc\SessionStateAttribute.cs" />\r
+    <Compile Include="Mvc\AllowHtmlAttribute.cs" />\r
+    <Compile Include="Mvc\UnvalidatedRequestValuesAccessor.cs" />\r
+    <Compile Include="Mvc\UnvalidatedRequestValuesWrapper.cs" />\r
+    <Compile Include="Mvc\IUnvalidatedRequestValues.cs" />\r
+    <Compile Include="Mvc\IUnvalidatedValueProvider.cs" />\r
+    <Compile Include="Mvc\DependencyResolverExtensions.cs" />\r
+    <Compile Include="Mvc\ExpressionUtil\BinaryExpressionFingerprint.cs" />\r
+    <Compile Include="Mvc\ExpressionUtil\CachedExpressionCompiler.cs" />\r
+    <Compile Include="Mvc\ExpressionUtil\ConditionalExpressionFingerprint.cs" />\r
+    <Compile Include="Mvc\ExpressionUtil\ConstantExpressionFingerprint.cs" />\r
+    <Compile Include="Mvc\ExpressionUtil\DefaultExpressionFingerprint.cs" />\r
+    <Compile Include="Mvc\ExpressionUtil\ExpressionFingerprint.cs" />\r
+    <Compile Include="Mvc\ExpressionUtil\ExpressionFingerprintChain.cs" />\r
+    <Compile Include="Mvc\ExpressionUtil\FingerprintingExpressionVisitor.cs" />\r
+    <Compile Include="Mvc\ExpressionUtil\HashCodeCombiner.cs" />\r
+    <Compile Include="Mvc\ExpressionUtil\Hoisted`2.cs" />\r
+    <Compile Include="Mvc\ExpressionUtil\HoistingExpressionVisitor.cs" />\r
+    <Compile Include="Mvc\ExpressionUtil\IndexExpressionFingerprint.cs" />\r
+    <Compile Include="Mvc\ExpressionUtil\LambdaExpressionFingerprint.cs" />\r
+    <Compile Include="Mvc\ExpressionUtil\MemberExpressionFingerprint.cs" />\r
+    <Compile Include="Mvc\ExpressionUtil\MethodCallExpressionFingerprint.cs" />\r
+    <Compile Include="Mvc\ExpressionUtil\ParameterExpressionFingerprint.cs" />\r
+    <Compile Include="Mvc\ExpressionUtil\TypeBinaryExpressionFingerprint.cs" />\r
+    <Compile Include="Mvc\ExpressionUtil\UnaryExpressionFingerprint.cs" />\r
+    <Compile Include="Mvc\IControllerActivator.cs" />\r
+    <Compile Include="Mvc\IModelBinderProvider.cs" />\r
+    <Compile Include="Mvc\IUniquelyIdentifiable.cs" />\r
+    <Compile Include="Mvc\IViewStartPageChild.cs" />\r
+    <Compile Include="Mvc\IResolver.cs" />\r
+    <Compile Include="Mvc\ControllerInstanceFilterProvider.cs" />\r
+    <Compile Include="Mvc\ModelClientValidationEqualToRule.cs" />\r
+    <Compile Include="Mvc\ModelClientValidationRemoteRule.cs" />\r
+    <Compile Include="Mvc\RazorView.cs" />\r
+    <Compile Include="Mvc\RazorViewEngine.cs" />\r
+    <Compile Include="Mvc\DynamicViewDataDictionary.cs" />\r
+    <Compile Include="Mvc\Filter.cs" />\r
+    <Compile Include="Mvc\FilterAttributeFilterProvider.cs" />\r
+    <Compile Include="Mvc\FilterProviderCollection.cs" />\r
+    <Compile Include="Mvc\FilterProviders.cs" />\r
+    <Compile Include="Mvc\FilterScope.cs" />\r
+    <Compile Include="Mvc\GlobalFilterCollection.cs" />\r
+    <Compile Include="Mvc\GlobalFilters.cs" />\r
+    <Compile Include="Mvc\IFilterProvider.cs" />\r
+    <Compile Include="Mvc\IMvcFilter.cs" />\r
+    <Compile Include="Mvc\IViewPageActivator.cs" />\r
+    <Compile Include="Mvc\ModelBinderProviderCollection.cs" />\r
+    <Compile Include="Mvc\ModelBinderProviders.cs" />\r
+    <Compile Include="Mvc\MultiServiceResolver.cs" />\r
+    <Compile Include="Mvc\Razor\ModelSpan.cs" />\r
+    <Compile Include="Mvc\Razor\MvcCSharpRazorCodeParser.cs" />\r
+    <Compile Include="Mvc\Razor\MvcCSharpRazorCodeGenerator.cs" />\r
+    <Compile Include="Mvc\MvcFilter.cs" />\r
+    <Compile Include="Mvc\Razor\MvcVBRazorCodeGenerator.cs" />\r
+    <Compile Include="Mvc\Razor\MvcVBRazorCodeParser.cs" />\r
+    <Compile Include="Mvc\Razor\MvcWebPageRazorHost.cs" />\r
+    <Compile Include="Mvc\MvcWebRazorHostFactory.cs" />\r
+    <Compile Include="Mvc\PreApplicationStartCode.cs" />\r
+    <Compile Include="Mvc\RemoteAttribute.cs" />\r
+    <Compile Include="Mvc\SecurityUtil.cs" />\r
+    <Compile Include="Mvc\SingleServiceResolver.cs" />\r
+    <Compile Include="Mvc\Razor\StartPageLookupDelegate.cs" />\r
+    <Compile Include="Mvc\TagBuilderExtensions.cs" />\r
+    <Compile Include="Mvc\UrlRewriterHelper.cs" />\r
+    <Compile Include="Mvc\ViewStartPage.cs" />\r
+    <Compile Include="Mvc\WebViewPage.cs" />\r
+    <Compile Include="Mvc\WebViewPage`1.cs" />\r
+    <Compile Include="Mvc\HttpNotFoundResult.cs" />\r
+    <Compile Include="Mvc\HttpStatusCodeResult.cs" />\r
+    <Compile Include="Mvc\IMvcControlBuilder.cs" />\r
+    <Compile Include="Mvc\AssociatedMetadataProvider.cs" />\r
+    <Compile Include="Mvc\ActionExecutedContext.cs" />\r
+    <Compile Include="Mvc\ActionExecutingContext.cs" />\r
+    <Compile Include="Mvc\ClientDataTypeModelValidatorProvider.cs" />\r
+    <Compile Include="Mvc\AssociatedValidatorProvider.cs" />\r
+    <Compile Include="Mvc\Async\ActionDescriptorCreator.cs" />\r
+    <Compile Include="Mvc\Async\AsyncActionDescriptor.cs" />\r
+    <Compile Include="Mvc\Async\AsyncActionMethodSelector.cs" />\r
+    <Compile Include="Mvc\Async\AsyncControllerActionInvoker.cs" />\r
+    <Compile Include="Mvc\Async\SynchronousOperationException.cs" />\r
+    <Compile Include="Mvc\Async\AsyncManager.cs" />\r
+    <Compile Include="Mvc\AsyncTimeoutAttribute.cs" />\r
+    <Compile Include="Mvc\Async\BeginInvokeDelegate.cs" />\r
+    <Compile Include="Mvc\Async\AsyncResultWrapper.cs" />\r
+    <Compile Include="Mvc\Async\AsyncVoid.cs" />\r
+    <Compile Include="Mvc\AsyncController.cs" />\r
+    <Compile Include="Mvc\Async\AsyncUtil.cs" />\r
+    <Compile Include="Mvc\Async\IAsyncController.cs" />\r
+    <Compile Include="Mvc\Async\IAsyncActionInvoker.cs" />\r
+    <Compile Include="Mvc\Async\IAsyncManagerContainer.cs" />\r
+    <Compile Include="Mvc\IClientValidatable.cs" />\r
+    <Compile Include="Mvc\IMetadataAware.cs" />\r
+    <Compile Include="Mvc\IDependencyResolver.cs" />\r
+    <Compile Include="Mvc\JsonValueProviderFactory.cs" />\r
+    <Compile Include="Mvc\DependencyResolver.cs" />\r
+    <Compile Include="Mvc\UrlParameter.cs" />\r
+    <Compile Include="Mvc\FormValueProvider.cs" />\r
+    <Compile Include="Mvc\FormValueProviderFactory.cs" />\r
+    <Compile Include="Mvc\HttpFileCollectionValueProvider.cs" />\r
+    <Compile Include="Mvc\HttpFileCollectionValueProviderFactory.cs" />\r
+    <Compile Include="Mvc\QueryStringValueProvider.cs" />\r
+    <Compile Include="Mvc\QueryStringValueProviderFactory.cs" />\r
+    <Compile Include="Mvc\RangeAttributeAdapter.cs" />\r
+    <Compile Include="Mvc\RegularExpressionAttributeAdapter.cs" />\r
+    <Compile Include="Mvc\RequiredAttributeAdapter.cs" />\r
+    <Compile Include="Mvc\RouteDataValueProvider.cs" />\r
+    <Compile Include="Mvc\RouteDataValueProviderFactory.cs" />\r
+    <Compile Include="Mvc\StringLengthAttributeAdapter.cs" />\r
+    <Compile Include="Mvc\TypeCacheUtil.cs" />\r
+    <Compile Include="Mvc\TypeCacheSerializer.cs" />\r
+    <Compile Include="Mvc\Html\DisplayTextExtensions.cs" />\r
+    <Compile Include="Mvc\NoAsyncTimeoutAttribute.cs" />\r
+    <Compile Include="Mvc\Async\OperationCounter.cs" />\r
+    <Compile Include="Mvc\Async\ReflectedAsyncActionDescriptor.cs" />\r
+    <Compile Include="Mvc\Async\ReflectedAsyncControllerDescriptor.cs" />\r
+    <Compile Include="Mvc\Async\Trigger.cs" />\r
+    <Compile Include="Mvc\Async\TriggerListener.cs" />\r
+    <Compile Include="Mvc\Async\SimpleAsyncResult.cs" />\r
+    <Compile Include="Mvc\Async\EndInvokeDelegate.cs" />\r
+    <Compile Include="Mvc\Async\EndInvokeDelegate`1.cs" />\r
+    <Compile Include="Mvc\Async\SynchronizationContextUtil.cs" />\r
+    <Compile Include="Mvc\AuthorizationContext.cs" />\r
+    <Compile Include="Mvc\ByteArrayModelBinder.cs" />\r
+    <Compile Include="Mvc\ControllerContext.cs" />\r
+    <Compile Include="Mvc\Html\ChildActionExtensions.cs" />\r
+    <Compile Include="Mvc\ParameterInfoUtil.cs" />\r
+    <Compile Include="Mvc\HttpHandlerUtil.cs" />\r
+    <Compile Include="Mvc\ChildActionOnlyAttribute.cs" />\r
+    <Compile Include="Mvc\TypeDescriptorHelper.cs" />\r
+    <Compile Include="Mvc\ValidatableObjectAdapter.cs" />\r
+    <Compile Include="Mvc\ValueProviderFactories.cs" />\r
+    <Compile Include="Mvc\ValueProviderFactory.cs" />\r
+    <Compile Include="Mvc\ValueProviderFactoryCollection.cs" />\r
+    <Compile Include="Mvc\ValueProviderCollection.cs" />\r
+    <Compile Include="Mvc\DictionaryValueProvider`1.cs" />\r
+    <Compile Include="Mvc\NameValueCollectionValueProvider.cs" />\r
+    <Compile Include="Mvc\ValueProviderUtil.cs" />\r
+    <Compile Include="Mvc\IValueProvider.cs" />\r
+    <Compile Include="Mvc\DataErrorInfoModelValidatorProvider.cs" />\r
+    <Compile Include="Mvc\ModelValidatorProviderCollection.cs" />\r
+    <Compile Include="Mvc\DataAnnotationsModelMetadata.cs" />\r
+    <Compile Include="Mvc\HiddenInputAttribute.cs" />\r
+    <Compile Include="Mvc\HttpGetAttribute.cs" />\r
+    <Compile Include="Mvc\HttpPutAttribute.cs" />\r
+    <Compile Include="Mvc\HttpDeleteAttribute.cs" />\r
+    <Compile Include="Mvc\ModelClientValidationRequiredRule.cs" />\r
+    <Compile Include="Mvc\ModelClientValidationRangeRule.cs" />\r
+    <Compile Include="Mvc\ModelClientValidationStringLengthRule.cs" />\r
+    <Compile Include="Mvc\MvcHtmlString.cs" />\r
+    <Compile Include="Mvc\DataAnnotationsModelValidator.cs" />\r
+    <Compile Include="Mvc\DataAnnotationsModelValidatorProvider.cs" />\r
+    <Compile Include="Mvc\DataAnnotationsModelValidator`1.cs" />\r
+    <Compile Include="Mvc\EmptyModelValidatorProvider.cs" />\r
+    <Compile Include="Mvc\ExpressionHelper.cs" />\r
+    <Compile Include="Mvc\FieldValidationMetadata.cs" />\r
+    <Compile Include="Mvc\FormContext.cs" />\r
+    <Compile Include="Mvc\JsonRequestBehavior.cs" />\r
+    <Compile Include="Mvc\ModelClientValidationRegexRule.cs" />\r
+    <Compile Include="Mvc\ModelClientValidationRule.cs" />\r
+    <Compile Include="Mvc\ModelValidationResult.cs" />\r
+    <Compile Include="Mvc\ModelValidator.cs" />\r
+    <Compile Include="Mvc\ModelValidatorProvider.cs" />\r
+    <Compile Include="Mvc\ModelValidatorProviders.cs" />\r
+    <Compile Include="Mvc\RequireHttpsAttribute.cs" />\r
+    <Compile Include="Mvc\HttpRequestExtensions.cs" />\r
+    <Compile Include="Mvc\DataAnnotationsModelMetadataProvider.cs" />\r
+    <Compile Include="Mvc\EmptyModelMetadataProvider.cs" />\r
+    <Compile Include="Mvc\ModelMetadata.cs" />\r
+    <Compile Include="Mvc\ModelMetadataProvider.cs" />\r
+    <Compile Include="Mvc\ModelMetadataProviders.cs" />\r
+    <Compile Include="Mvc\AreaHelpers.cs" />\r
+    <Compile Include="Mvc\AreaRegistration.cs" />\r
+    <Compile Include="Mvc\AreaRegistrationContext.cs" />\r
+    <Compile Include="Mvc\Error.cs" />\r
+    <Compile Include="Mvc\IRouteWithArea.cs" />\r
+    <Compile Include="Mvc\Async\SingleEntryGate.cs" />\r
+    <Compile Include="Mvc\Html\PartialExtensions.cs" />\r
+    <Compile Include="Mvc\LinqBinaryModelBinder.cs" />\r
+    <Compile Include="Mvc\TryGetValueDelegate.cs" />\r
+    <Compile Include="Mvc\ViewDataInfo.cs" />\r
+    <Compile Include="Mvc\Html\DefaultDisplayTemplates.cs" />\r
+    <Compile Include="Mvc\Html\DefaultEditorTemplates.cs" />\r
+    <Compile Include="Mvc\Html\DisplayExtensions.cs" />\r
+    <Compile Include="Mvc\Html\EditorExtensions.cs" />\r
+    <Compile Include="Mvc\Html\LabelExtensions.cs" />\r
+    <Compile Include="Mvc\Html\TemplateHelpers.cs" />\r
+    <Compile Include="Mvc\HttpPostAttribute.cs" />\r
+    <Compile Include="Mvc\PathHelpers.cs" />\r
+    <Compile Include="Mvc\ExceptionContext.cs" />\r
+    <Compile Include="Mvc\ResultExecutedContext.cs" />\r
+    <Compile Include="Mvc\ResultExecutingContext.cs" />\r
+    <Compile Include="Mvc\TemplateInfo.cs" />\r
+    <Compile Include="Mvc\ValidateAntiForgeryTokenAttribute.cs" />\r
+    <Compile Include="Mvc\JavaScriptResult.cs" />\r
+    <Compile Include="Mvc\ActionDescriptor.cs" />\r
+    <Compile Include="Mvc\ActionMethodDispatcher.cs" />\r
+    <Compile Include="Mvc\ActionMethodSelector.cs" />\r
+    <Compile Include="Mvc\ActionMethodSelectorAttribute.cs" />\r
+    <Compile Include="Mvc\ActionNameSelectorAttribute.cs" />\r
+    <Compile Include="Mvc\AuthorizeAttribute.cs" />\r
+    <Compile Include="Mvc\Ajax\AjaxOptions.cs" />\r
+    <Compile Include="Mvc\Ajax\AjaxExtensions.cs" />\r
+    <Compile Include="Mvc\ActionMethodDispatcherCache.cs" />\r
+    <Compile Include="Mvc\BindAttribute.cs" />\r
+    <Compile Include="Mvc\ControllerBase.cs" />\r
+    <Compile Include="Mvc\ActionNameAttribute.cs" />\r
+    <Compile Include="Mvc\AcceptVerbsAttribute.cs" />\r
+    <Compile Include="Mvc\AjaxHelper`1.cs" />\r
+    <Compile Include="Mvc\HtmlHelper`1.cs" />\r
+    <Compile Include="Mvc\DictionaryHelpers.cs" />\r
+    <Compile Include="Mvc\AjaxRequestExtensions.cs" />\r
+    <Compile Include="Mvc\ModelBinderDictionary.cs" />\r
+    <Compile Include="Mvc\ValueProviderDictionary.cs" />\r
+    <Compile Include="Mvc\ViewContext.cs" />\r
+    <Compile Include="Mvc\ViewMasterPageControlBuilder.cs" />\r
+    <Compile Include="Mvc\ViewTemplateUserControl.cs">\r
+      <SubType>ASPXCodeBehind</SubType>\r
+    </Compile>\r
+    <Compile Include="Mvc\ViewTemplateUserControl`1.cs">\r
+      <SubType>ASPXCodeBehind</SubType>\r
+    </Compile>\r
+    <Compile Include="Mvc\ViewType.cs" />\r
+    <Compile Include="Mvc\ViewTypeControlBuilder.cs" />\r
+    <Compile Include="Mvc\ViewUserControlControlBuilder.cs">\r
+    </Compile>\r
+    <Compile Include="Mvc\ViewPageControlBuilder.cs">\r
+    </Compile>\r
+    <Compile Include="Mvc\ViewTypeParserFilter.cs" />\r
+    <Compile Include="Mvc\DefaultViewLocationCache.cs" />\r
+    <Compile Include="Mvc\FormCollection.cs" />\r
+    <Compile Include="Mvc\HttpPostedFileBaseModelBinder.cs" />\r
+    <Compile Include="Mvc\NullViewLocationCache.cs" />\r
+    <Compile Include="Mvc\ValidateInputAttribute.cs" />\r
+    <Compile Include="Mvc\FileContentResult.cs" />\r
+    <Compile Include="Mvc\FilePathResult.cs" />\r
+    <Compile Include="Mvc\FileResult.cs" />\r
+    <Compile Include="Mvc\FileStreamResult.cs" />\r
+    <Compile Include="Mvc\InputType.cs" />\r
+    <Compile Include="Mvc\ControllerDescriptorCache.cs" />\r
+    <Compile Include="Mvc\ReflectedParameterBindingInfo.cs" />\r
+    <Compile Include="Mvc\ParameterBindingInfo.cs" />\r
+    <Compile Include="Mvc\ReaderWriterCache`2.cs" />\r
+    <Compile Include="Mvc\DescriptorUtil.cs" />\r
+    <Compile Include="Mvc\ReflectedControllerDescriptor.cs" />\r
+    <Compile Include="Mvc\ControllerDescriptor.cs" />\r
+    <Compile Include="Mvc\ActionSelector.cs" />\r
+    <Compile Include="Mvc\ReflectedActionDescriptor.cs" />\r
+    <Compile Include="Mvc\Html\MvcForm.cs" />\r
+    <Compile Include="Mvc\HttpVerbs.cs" />\r
+    <Compile Include="Mvc\DefaultModelBinder.cs" />\r
+    <Compile Include="Mvc\ModelBindingContext.cs" />\r
+    <Compile Include="Mvc\ParameterDescriptor.cs" />\r
+    <Compile Include="Mvc\RouteValuesHelpers.cs" />\r
+    <Compile Include="Mvc\SelectListItem.cs" />\r
+    <Compile Include="Mvc\ReflectedParameterDescriptor.cs" />\r
+    <Compile Include="Mvc\ValueProviderResult.cs" />\r
+    <Compile Include="Mvc\CustomModelBinderAttribute.cs" />\r
+    <Compile Include="Mvc\FormMethod.cs" />\r
+    <Compile Include="Mvc\Html\FormExtensions.cs" />\r
+    <Compile Include="Mvc\Html\InputExtensions.cs">\r
+      <SubType>Code</SubType>\r
+    </Compile>\r
+    <Compile Include="Mvc\Html\RenderPartialExtensions.cs" />\r
+    <Compile Include="Mvc\Html\SelectExtensions.cs" />\r
+    <Compile Include="Mvc\Html\TextAreaExtensions.cs" />\r
+    <Compile Include="Mvc\Html\ValidationExtensions.cs" />\r
+    <Compile Include="Mvc\IModelBinder.cs" />\r
+    <Compile Include="Mvc\Html\LinkExtensions.cs" />\r
+    <Compile Include="Mvc\ModelBinderAttribute.cs" />\r
+    <Compile Include="Mvc\ModelBinders.cs" />\r
+    <Compile Include="Mvc\ModelStateDictionary.cs" />\r
+    <Compile Include="Mvc\ModelState.cs" />\r
+    <Compile Include="Mvc\ModelErrorCollection.cs" />\r
+    <Compile Include="Mvc\ModelError.cs" />\r
+    <Compile Include="Mvc\Ajax\InsertionMode.cs" />\r
+    <Compile Include="Mvc\HandleErrorAttribute.cs" />\r
+    <Compile Include="Mvc\HandleErrorInfo.cs" />\r
+    <Compile Include="Mvc\HttpUnauthorizedResult.cs" />\r
+    <Compile Include="Mvc\IActionInvoker.cs" />\r
+    <Compile Include="Mvc\IView.cs" />\r
+    <Compile Include="Mvc\IViewLocationCache.cs" />\r
+    <Compile Include="Mvc\MvcHttpHandler.cs" />\r
+    <Compile Include="Mvc\PartialViewResult.cs" />\r
+    <Compile Include="Mvc\SessionStateTempDataProvider.cs" />\r
+    <Compile Include="Mvc\ITempDataProvider.cs" />\r
+    <Compile Include="Mvc\OutputCacheAttribute.cs" />\r
+    <Compile Include="Mvc\FilterInfo.cs" />\r
+    <Compile Include="GlobalSuppressions.cs" />\r
+    <Compile Include="Mvc\ActionFilterAttribute.cs" />\r
+    <Compile Include="Mvc\ActionResult.cs" />\r
+    <Compile Include="Mvc\AjaxHelper.cs" />\r
+    <Compile Include="Mvc\BuildManagerWrapper.cs" />\r
+    <Compile Include="Mvc\Controller.cs" />\r
+    <Compile Include="Mvc\ControllerActionInvoker.cs" />\r
+    <Compile Include="Mvc\ControllerBuilder.cs" />\r
+    <Compile Include="Mvc\ControllerTypeCache.cs" />\r
+    <Compile Include="Mvc\ContentResult.cs" />\r
+    <Compile Include="Mvc\FilterAttribute.cs" />\r
+    <Compile Include="Mvc\IResultFilter.cs" />\r
+    <Compile Include="Mvc\IExceptionFilter.cs" />\r
+    <Compile Include="Mvc\IAuthorizationFilter.cs" />\r
+    <Compile Include="Mvc\JsonResult.cs" />\r
+    <Compile Include="Mvc\NameValueCollectionExtensions.cs" />\r
+    <Compile Include="Mvc\ViewDataDictionary`1.cs" />\r
+    <Compile Include="Mvc\EmptyResult.cs" />\r
+    <Compile Include="Mvc\MultiSelectList.cs" />\r
+    <Compile Include="Mvc\RedirectResult.cs" />\r
+    <Compile Include="Mvc\RedirectToRouteResult.cs" />\r
+    <Compile Include="Mvc\DefaultControllerFactory.cs" />\r
+    <Compile Include="Mvc\HtmlHelper.cs" />\r
+    <Compile Include="Mvc\IActionFilter.cs" />\r
+    <Compile Include="Mvc\IBuildManager.cs" />\r
+    <Compile Include="Mvc\IController.cs" />\r
+    <Compile Include="Mvc\IControllerFactory.cs" />\r
+    <Compile Include="Mvc\IViewDataContainer.cs" />\r
+    <Compile Include="Mvc\IViewEngine.cs" />\r
+    <Compile Include="Mvc\MvcHandler.cs" />\r
+    <Compile Include="Mvc\MvcRouteHandler.cs" />\r
+    <Compile Include="Mvc\NonActionAttribute.cs" />\r
+    <Compile Include="Mvc\RouteCollectionExtensions.cs" />\r
+    <Compile Include="Mvc\SelectList.cs" />\r
+    <Compile Include="Mvc\TempDataDictionary.cs" />\r
+    <Compile Include="Mvc\TypeHelpers.cs" />\r
+    <Compile Include="Mvc\UrlHelper.cs" />\r
+    <Compile Include="Mvc\ViewDataDictionary.cs" />\r
+    <Compile Include="Mvc\ViewEngineCollection.cs" />\r
+    <Compile Include="Mvc\ViewEngineResult.cs" />\r
+    <Compile Include="Mvc\ViewEngines.cs" />\r
+    <Compile Include="Mvc\ViewMasterPage.cs">\r
+      <SubType>ASPXCodeBehind</SubType>\r
+    </Compile>\r
+    <Compile Include="Mvc\ViewMasterPage`1.cs">\r
+      <SubType>ASPXCodeBehind</SubType>\r
+    </Compile>\r
+    <Compile Include="Mvc\ViewPage.cs">\r
+      <SubType>ASPXCodeBehind</SubType>\r
+    </Compile>\r
+    <Compile Include="Mvc\ViewPage`1.cs">\r
+      <SubType>ASPXCodeBehind</SubType>\r
+    </Compile>\r
+    <Compile Include="Mvc\ViewResult.cs" />\r
+    <Compile Include="Mvc\ViewResultBase.cs" />\r
+    <Compile Include="Mvc\ViewUserControl.cs">\r
+      <SubType>ASPXCodeBehind</SubType>\r
+    </Compile>\r
+    <Compile Include="Mvc\ViewUserControl`1.cs">\r
+      <SubType>ASPXCodeBehind</SubType>\r
+    </Compile>\r
+    <Compile Include="Mvc\VirtualPathProviderViewEngine.cs" />\r
+    <Compile Include="Mvc\WebFormView.cs" />\r
+    <Compile Include="Mvc\WebFormViewEngine.cs" />\r
+    <Compile Include="Properties\AssemblyInfo.cs" />\r
+    <Compile Include="Mvc\Resources\MvcResources.Designer.cs">\r
+      <AutoGen>True</AutoGen>\r
+      <DesignTime>True</DesignTime>\r
+      <DependentUpon>MvcResources.resx</DependentUpon>\r
+    </Compile>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <EmbeddedResource Include="Mvc\Resources\MvcResources.resx">\r
+      <Generator>ResXFileCodeGenerator</Generator>\r
+      <LastGenOutput>MvcResources.Designer.cs</LastGenOutput>\r
+      <SubType>Designer</SubType>\r
+    </EmbeddedResource>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <CodeAnalysisDictionary Include="..\CustomDictionary.xml" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ProjectReference Include="..\..\..\webpages\src\System.Web.Razor\System.Web.Razor.csproj">\r
+      <Project>{8F18041B-9410-4C36-A9C5-067813DF5F31}</Project>\r
+      <Name>System.Web.Razor</Name>\r
+    </ProjectReference>\r
+    <ProjectReference Include="..\..\..\webpages\src\System.Web.WebPages.Razor\System.Web.WebPages.Razor.csproj">\r
+      <Project>{0939B11A-FE4E-4BA1-8AD6-D97741EE314F}</Project>\r
+      <Name>System.Web.WebPages.Razor</Name>\r
+    </ProjectReference>\r
+    <ProjectReference Include="..\..\..\webpages\src\System.Web.WebPages\System.Web.WebPages.csproj">\r
+      <Project>{76EFA9C5-8D7E-4FDF-B710-E20F8B6B00D2}</Project>\r
+      <Name>System.Web.WebPages</Name>\r
+    </ProjectReference>\r
+  </ItemGroup>\r
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />\r
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \r
+       Other similar extension points exist, see Microsoft.Common.targets.\r
+  <Target Name="BeforeBuild">\r
+  </Target>\r
+  <Target Name="AfterBuild">\r
+  </Target>\r
+  -->\r
+</Project>
\ No newline at end of file
diff --git a/mcs/class/System.Web.Mvc3/System.Web.Mvc3.dll.sources b/mcs/class/System.Web.Mvc3/System.Web.Mvc3.dll.sources
new file mode 100644 (file)
index 0000000..837c3cb
--- /dev/null
@@ -0,0 +1,340 @@
+./GlobalSuppressions.cs
+./Mvc/AcceptVerbsAttribute.cs
+./Mvc/ActionDescriptor.cs
+./Mvc/ActionExecutedContext.cs
+./Mvc/ActionExecutingContext.cs
+./Mvc/ActionFilterAttribute.cs
+./Mvc/ActionMethodDispatcherCache.cs
+./Mvc/ActionMethodDispatcher.cs
+./Mvc/ActionMethodSelectorAttribute.cs
+./Mvc/ActionMethodSelector.cs
+./Mvc/ActionNameAttribute.cs
+./Mvc/ActionNameSelectorAttribute.cs
+./Mvc/ActionResult.cs
+./Mvc/ActionSelector.cs
+./Mvc/AdditionalMetaDataAttribute.cs
+./Mvc/Ajax/AjaxExtensions.cs
+./Mvc/Ajax/AjaxOptions.cs
+./Mvc/AjaxHelper`1.cs
+./Mvc/AjaxHelper.cs
+./Mvc/Ajax/InsertionMode.cs
+./Mvc/AjaxRequestExtensions.cs
+./Mvc/AllowHtmlAttribute.cs
+./Mvc/AreaHelpers.cs
+./Mvc/AreaRegistrationContext.cs
+./Mvc/AreaRegistration.cs
+./Mvc/AssociatedMetadataProvider.cs
+./Mvc/AssociatedValidatorProvider.cs
+./Mvc/Async/ActionDescriptorCreator.cs
+./Mvc/Async/AsyncActionDescriptor.cs
+./Mvc/Async/AsyncActionMethodSelector.cs
+./Mvc/Async/AsyncControllerActionInvoker.cs
+./Mvc/Async/AsyncManager.cs
+./Mvc/Async/AsyncResultWrapper.cs
+./Mvc/Async/AsyncUtil.cs
+./Mvc/Async/AsyncVoid.cs
+./Mvc/Async/BeginInvokeDelegate.cs
+./Mvc/AsyncController.cs
+./Mvc/Async/EndInvokeDelegate`1.cs
+./Mvc/Async/EndInvokeDelegate.cs
+./Mvc/Async/IAsyncActionInvoker.cs
+./Mvc/Async/IAsyncController.cs
+./Mvc/Async/IAsyncManagerContainer.cs
+./Mvc/Async/OperationCounter.cs
+./Mvc/Async/ReflectedAsyncActionDescriptor.cs
+./Mvc/Async/ReflectedAsyncControllerDescriptor.cs
+./Mvc/Async/SimpleAsyncResult.cs
+./Mvc/Async/SingleEntryGate.cs
+./Mvc/Async/SynchronizationContextUtil.cs
+./Mvc/Async/SynchronousOperationException.cs
+./Mvc/AsyncTimeoutAttribute.cs
+./Mvc/Async/Trigger.cs
+./Mvc/Async/TriggerListener.cs
+./Mvc/AuthorizationContext.cs
+./Mvc/AuthorizeAttribute.cs
+./Mvc/BindAttribute.cs
+./Mvc/BuildManagerCompiledView.cs
+./Mvc/BuildManagerViewEngine.cs
+./Mvc/BuildManagerWrapper.cs
+./Mvc/ByteArrayModelBinder.cs
+./Mvc/ChildActionOnlyAttribute.cs
+./Mvc/ChildActionValueProvider.cs
+./Mvc/ChildActionValueProviderFactory.cs
+./Mvc/ClientDataTypeModelValidatorProvider.cs
+./Mvc/CompareAttribute.cs
+./Mvc/ContentResult.cs
+./Mvc/ControllerActionInvoker.cs
+./Mvc/ControllerBase.cs
+./Mvc/ControllerBuilder.cs
+./Mvc/ControllerContext.cs
+./Mvc/Controller.cs
+./Mvc/ControllerDescriptorCache.cs
+./Mvc/ControllerDescriptor.cs
+./Mvc/ControllerInstanceFilterProvider.cs
+./Mvc/ControllerTypeCache.cs
+./Mvc/CustomModelBinderAttribute.cs
+./Mvc/DataAnnotationsModelMetadata.cs
+./Mvc/DataAnnotationsModelMetadataProvider.cs
+./Mvc/DataAnnotationsModelValidator`1.cs
+./Mvc/DataAnnotationsModelValidator.cs
+./Mvc/DataAnnotationsModelValidatorProvider.cs
+./Mvc/DataErrorInfoModelValidatorProvider.cs
+./Mvc/DataTypeUtil.cs
+./Mvc/DefaultControllerFactory.cs
+./Mvc/DefaultModelBinder.cs
+./Mvc/DefaultViewLocationCache.cs
+./Mvc/DependencyResolver.cs
+./Mvc/DependencyResolverExtensions.cs
+./Mvc/DescriptorUtil.cs
+./Mvc/DictionaryHelpers.cs
+./Mvc/DictionaryValueProvider`1.cs
+./Mvc/DynamicViewDataDictionary.cs
+./Mvc/EmptyModelMetadataProvider.cs
+./Mvc/EmptyModelValidatorProvider.cs
+./Mvc/EmptyResult.cs
+./Mvc/Error.cs
+./Mvc/ExceptionContext.cs
+./Mvc/ExpressionHelper.cs
+./Mvc/ExpressionUtil/BinaryExpressionFingerprint.cs
+./Mvc/ExpressionUtil/CachedExpressionCompiler.cs
+./Mvc/ExpressionUtil/ConditionalExpressionFingerprint.cs
+./Mvc/ExpressionUtil/ConstantExpressionFingerprint.cs
+./Mvc/ExpressionUtil/DefaultExpressionFingerprint.cs
+./Mvc/ExpressionUtil/ExpressionFingerprintChain.cs
+./Mvc/ExpressionUtil/ExpressionFingerprint.cs
+./Mvc/ExpressionUtil/FingerprintingExpressionVisitor.cs
+./Mvc/ExpressionUtil/HashCodeCombiner.cs
+./Mvc/ExpressionUtil/Hoisted`2.cs
+./Mvc/ExpressionUtil/HoistingExpressionVisitor.cs
+./Mvc/ExpressionUtil/IndexExpressionFingerprint.cs
+./Mvc/ExpressionUtil/LambdaExpressionFingerprint.cs
+./Mvc/ExpressionUtil/MemberExpressionFingerprint.cs
+./Mvc/ExpressionUtil/MethodCallExpressionFingerprint.cs
+./Mvc/ExpressionUtil/ParameterExpressionFingerprint.cs
+./Mvc/ExpressionUtil/TypeBinaryExpressionFingerprint.cs
+./Mvc/ExpressionUtil/UnaryExpressionFingerprint.cs
+./Mvc/FieldValidationMetadata.cs
+./Mvc/FileContentResult.cs
+./Mvc/FilePathResult.cs
+./Mvc/FileResult.cs
+./Mvc/FileStreamResult.cs
+./Mvc/FilterAttribute.cs
+./Mvc/FilterAttributeFilterProvider.cs
+./Mvc/Filter.cs
+./Mvc/FilterInfo.cs
+./Mvc/FilterProviderCollection.cs
+./Mvc/FilterProviders.cs
+./Mvc/FilterScope.cs
+./Mvc/FormCollection.cs
+./Mvc/FormContext.cs
+./Mvc/FormMethod.cs
+./Mvc/FormValueProvider.cs
+./Mvc/FormValueProviderFactory.cs
+./Mvc/GlobalFilterCollection.cs
+./Mvc/GlobalFilters.cs
+./Mvc/HandleErrorAttribute.cs
+./Mvc/HandleErrorInfo.cs
+./Mvc/HiddenInputAttribute.cs
+./Mvc/Html/ChildActionExtensions.cs
+./Mvc/Html/DefaultDisplayTemplates.cs
+./Mvc/Html/DefaultEditorTemplates.cs
+./Mvc/Html/DisplayExtensions.cs
+./Mvc/Html/DisplayTextExtensions.cs
+./Mvc/Html/EditorExtensions.cs
+./Mvc/Html/FormExtensions.cs
+./Mvc/HtmlHelper`1.cs
+./Mvc/HtmlHelper.cs
+./Mvc/Html/InputExtensions.cs
+./Mvc/Html/LabelExtensions.cs
+./Mvc/Html/LinkExtensions.cs
+./Mvc/Html/MvcForm.cs
+./Mvc/Html/PartialExtensions.cs
+./Mvc/Html/RenderPartialExtensions.cs
+./Mvc/Html/SelectExtensions.cs
+./Mvc/Html/TemplateHelpers.cs
+./Mvc/Html/TextAreaExtensions.cs
+./Mvc/Html/ValidationExtensions.cs
+./Mvc/HttpDeleteAttribute.cs
+./Mvc/HttpFileCollectionValueProvider.cs
+./Mvc/HttpFileCollectionValueProviderFactory.cs
+./Mvc/HttpGetAttribute.cs
+./Mvc/HttpHandlerUtil.cs
+./Mvc/HttpNotFoundResult.cs
+./Mvc/HttpPostAttribute.cs
+./Mvc/HttpPostedFileBaseModelBinder.cs
+./Mvc/HttpPutAttribute.cs
+./Mvc/HttpRequestExtensions.cs
+./Mvc/HttpStatusCodeResult.cs
+./Mvc/HttpUnauthorizedResult.cs
+./Mvc/HttpVerbs.cs
+./Mvc/IActionFilter.cs
+./Mvc/IActionInvoker.cs
+./Mvc/IAuthorizationFilter.cs
+./Mvc/IBuildManager.cs
+./Mvc/IClientValidatable.cs
+./Mvc/IControllerActivator.cs
+./Mvc/IController.cs
+./Mvc/IControllerFactory.cs
+./Mvc/IDependencyResolver.cs
+./Mvc/IExceptionFilter.cs
+./Mvc/IFilterProvider.cs
+./Mvc/IMetadataAware.cs
+./Mvc/IModelBinder.cs
+./Mvc/IModelBinderProvider.cs
+./Mvc/IMvcControlBuilder.cs
+./Mvc/IMvcFilter.cs
+./Mvc/InputType.cs
+./Mvc/IResolver.cs
+./Mvc/IResultFilter.cs
+./Mvc/IRouteWithArea.cs
+./Mvc/ITempDataProvider.cs
+./Mvc/IUniquelyIdentifiable.cs
+./Mvc/IUnvalidatedRequestValues.cs
+./Mvc/IUnvalidatedValueProvider.cs
+./Mvc/IValueProvider.cs
+./Mvc/IView.cs
+./Mvc/IViewDataContainer.cs
+./Mvc/IViewEngine.cs
+./Mvc/IViewLocationCache.cs
+./Mvc/IViewPageActivator.cs
+./Mvc/IViewStartPageChild.cs
+./Mvc/JavaScriptResult.cs
+./Mvc/JsonRequestBehavior.cs
+./Mvc/JsonResult.cs
+./Mvc/JsonValueProviderFactory.cs
+./Mvc/LinqBinaryModelBinder.cs
+./Mvc/ModelBinderAttribute.cs
+./Mvc/ModelBinderDictionary.cs
+./Mvc/ModelBinderProviderCollection.cs
+./Mvc/ModelBinderProviders.cs
+./Mvc/ModelBinders.cs
+./Mvc/ModelBindingContext.cs
+./Mvc/ModelClientValidationEqualToRule.cs
+./Mvc/ModelClientValidationRangeRule.cs
+./Mvc/ModelClientValidationRegexRule.cs
+./Mvc/ModelClientValidationRemoteRule.cs
+./Mvc/ModelClientValidationRequiredRule.cs
+./Mvc/ModelClientValidationRule.cs
+./Mvc/ModelClientValidationStringLengthRule.cs
+./Mvc/ModelErrorCollection.cs
+./Mvc/ModelError.cs
+./Mvc/ModelMetadata.cs
+./Mvc/ModelMetadataProvider.cs
+./Mvc/ModelMetadataProviders.cs
+./Mvc/ModelState.cs
+./Mvc/ModelStateDictionary.cs
+./Mvc/ModelValidationResult.cs
+./Mvc/ModelValidator.cs
+./Mvc/ModelValidatorProviderCollection.cs
+./Mvc/ModelValidatorProvider.cs
+./Mvc/ModelValidatorProviders.cs
+./Mvc/MultiSelectList.cs
+./Mvc/MultiServiceResolver.cs
+./Mvc/MvcFilter.cs
+./Mvc/MvcHandler.cs
+./Mvc/MvcHtmlString.cs
+./Mvc/MvcHttpHandler.cs
+./Mvc/MvcRouteHandler.cs
+./Mvc/MvcWebRazorHostFactory.cs
+./Mvc/NameValueCollectionExtensions.cs
+./Mvc/NameValueCollectionValueProvider.cs
+./Mvc/NoAsyncTimeoutAttribute.cs
+./Mvc/NonActionAttribute.cs
+./Mvc/NullViewLocationCache.cs
+./Mvc/OutputCacheAttribute.cs
+./Mvc/ParameterBindingInfo.cs
+./Mvc/ParameterDescriptor.cs
+./Mvc/ParameterInfoUtil.cs
+./Mvc/PartialViewResult.cs
+./Mvc/PathHelpers.cs
+./Mvc/PreApplicationStartCode.cs
+./Mvc/QueryStringValueProvider.cs
+./Mvc/QueryStringValueProviderFactory.cs
+./Mvc/RangeAttributeAdapter.cs
+./Mvc/Razor/MvcCSharpRazorCodeGenerator.cs
+./Mvc/Razor/MvcCSharpRazorCodeParser.cs
+./Mvc/Razor/MvcVBRazorCodeParser.cs
+./Mvc/Razor/MvcWebPageRazorHost.cs
+./Mvc/Razor/SetModelTypeCodeGenerator.cs
+./Mvc/Razor/StartPageLookupDelegate.cs
+./Mvc/RazorView.cs
+./Mvc/RazorViewEngine.cs
+./Mvc/ReaderWriterCache`2.cs
+./Mvc/RedirectResult.cs
+./Mvc/RedirectToRouteResult.cs
+./Mvc/ReflectedActionDescriptor.cs
+./Mvc/ReflectedAttributeCache.cs
+./Mvc/ReflectedControllerDescriptor.cs
+./Mvc/ReflectedParameterBindingInfo.cs
+./Mvc/ReflectedParameterDescriptor.cs
+./Mvc/RegularExpressionAttributeAdapter.cs
+./Mvc/RemoteAttribute.cs
+./Mvc/RequiredAttributeAdapter.cs
+./Mvc/RequireHttpsAttribute.cs
+./Mvc/Resources/MvcResources.Designer.cs
+./Mvc/ResultExecutedContext.cs
+./Mvc/ResultExecutingContext.cs
+./Mvc/RouteCollectionExtensions.cs
+./Mvc/RouteDataValueProvider.cs
+./Mvc/RouteDataValueProviderFactory.cs
+./Mvc/RouteValuesHelpers.cs
+./Mvc/SecurityUtil.cs
+./Mvc/SelectList.cs
+./Mvc/SelectListItem.cs
+./Mvc/SessionStateAttribute.cs
+./Mvc/SessionStateTempDataProvider.cs
+./Mvc/SingleServiceResolver.cs
+./Mvc/StringLengthAttributeAdapter.cs
+./Mvc/TagBuilderExtensions.cs
+./Mvc/TempDataDictionary.cs
+./Mvc/TemplateInfo.cs
+./Mvc/TryGetValueDelegate.cs
+./Mvc/TypeCacheSerializer.cs
+./Mvc/TypeCacheUtil.cs
+./Mvc/TypeDescriptorHelper.cs
+./Mvc/TypeHelpers.cs
+./Mvc/UnvalidatedRequestValuesAccessor.cs
+./Mvc/UnvalidatedRequestValuesWrapper.cs
+./Mvc/UrlHelper.cs
+./Mvc/UrlParameter.cs
+./Mvc/UrlRewriterHelper.cs
+./Mvc/ValidatableObjectAdapter.cs
+./Mvc/ValidateAntiForgeryTokenAttribute.cs
+./Mvc/ValidateInputAttribute.cs
+./Mvc/ValueProviderCollection.cs
+./Mvc/ValueProviderDictionary.cs
+./Mvc/ValueProviderFactories.cs
+./Mvc/ValueProviderFactoryCollection.cs
+./Mvc/ValueProviderFactory.cs
+./Mvc/ValueProviderResult.cs
+./Mvc/ValueProviderUtil.cs
+./Mvc/ViewContext.cs
+./Mvc/ViewDataDictionary`1.cs
+./Mvc/ViewDataDictionary.cs
+./Mvc/ViewDataInfo.cs
+./Mvc/ViewEngineCollection.cs
+./Mvc/ViewEngineResult.cs
+./Mvc/ViewEngines.cs
+./Mvc/ViewMasterPage`1.cs
+./Mvc/ViewMasterPageControlBuilder.cs
+./Mvc/ViewMasterPage.cs
+./Mvc/ViewPage`1.cs
+./Mvc/ViewPageControlBuilder.cs
+./Mvc/ViewPage.cs
+./Mvc/ViewResultBase.cs
+./Mvc/ViewResult.cs
+./Mvc/ViewStartPage.cs
+./Mvc/ViewTemplateUserControl`1.cs
+./Mvc/ViewTemplateUserControl.cs
+./Mvc/ViewTypeControlBuilder.cs
+./Mvc/ViewType.cs
+./Mvc/ViewTypeParserFilter.cs
+./Mvc/ViewUserControl`1.cs
+./Mvc/ViewUserControlControlBuilder.cs
+./Mvc/ViewUserControl.cs
+./Mvc/VirtualPathProviderViewEngine.cs
+./Mvc/WebFormView.cs
+./Mvc/WebFormViewEngine.cs
+./Mvc/WebViewPage`1.cs
+./Mvc/WebViewPage.cs
+./Properties/AssemblyInfo.cs
diff --git a/mcs/class/System.Web.Razor/Assembly/AssemblyInfo.cs b/mcs/class/System.Web.Razor/Assembly/AssemblyInfo.cs
new file mode 100644 (file)
index 0000000..bce0eb0
--- /dev/null
@@ -0,0 +1,41 @@
+//
+// AssemblyInfo.cs
+//
+// Authors:
+//     Marek Safar (marek.safar@gmail.com)
+//
+// Copyright (C) 2007 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+using System;
+using System.Reflection;
+using System.Resources;
+using System.Security;
+using System.Security.Permissions;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyDefaultAlias ("System.Web.Razor.dll")]
+
+[assembly: AssemblyInformationalVersion (Consts.FxFileVersion)]
+
diff --git a/mcs/class/System.Web.Razor/Makefile b/mcs/class/System.Web.Razor/Makefile
new file mode 100644 (file)
index 0000000..f2ea6ce
--- /dev/null
@@ -0,0 +1,46 @@
+thisdir = class/System.Web.Razor
+SUBDIRS = 
+include ../../build/rules.make
+
+LIBRARY = System.Web.Razor.dll
+LIBRARY_NAME = System.Web.Razor.dll
+
+UPSTREAM_DIR = ../../../external/aspnetwebstack/src
+RESX_DIST = \
+       $(UPSTREAM_DIR)/System.Web.Razor/Resources/RazorResources.resx \
+       $(UPSTREAM_DIR)/CommonResources.resx
+
+RESOURCES = $(subst $(UPSTREAM_DIR),$(build_libdir),$(RESX_DIST:.resx=.resources))
+
+LIB_MCS_FLAGS = \
+               /warn:1 \
+               /noconfig \
+               /keyfile:../winfx.pub -delaysign \
+               /r:System.dll \
+               /r:System.Core.dll \
+               /d:ASPNETWEBPAGES \
+               $(RESOURCES:%=/resource:%)
+
+EXTRA_DISTFILES = $(RESX_DIST)
+
+include ../../build/library.make
+
+$(build_lib): $(RESOURCES)
+
+# Canned recipe which would be useful, but make doesn't run it for some reason...
+#define run-resgen = 
+#      mkdir -p $(dir `echo $@ | $(PLATFORM_CHANGE_SEPARATOR_CMD)`)
+#      $(RESGEN) `echo $< | $(PLATFORM_CHANGE_SEPARATOR_CMD)` `echo $@ | $(PLATFORM_CHANGE_SEPARATOR_CMD)`
+#endef
+
+$(build_libdir)/System.Web.Razor/Resources/RazorResources.resources: $(UPSTREAM_DIR)/System.Web.Razor/Resources/RazorResources.resx
+#      Doesn't work for some reason
+#      $(run-resgen)
+       mkdir -p $(dir `echo $@ | $(PLATFORM_CHANGE_SEPARATOR_CMD)`)
+       $(RESGEN) `echo $< | $(PLATFORM_CHANGE_SEPARATOR_CMD)` `echo $@ | $(PLATFORM_CHANGE_SEPARATOR_CMD)`
+
+$(build_libdir)/CommonResources.resources: $(UPSTREAM_DIR)/CommonResources.resx
+#      Doesn't work for some reason
+#      $(run-resgen)
+       mkdir -p $(dir `echo $@ | $(PLATFORM_CHANGE_SEPARATOR_CMD)`)
+       $(RESGEN) `echo $< | $(PLATFORM_CHANGE_SEPARATOR_CMD)` `echo $@ | $(PLATFORM_CHANGE_SEPARATOR_CMD)`
diff --git a/mcs/class/System.Web.Razor/System.Web.Razor.dll.sources b/mcs/class/System.Web.Razor/System.Web.Razor.dll.sources
new file mode 100644 (file)
index 0000000..cf90675
--- /dev/null
@@ -0,0 +1,153 @@
+../../build/common/Consts.cs
+
+Assembly/AssemblyInfo.cs
+
+../../../external/aspnetwebstack/src/CommonAssemblyInfo.cs
+../../../external/aspnetwebstack/src/CommonResources.Designer.cs
+../../../external/aspnetwebstack/src/ExceptionHelper.cs
+../../../external/aspnetwebstack/src/GlobalSuppressions.cs
+../../../external/aspnetwebstack/src/HashCodeCombiner.cs
+../../../external/aspnetwebstack/src/TransparentCommonAssemblyInfo.cs
+
+../../../external/aspnetwebstack/src/System.Web.Razor/VBRazorCodeLanguage.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Utils/EnumeratorExtensions.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Utils/DisposableAction.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Utils/CharUtils.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Utils/EnumUtil.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/RazorTemplateEngine.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/RazorCodeLanguage.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/SyntaxConstants.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/ParserContext.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/ConditionalAttributeCollapser.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/VBCodeParser.Directives.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/MarkupRewriter.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/LanguageCharacteristics.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/HtmlMarkupParser.Block.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/TokenizerBackedParser.Helpers.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/SyntaxTree/BlockBuilder.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/SyntaxTree/RazorError.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/SyntaxTree/AcceptedCharacters.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/SyntaxTree/EquivalenceComparer.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/SyntaxTree/Span.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/SyntaxTree/BlockType.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/SyntaxTree/SpanKind.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/SyntaxTree/SyntaxTreeNode.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/SyntaxTree/Block.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/SyntaxTree/SpanBuilder.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/HtmlMarkupParser.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/RazorParser.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/ParserVisitor.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/MarkupCollapser.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/CSharpCodeParser.Statements.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/CSharpLanguageCharacteristics.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/HtmlMarkupParser.Document.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/ISyntaxTreeRewriter.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/ParserVisitorExtensions.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/HtmlMarkupParser.Section.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/TextReaderExtensions.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/CallbackVisitor.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/CSharpCodeParser.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/VBLanguageCharacteristics.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/CSharpCodeParser.Directives.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/BalancingModes.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/VBCodeParser.Statements.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/HtmlLanguageCharacteristics.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/ParserBase.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/ParserHelpers.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/WhitespaceRewriter.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/TokenizerBackedParser.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Parser/VBCodeParser.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/CSharpRazorCodeLanguage.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Properties/AssemblyInfo.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/RazorDebugHelpers.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/PartialParseResult.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/ParserResults.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Resources/RazorResources.Designer.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/RazorDirectiveAttribute.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/GeneratorResults.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/DocumentParseCompleteEventArgs.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/RazorEngineHost.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Tokenizer/VBTokenizer.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Tokenizer/ITokenizer.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Tokenizer/XmlHelpers.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Tokenizer/CSharpTokenizer.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Tokenizer/CSharpKeywordDetector.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Tokenizer/Symbols/HtmlSymbolType.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Tokenizer/Symbols/CSharpKeyword.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Tokenizer/Symbols/ISymbol.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Tokenizer/Symbols/VBKeyword.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Tokenizer/Symbols/HtmlSymbol.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Tokenizer/Symbols/SymbolBase.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Tokenizer/Symbols/SymbolExtensions.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Tokenizer/Symbols/VBSymbol.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Tokenizer/Symbols/CSharpSymbol.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Tokenizer/Symbols/KnownSymbolType.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Tokenizer/Symbols/SymbolTypeSuppressions.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Tokenizer/Symbols/VBSymbolType.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Tokenizer/Symbols/CSharpSymbolType.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Tokenizer/VBHelpers.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Tokenizer/VBKeywordDetector.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Tokenizer/Tokenizer.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Tokenizer/HtmlTokenizer.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Tokenizer/TokenizerView.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Tokenizer/CSharpHelpers.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Editor/BackgroundParseTask.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Editor/AutoCompleteEditHandler.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Editor/SpanEditHandler.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Editor/ImplicitExpressionEditHandler.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Editor/EditorHints.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Editor/SingleLineMarkupEditHandler.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Editor/EditResult.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/GlobalSuppressions.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/LiteralAttributeCodeGenerator.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/RazorDirectiveAttributeCodeGenerator.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/StatementCodeGenerator.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/SetVBOptionCodeGenerator.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/AttributeBlockCodeGenerator.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/DynamicAttributeBlockCodeGenerator.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/SetLayoutCodeGenerator.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/CodeGeneratorBase.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/CodeWriterExtensions.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/GeneratedCodeMapping.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/ExpressionRenderingMode.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/CodeGenerationCompleteEventArgs.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/GeneratedClassContext.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/CodeWriter.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/ExpressionCodeGenerator.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/RazorCommentCodeGenerator.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/BaseCodeWriter.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/SectionCodeGenerator.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/CSharpCodeWriter.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/AddImportCodeGenerator.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/VBCodeWriter.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/HelperCodeGenerator.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/BlockCodeGenerator.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/CodeGeneratorContext.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/VBRazorCodeGenerator.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/HybridCodeGenerator.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/RazorCodeGenerator.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/TypeMemberCodeGenerator.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/CSharpRazorCodeGenerator.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/TemplateBlockCodeGenerator.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/SetBaseTypeCodeGenerator.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/SpanCodeGenerator.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/IBlockCodeGenerator.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/MarkupCodeGenerator.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/ISpanCodeGenerator.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Generator/ResolveUrlCodeGenerator.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/RazorEditorParser.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Text/TextExtensions.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Text/SourceLocation.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Text/TextDocumentReader.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Text/LookaheadToken.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Text/SourceLocationTracker.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Text/TextBufferReader.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Text/LineTrackingStringBuffer.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Text/ITextBuffer.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Text/LocationTagged.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Text/BufferingTextReader.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Text/TextChange.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Text/TextChangeType.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Text/SeekableTextReader.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/Text/LookaheadTextReader.cs
+../../../external/aspnetwebstack/src/System.Web.Razor/StateMachine.cs
diff --git a/mcs/class/System.Web.WebPages.Deployment/Assembly/AssemblyInfo.cs b/mcs/class/System.Web.WebPages.Deployment/Assembly/AssemblyInfo.cs
new file mode 100644 (file)
index 0000000..e8362ba
--- /dev/null
@@ -0,0 +1,39 @@
+//
+// AssemblyInfo.cs
+//
+// Authors:
+//     Marek Safar (marek.safar@gmail.com)
+//
+// Copyright (C) 2007 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+using System;
+using System.Reflection;
+using System.Resources;
+using System.Security;
+using System.Security.Permissions;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyDefaultAlias ("System.Web.WebPages.Deployment.dll")]
+[assembly: AssemblyInformationalVersion (Consts.FxFileVersion)]
diff --git a/mcs/class/System.Web.WebPages.Deployment/Makefile b/mcs/class/System.Web.WebPages.Deployment/Makefile
new file mode 100644 (file)
index 0000000..f280b4b
--- /dev/null
@@ -0,0 +1,49 @@
+thisdir = class/System.Web.WebPages.Deployment
+SUBDIRS = 
+include ../../build/rules.make
+
+LIBRARY = System.Web.WebPages.Deployment.dll
+LIBRARY_NAME = System.Web.WebPages.Deployment.dll
+
+UPSTREAM_DIR = ../../../external/aspnetwebstack/src
+RESX_DIST = \
+       $(UPSTREAM_DIR)/System.Web.WebPages.Deployment/Resources/ConfigurationResources.resx \
+       $(UPSTREAM_DIR)/CommonResources.resx
+
+RESOURCES = $(subst $(UPSTREAM_DIR),$(build_libdir),$(RESX_DIST:.resx=.resources))
+
+LIB_MCS_FLAGS = \
+               /warn:1 \
+               /noconfig \
+               /keyfile:../winfx.pub -delaysign \
+               /r:System.dll \
+               /r:System.Core.dll \
+               /r:System.Configuration.dll \
+               /r:System.Web.dll \
+               /r:Microsoft.Web.Infrastructure.dll \
+               /d:ASPNETWEBPAGES \
+               $(RESOURCES:%=/resource:%)
+
+EXTRA_DISTFILES = $(RESX_DIST)
+
+include ../../build/library.make
+
+$(build_lib): $(RESOURCES)
+
+# Canned recipe which would be useful, but make doesn't run it for some reason...
+#define run-resgen = 
+#      mkdir -p $(dir `echo $@ | $(PLATFORM_CHANGE_SEPARATOR_CMD)`)
+#      $(RESGEN) `echo $< | $(PLATFORM_CHANGE_SEPARATOR_CMD)` `echo $@ | $(PLATFORM_CHANGE_SEPARATOR_CMD)`
+#endef
+
+$(build_libdir)/System.Web.WebPages.Deployment/Resources/ConfigurationResources.resources: $(UPSTREAM_DIR)/System.Web.WebPages.Deployment/Resources/ConfigurationResources.resx
+#      Doesn't work for some reason
+#      $(run-resgen)
+       mkdir -p $(dir `echo $@ | $(PLATFORM_CHANGE_SEPARATOR_CMD)`)
+       $(RESGEN) `echo $< | $(PLATFORM_CHANGE_SEPARATOR_CMD)` `echo $@ | $(PLATFORM_CHANGE_SEPARATOR_CMD)`
+
+$(build_libdir)/CommonResources.resources: $(UPSTREAM_DIR)/CommonResources.resx
+#      Doesn't work for some reason
+#      $(run-resgen)
+       mkdir -p $(dir `echo $@ | $(PLATFORM_CHANGE_SEPARATOR_CMD)`)
+       $(RESGEN) `echo $< | $(PLATFORM_CHANGE_SEPARATOR_CMD)` `echo $@ | $(PLATFORM_CHANGE_SEPARATOR_CMD)`
diff --git a/mcs/class/System.Web.WebPages.Deployment/System.Web.WebPages.Deployment.dll.sources b/mcs/class/System.Web.WebPages.Deployment/System.Web.WebPages.Deployment.dll.sources
new file mode 100644 (file)
index 0000000..66d8179
--- /dev/null
@@ -0,0 +1,21 @@
+../../build/common/Consts.cs
+
+Assembly/AssemblyInfo.cs
+
+../../../external/aspnetwebstack/src/CommonAssemblyInfo.cs
+../../../external/aspnetwebstack/src/CommonResources.Designer.cs
+../../../external/aspnetwebstack/src/ExceptionHelper.cs
+../../../external/aspnetwebstack/src/GlobalSuppressions.cs
+../../../external/aspnetwebstack/src/TransparentCommonAssemblyInfo.cs
+
+../../../external/aspnetwebstack/src/System.Web.WebPages.Deployment/AppDomainHelper.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages.Deployment/AssemblyUtils.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages.Deployment/BuildManagerWrapper.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages.Deployment/Common/IFileSystem.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages.Deployment/Common/PhysicalFileSystem.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages.Deployment/GlobalSuppressions.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages.Deployment/IBuildManager.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages.Deployment/PreApplicationStartCode.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages.Deployment/Properties/AssemblyInfo.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages.Deployment/Resources/ConfigurationResources.Designer.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages.Deployment/WebPagesDeployment.cs
diff --git a/mcs/class/System.Web.WebPages.Razor/Assembly/AssemblyInfo.cs b/mcs/class/System.Web.WebPages.Razor/Assembly/AssemblyInfo.cs
new file mode 100644 (file)
index 0000000..be48746
--- /dev/null
@@ -0,0 +1,42 @@
+//
+// AssemblyInfo.cs
+//
+// Authors:
+//     Marek Safar (marek.safar@gmail.com)
+//
+// Copyright (C) 2007 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+using System;
+using System.Reflection;
+using System.Resources;
+using System.Security;
+using System.Security.Permissions;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyDefaultAlias ("System.Web.WebPages.Razor.dll")]
+
+[assembly: SatelliteContractVersion (Consts.FxVersion)]
+[assembly: AssemblyInformationalVersion (Consts.FxFileVersion)]
+
diff --git a/mcs/class/System.Web.WebPages.Razor/Makefile b/mcs/class/System.Web.WebPages.Razor/Makefile
new file mode 100644 (file)
index 0000000..460e08c
--- /dev/null
@@ -0,0 +1,51 @@
+thisdir = class/System.Web.WebPages.Razor
+SUBDIRS = 
+include ../../build/rules.make
+
+LIBRARY = System.Web.WebPages.Razor.dll
+LIBRARY_NAME = System.Web.WebPages.Razor.dll
+
+UPSTREAM_DIR = ../../../external/aspnetwebstack/src
+RESX_DIST = \
+       $(UPSTREAM_DIR)/System.Web.WebPages.Razor/Resources/RazorWebResources.resx \
+       $(UPSTREAM_DIR)/CommonResources.resx
+
+RESOURCES = $(subst $(UPSTREAM_DIR),$(build_libdir),$(RESX_DIST:.resx=.resources))
+
+LIB_MCS_FLAGS = \
+               /warn:1 \
+               /noconfig \
+               /keyfile:../winfx.pub \
+               /delaysign \
+               /r:System.dll \
+               /r:System.Core.dll \
+               /r:System.Configuration.dll \
+               /r:System.Web.dll \
+               /r:System.Web.WebPages.dll \
+               /r:System.Web.Razor.dll \
+               /d:ASPNETWEBPAGES \
+               $(RESOURCES:%=/resource:%)
+
+EXTRA_DISTFILES = $(RESX_DIST)
+
+include ../../build/library.make
+
+$(build_lib): $(RESOURCES)
+
+# Canned recipe which would be useful, but make doesn't run it for some reason...
+#define run-resgen = 
+#      mkdir -p $(dir `echo $@ | $(PLATFORM_CHANGE_SEPARATOR_CMD)`)
+#      $(RESGEN) `echo $< | $(PLATFORM_CHANGE_SEPARATOR_CMD)` `echo $@ | $(PLATFORM_CHANGE_SEPARATOR_CMD)`
+#endef
+
+$(build_libdir)/System.Web.WebPages.Razor/Resources/RazorWebResources.resources: $(UPSTREAM_DIR)/System.Web.WebPages.Razor/Resources/RazorWebResources.resx
+#      Doesn't work for some reason
+#      $(run-resgen)
+       mkdir -p $(dir `echo $@ | $(PLATFORM_CHANGE_SEPARATOR_CMD)`)
+       $(RESGEN) `echo $< | $(PLATFORM_CHANGE_SEPARATOR_CMD)` `echo $@ | $(PLATFORM_CHANGE_SEPARATOR_CMD)`
+
+$(build_libdir)/CommonResources.resources: $(UPSTREAM_DIR)/CommonResources.resx
+#      Doesn't work for some reason
+#      $(run-resgen)
+       mkdir -p $(dir `echo $@ | $(PLATFORM_CHANGE_SEPARATOR_CMD)`)
+       $(RESGEN) `echo $< | $(PLATFORM_CHANGE_SEPARATOR_CMD)` `echo $@ | $(PLATFORM_CHANGE_SEPARATOR_CMD)`
diff --git a/mcs/class/System.Web.WebPages.Razor/System.Web.WebPages.Razor.dll.sources b/mcs/class/System.Web.WebPages.Razor/System.Web.WebPages.Razor.dll.sources
new file mode 100644 (file)
index 0000000..2adb7c2
--- /dev/null
@@ -0,0 +1,24 @@
+../../build/common/Consts.cs
+
+Assembly/AssemblyInfo.cs
+
+../../../external/aspnetwebstack/src/CommonAssemblyInfo.cs
+../../../external/aspnetwebstack/src/CommonResources.Designer.cs
+../../../external/aspnetwebstack/src/TransparentCommonAssemblyInfo.cs
+
+../../../external/aspnetwebstack/src/System.Web.WebPages.Razor/AssemblyBuilderWrapper.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages.Razor/CompilingPathEventArgs.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages.Razor/Configuration/HostSection.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages.Razor/Configuration/RazorPagesSection.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages.Razor/Configuration/RazorWebSectionGroup.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages.Razor/GlobalSuppressions.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages.Razor/HostingEnvironmentWrapper.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages.Razor/IAssemblyBuilder.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages.Razor/IHostingEnvironment.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages.Razor/PreApplicationStartCode.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages.Razor/Properties/AssemblyInfo.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages.Razor/RazorBuildProvider.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages.Razor/Resources/RazorWebResources.Designer.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages.Razor/WebCodeRazorHost.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages.Razor/WebPageRazorHost.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages.Razor/WebRazorHostFactory.cs
diff --git a/mcs/class/System.Web.WebPages/Assembly/AssemblyInfo.cs b/mcs/class/System.Web.WebPages/Assembly/AssemblyInfo.cs
new file mode 100644 (file)
index 0000000..c9f1293
--- /dev/null
@@ -0,0 +1,42 @@
+//
+// AssemblyInfo.cs
+//
+// Authors:
+//     Marek Safar (marek.safar@gmail.com)
+//
+// Copyright (C) 2007 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+
+using System;
+using System.Reflection;
+using System.Resources;
+using System.Security;
+using System.Security.Permissions;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyDefaultAlias ("System.Web.WebPages.dll")]
+
+[assembly: SatelliteContractVersion (Consts.FxVersion)]
+[assembly: AssemblyInformationalVersion (Consts.FxFileVersion)]
+
diff --git a/mcs/class/System.Web.WebPages/Makefile b/mcs/class/System.Web.WebPages/Makefile
new file mode 100644 (file)
index 0000000..23bd17b
--- /dev/null
@@ -0,0 +1,57 @@
+thisdir = class/System.Web.WebPages
+SUBDIRS = 
+include ../../build/rules.make
+
+LIBRARY = System.Web.WebPages.dll
+LIBRARY_NAME = System.Web.WebPages.dll
+
+UPSTREAM_DIR = ../../../external/aspnetwebstack/src
+RESX_DIST = \
+       $(UPSTREAM_DIR)/System.Web.WebPages/Resources/WebPageResources.resx \
+       $(UPSTREAM_DIR)/CommonResources.resx
+
+RESOURCES = $(subst $(UPSTREAM_DIR),$(build_libdir),$(RESX_DIST:.resx=.resources))
+
+LIB_MCS_FLAGS = \
+               /warn:1 \
+               /noconfig \
+               /keyfile:../winfx.pub \
+               /delaysign \
+               /r:Microsoft.CSharp.dll \
+               /r:Microsoft.Web.Infrastructure.dll \
+               /r:System.dll \
+               /r:System.ComponentModel.DataAnnotations.dll \
+               /r:System.Configuration.dll \
+               /r:System.Core.dll \
+               /r:System.Data.Linq.dll \
+               /r:System.Web.dll \
+               /r:System.Web.WebPages.Deployment.dll \
+               /r:System.Web.Razor.dll \
+               /r:System.Xml.dll \
+               /r:System.Xml.Linq.dll \
+               /d:ASPNETWEBPAGES \
+               $(RESOURCES:%=/resource:%)
+
+EXTRA_DISTFILES = $(RESX_DIST)
+
+include ../../build/library.make
+
+$(build_lib): $(RESOURCES)
+
+# Canned recipe which would be useful, but make doesn't run it for some reason...
+#define run-resgen = 
+#      mkdir -p $(dir `echo $@ | $(PLATFORM_CHANGE_SEPARATOR_CMD)`)
+#      $(RESGEN) `echo $< | $(PLATFORM_CHANGE_SEPARATOR_CMD)` `echo $@ | $(PLATFORM_CHANGE_SEPARATOR_CMD)`
+#endef
+
+$(build_libdir)/System.Web.WebPages/Resources/WebPageResources.resources: $(UPSTREAM_DIR)/System.Web.WebPages/Resources/WebPageResources.resx
+#      Doesn't work for some reason
+#      $(run-resgen)
+       mkdir -p $(dir `echo $@ | $(PLATFORM_CHANGE_SEPARATOR_CMD)`)
+       $(RESGEN) `echo $< | $(PLATFORM_CHANGE_SEPARATOR_CMD)` `echo $@ | $(PLATFORM_CHANGE_SEPARATOR_CMD)`
+
+$(build_libdir)/CommonResources.resources: $(UPSTREAM_DIR)/CommonResources.resx
+#      Doesn't work for some reason
+#      $(run-resgen)
+       mkdir -p $(dir `echo $@ | $(PLATFORM_CHANGE_SEPARATOR_CMD)`)
+       $(RESGEN) `echo $< | $(PLATFORM_CHANGE_SEPARATOR_CMD)` `echo $@ | $(PLATFORM_CHANGE_SEPARATOR_CMD)`
diff --git a/mcs/class/System.Web.WebPages/System.Web.WebPages.dll.sources b/mcs/class/System.Web.WebPages/System.Web.WebPages.dll.sources
new file mode 100644 (file)
index 0000000..15f0fb7
--- /dev/null
@@ -0,0 +1,130 @@
+../../build/common/Consts.cs
+
+Assembly/AssemblyInfo.cs
+
+../../../external/aspnetwebstack/src/CommonAssemblyInfo.cs
+../../../external/aspnetwebstack/src/CommonResources.Designer.cs
+../../../external/aspnetwebstack/src/ExceptionHelper.cs
+../../../external/aspnetwebstack/src/GlobalSuppressions.cs
+../../../external/aspnetwebstack/src/HashCodeCombiner.cs
+../../../external/aspnetwebstack/src/TransparentCommonAssemblyInfo.cs
+../../../external/aspnetwebstack/src/MimeMapping.cs
+../../../external/aspnetwebstack/src/IVirtualPathUtility.cs
+../../../external/aspnetwebstack/src/VirtualPathUtilityWrapper.cs
+
+../../../external/aspnetwebstack/src/System.Web.WebPages/ApplicationPart.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/ApplicationParts/ApplicationPartRegistry.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/ApplicationParts/DictionaryBasedVirtualPathFactory.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/ApplicationParts/IResourceAssembly.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/ApplicationParts/LazyAction.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/ApplicationParts/ResourceAssembly.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/ApplicationParts/ResourceHandler.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/ApplicationParts/ResourceRouteHandler.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/ApplicationStartPage.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/AttributeValue.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/BrowserHelpers.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/BrowserOverride.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/BrowserOverrideStore.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/BrowserOverrideStores.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/BuildManagerWrapper.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Common/DisposableAction.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/CookieBrowserOverrideStore.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/DefaultDisplayMode.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/DisplayInfo.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/DisplayModeProvider.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/DynamicHttpApplicationState.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/DynamicPageDataDictionary.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/FileExistenceCache.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/GlobalSuppressions.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/HelperPage.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/HelperResult.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Helpers/AntiForgery.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Helpers/AntiForgeryData.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Helpers/AntiForgeryDataSerializer.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Helpers/AntiForgeryWorker.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Helpers/UnvalidatedRequestValues.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Helpers/Validation.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Html/HtmlHelper.Checkbox.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Html/HtmlHelper.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Html/HtmlHelper.Input.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Html/HtmlHelper.Internal.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Html/HtmlHelper.Label.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Html/HtmlHelper.Radio.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Html/HtmlHelper.Select.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Html/HtmlHelper.TextArea.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Html/HtmlHelper.Validation.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Html/ModelState.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Html/ModelStateDictionary.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Html/SelectListItem.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/HttpContextExtensions.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/IDisplayMode.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Instrumentation/HttpContextAdapter.Availability.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Instrumentation/HttpContextAdapter.generated.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Instrumentation/InstrumentationService.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Instrumentation/PageExecutionContextAdapter.generated.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Instrumentation/PageExecutionListenerAdapter.generated.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Instrumentation/PageInstrumentationServiceAdapter.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Instrumentation/PositionTagged.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/ITemplateFile.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/IVirtualPathFactory.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/IWebPageRequestExecutor.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Mvc/HttpAntiForgeryException.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Mvc/ModelClientValidationEqualToRule.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Mvc/ModelClientValidationRangeRule.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Mvc/ModelClientValidationRegexRule.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Mvc/ModelClientValidationRemoteRule.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Mvc/ModelClientValidationRequiredRule.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Mvc/ModelClientValidationRule.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Mvc/ModelClientValidationStringLengthRule.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Mvc/TagBuilder.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Mvc/TagRenderMode.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Mvc/UnobtrusiveValidationAttributesGenerator.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/PageDataDictionary.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/PageVirtualPathAttribute.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/PreApplicationStartCode.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Properties/AssemblyInfo.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/ReflectionDynamicObject.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/RequestBrowserOverrideStore.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/RequestExtensions.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/RequestResourceTracker.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Resources/WebPageResources.Designer.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/ResponseExtensions.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Scope/ApplicationScopeStorageDictionary.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Scope/AspNetRequestScopeStorageProvider.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Scope/IScopeStorageProvider.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Scope/ScopeStorageComparer.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Scope/ScopeStorage.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Scope/ScopeStorageDictionary.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Scope/StaticScopeStorageProvider.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Scope/WebConfigScopeStorageDictionary.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/SectionWriter.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/SecurityUtil.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/StartPage.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/StringExtensions.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/TemplateFileInfo.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/TemplateStack.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/UrlDataList.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Utils/BuildManagerExceptionUtil.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Utils/CultureUtil.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Utils/PathUtil.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Utils/SessionStateUtil.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Utils/TypeHelper.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Utils/UrlUtil.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Validation/CompareValidator.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Validation/DataTypeValidator.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Validation/IValidator.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Validation/RequestFieldValidatorBase.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Validation/ValidationAttributeAdapter.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Validation/ValidationHelper.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/Validation/Validator.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/VirtualPathFactoryExtensions.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/VirtualPathFactoryManager.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/WebPageBase.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/WebPageContext.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/WebPage.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/WebPageExecutingBase.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/WebPageHttpHandler.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/WebPageHttpModule.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/WebPageMatch.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/WebPageRenderingBase.cs
+../../../external/aspnetwebstack/src/System.Web.WebPages/WebPageRoute.cs
index 7f1691c32fceb94a78fc27c967166545e286eaae..399812855e1ba649a72764f53e9f54e89f7c23c2 100644 (file)
@@ -321,6 +321,7 @@ EXTRA_DISTFILES = \
        $(shell find Test/tools/ -path '*/.svn' -prune -o -type f -printf "'%p' ") \
        System.Web_standalone_test.dll.sources \
        standalone-runner-support.dll.sources \
+       $(shell find Test/System.Web.Caching/CacheItemPriorityQueueTestData/ -name "Sequence*.*" -type f -printf "'%p' ") \
        ASPState.sql
 
 BUILT_SOURCES = System.Web/UplevelHelper.cs 
index b664bca0850a3c7d1e82548855bdf0c8db6970cb..5dfdbef48e958635afd1d84373b009f6d4664992 100644 (file)
@@ -66,7 +66,7 @@ EXTRA_DISTFILES = \
        Test/XmlFiles/76102.xml         \
        Test/XmlFiles/79683.dtd         \
        Test/XmlFiles/496192.xml        \
-       Test/XmlFiles/496192.xsd        \
+       Test/XmlFiles/*.xsd     \
        $(wildcard Test/XmlFiles/xsd/*.xml) \
        $(wildcard Test/XmlFiles/xsd/*.xsd) \
        $(wildcard Test/XmlFiles/xsl/*.xml) \
index 2ee3a8ee2da09ca0d8eb4755f67f87edbe96ca23..42dce1ffe26e3ddf5a83246e4060c5b34f027c12 100644 (file)
@@ -77,6 +77,11 @@ namespace System.Diagnostics {
                                String trace = Environment.GetEnvironmentVariable("MONO_TRACE_LISTENER");
 #endif
 
+#if MOBILE
+                               if (trace == null)
+                                       trace = ConsoleOutTrace;
+#endif
+
                                if (trace != null) {
                                        string file = null;
                                        string prefix = null;
index 265cd6eb60d4c3b456999502657f930dbf367e11..167045711178e4572ebb9eb009c25089764d0277 100644 (file)
@@ -37,6 +37,7 @@ using System.Threading;
 
 namespace System.Diagnostics {
 
+#if !MOBILE
        internal class TraceImplSettings {
                public const string Key = ".__TraceInfoSettingsKey__.";
 
@@ -49,10 +50,13 @@ namespace System.Diagnostics {
                        Listeners.Add (new DefaultTraceListener (), this);
                }
        }
+#endif
 
        internal class TraceImpl {
 
+#if !MOBILE
                private static object initLock = new object ();
+#endif
 
                private static bool autoFlush;
 
@@ -91,6 +95,13 @@ namespace System.Diagnostics {
                {
                }
 
+#if MOBILE
+               static TraceImpl ()
+               {
+                       listeners = new TraceListenerCollection (true);
+               }
+#endif
+
                public static bool AutoFlush {
                        get {
                                InitOnce ();
@@ -151,7 +162,7 @@ namespace System.Diagnostics {
                }
 
                static bool use_global_lock;
-#if NET_2_0
+#if NET_2_0 && !MOBILE
                static CorrelationManager correlation_manager = new CorrelationManager ();
 
                public static CorrelationManager CorrelationManager {
@@ -193,6 +204,7 @@ namespace System.Diagnostics {
                // in the IDictionary returned).
                private static void InitOnce ()
                {
+#if !MOBILE
                        if (initLock != null) {
                                lock (initLock) {
                                        if (listeners == null) {
@@ -209,6 +221,7 @@ namespace System.Diagnostics {
                                }
                                initLock = null;
                        }
+#endif
                }
 
                // FIXME: According to MSDN, this method should display a dialog box
index 873a62343c63dd7e6c17524706b06f0ee1166874..6ce37000c10bc7614089c66d93e7ab0115499d43 100644 (file)
@@ -76,10 +76,12 @@ namespace System.Diagnostics {
                        set { System.Threading.Thread.SetData (_attributesStore, value); }
                }
 
+#if !MOBILE
                private TraceFilter filter {
                        get { return (TraceFilter) System.Threading.Thread.GetData (_filterStore); }
                        set { System.Threading.Thread.SetData (_filterStore, value); }
                }
+#endif
 
                private TraceOptions options {
                        get {
@@ -101,8 +103,10 @@ namespace System.Diagnostics {
 #if NET_2_0
                [ThreadStatic]
                private StringDictionary attributes = new StringDictionary ();
+#if !MOBILE
                [ThreadStatic]
                private TraceFilter filter;
+#endif
                [ThreadStatic]
                private TraceOptions options;
 #endif
@@ -234,6 +238,7 @@ namespace System.Diagnostics {
                        return String.Join (joiner, arr);
                }
 
+#if !MOBILE
                [ComVisible (false)]
                public virtual void TraceData (TraceEventCache eventCache, string source,
                        TraceEventType eventType, int id, object data)
@@ -298,6 +303,7 @@ namespace System.Diagnostics {
                {
                        TraceEvent (eventCache, source, TraceEventType.Transfer, id, String.Format ("{0}, relatedActivityId={1}", message, relatedActivityId));
                }
+#endif
 
                protected internal virtual string [] GetSupportedAttributes ()
                {
@@ -308,11 +314,13 @@ namespace System.Diagnostics {
                        get { return attributes; }
                }
 
+#if !MOBILE
                [ComVisibleAttribute (false)]
                public TraceFilter Filter {
                        get { return filter; }
                        set { filter = value; }
                }
+#endif
 
                [ComVisibleAttribute (false)]
                public TraceOptions TraceOutputOptions {
index d01064be91c0548043f8d1384ce904e2cd85cc82..f2c36d87f9aef9d87ce796f9f40bd7fa1f5710e6 100644 (file)
@@ -109,12 +109,14 @@ namespace System.Diagnostics {
                        return listeners.Add (listener);
                }
 
+#if !MOBILE
                internal void Add (TraceListener listener, TraceImplSettings settings)
                {
                        listener.IndentLevel = settings.IndentLevel;
                        listener.IndentSize  = settings.IndentSize;
                        listeners.Add (listener);
                }
+#endif
 
                private void InitializeListener (TraceListener listener)
                {
index 6656ee67febaf08d209718fd97832722eda3c52c..b36696dbb6948b7cedae925f9fdb94b26cbe8232 100644 (file)
@@ -191,7 +191,8 @@ System.ComponentModel/WeakObjectWrapperComparer.cs
 System.ComponentModel/Win32Exception.cs
 System.Diagnostics/DataReceivedEventArgs.cs
 System.Diagnostics/DataReceivedEventHandler.cs
-System.Diagnostics/Debug_2_1.cs
+System.Diagnostics/Debug.cs
+System.Diagnostics/DefaultTraceListener.cs
 System.Diagnostics/FileVersionInfo.cs
 System.Diagnostics/MonitoringDescriptionAttribute.cs
 System.Diagnostics/Process.cs
@@ -203,6 +204,10 @@ System.Diagnostics/ProcessThread.cs
 System.Diagnostics/ProcessThreadCollection.cs
 System.Diagnostics/ProcessWindowStyle.cs
 System.Diagnostics/Stopwatch.cs
+System.Diagnostics/TraceImpl.cs
+System.Diagnostics/TraceListener.cs
+System.Diagnostics/TraceListenerCollection.cs
+System.Diagnostics/TraceOptions.cs
 System.Diagnostics/ThreadPriorityLevel.cs
 System.Diagnostics/ThreadState.cs
 System.Diagnostics/ThreadWaitReason.cs
index 147ed2ae5fdb7e1e5654b6a29279e5b0f366b52d..dc4d39615df605f5790bb4d174a479efa88ea34a 100644 (file)
@@ -114,7 +114,7 @@ $(vtsdir)/BinarySerializationOverVersions.exe: $(vtsdir)/BinarySerializationOver
 # Need to define MONO_PATH to an absolute dir since the test is ran from a subdir
 run-test-vts: test-vts
        @echo Running vts tests...
-       MONO_PATH=$(PWD)/../lib/$(PROFILE) $(TEST_RUNTIME) $(RUNTIME_FLAGS) $(TEST_HARNESS) -noshadow \
+       $(TEST_RUNTIME) $(RUNTIME_FLAGS) $(TEST_HARNESS) -noshadow \
                $(vtsdir)/BinarySerializationOverVersions.exe 
 test: test-vts
 run-test: run-test-vts
index da9e3075c61c9c0e728adecf4a446bca04774dcb..ebedda41ac7e90f152b5fd0e1a4612bbd8112a08 100644 (file)
@@ -27,8 +27,9 @@ namespace System.IO {
 
                public override void Write (string s)
                {
-                       foreach (char c in s)
-                               Write (c);
+                       if (s != null)
+                               foreach (char c in s)
+                                       Write (c);
                }
 
                public override void Write (char value)
index 26873ce83c4f4664deda1b21eff646d22848101a..5e366bbf51c0749ab37655871e373ac7b6b3b126 100644 (file)
@@ -313,6 +313,12 @@ namespace Mono.CSharp {
                        }
 
                        var hoisted = localVariable.HoistedVariant;
+                       if (hoisted != null && hoisted.Storey != this && hoisted.Storey.Kind == MemberKind.Struct) {
+                               // TODO: It's too late the field is defined in HoistedLocalVariable ctor
+                               hoisted.Storey.hoisted_locals.Remove (hoisted);
+                               hoisted = null;
+                       }
+
                        if (hoisted == null) {
                                hoisted = new HoistedLocalVariable (this, localVariable, GetVariableMangledName (localVariable));
                                localVariable.HoistedVariant = hoisted;
@@ -1543,31 +1549,47 @@ namespace Mono.CSharp {
                        //
 
                        Modifiers modifiers;
+                       TypeDefinition parent = null;
+
                        var src_block = Block.Original.Explicit;
                        if (src_block.HasCapturedVariable || src_block.HasCapturedThis) {
-                               storey = FindBestMethodStorey ();
+                               parent = storey = FindBestMethodStorey ();
 
-                               //
-                               // Remove hoisted this demand when simple instance method is enough
-                               //
-                               if (storey == null && src_block.HasCapturedThis)
-                                       src_block.ParametersBlock.TopBlock.RemoveThisReferenceFromChildrenBlock (src_block);
+                               if (storey == null) {
+                                       var sm = src_block.ParametersBlock.TopBlock.StateMachine;
 
-                               //
-                               // For iterators we can host everything in one class
-                               //
-                               if (storey == null && Block.TopBlock.StateMachine is IteratorStorey)
-                                       storey = block.TopBlock.StateMachine;
+                                       //
+                                       // Remove hoisted this demand when simple instance method is enough
+                                       //
+                                       if (src_block.HasCapturedThis) {
+                                               src_block.ParametersBlock.TopBlock.RemoveThisReferenceFromChildrenBlock (src_block);
+
+                                               //
+                                               // Special case where parent class is used to emit instance method
+                                               // because currect storey is of value type (async host) and we don't
+                                               // want to create another childer storey to host this reference only
+                                               //
+                                               if (sm != null && sm.Kind == MemberKind.Struct)
+                                                       parent = sm.Parent.PartialContainer;
+                                       }
+
+                                       //
+                                       // For iterators we can host everything in one class
+                                       //
+                                       if (sm is IteratorStorey)
+                                               parent = storey = sm;
+                               }
 
                                modifiers = storey != null ? Modifiers.INTERNAL : Modifiers.PRIVATE;
                        } else {
                                if (ec.CurrentAnonymousMethod != null)
-                                       storey = ec.CurrentAnonymousMethod.Storey;
+                                       parent = storey = ec.CurrentAnonymousMethod.Storey;
 
                                modifiers = Modifiers.STATIC | Modifiers.PRIVATE;
                        }
 
-                       var parent = storey != null ? storey : ec.CurrentTypeDefinition.Parent.PartialContainer;
+                       if (parent == null)
+                               parent = ec.CurrentTypeDefinition.Parent.PartialContainer;
 
                        string name = CompilerGeneratedContainer.MakeName (parent != storey ? block_name : null,
                                "m", null, ec.Module.CounterAnonymousMethods++);
@@ -1672,6 +1694,17 @@ namespace Mono.CSharp {
                                }
                        } else {
                                ec.EmitThis ();
+
+                               //
+                               // Special case for value type storey where this is not lifted but
+                               // droped off to parent class
+                               //
+                               for (var b = Block.Parent; b != null; b = b.Parent) {
+                                       if (b.ParametersBlock.StateMachine != null) {
+                                               ec.Emit (OpCodes.Ldfld, b.ParametersBlock.StateMachine.HoistedThis.Field.Spec);
+                                               break;
+                                       }
+                               }
                        }
 
                        var delegate_method = method.Spec;
index fba2704ebd0630361806217b082da9b2034e0f3c..c2885de8e0b1350a76c2a137ffa70c73b0831d1a 100644 (file)
@@ -464,7 +464,7 @@ namespace Mono.CSharp
                Dictionary<TypeSpec, List<Field>> awaiter_fields;
 
                public AsyncTaskStorey (ParametersBlock block, IMemberContext context, AsyncInitializer initializer, TypeSpec type)
-                       : base (block, initializer.Host, context.CurrentMemberDefinition as MemberBase, context.CurrentTypeParameters, "async", MemberKind.Class)
+                       : base (block, initializer.Host, context.CurrentMemberDefinition as MemberBase, context.CurrentTypeParameters, "async", MemberKind.Struct)
                {
                        return_type = type;
                        awaiter_fields = new Dictionary<TypeSpec, List<Field>> ();
@@ -749,16 +749,10 @@ namespace Mono.CSharp
                                InstanceExpression = new CompilerGeneratedThis (ec.CurrentType, Location)
                        };
 
-                       // TODO: CompilerGeneratedThis is enough for structs
-                       var temp_this = new LocalTemporary (CurrentType);
-                       temp_this.EmitAssign (ec, new CompilerGeneratedThis (CurrentType, Location), false, false);
-
                        var args = new Arguments (2);
                        args.Add (new Argument (awaiter, Argument.AType.Ref));
-                       args.Add (new Argument (temp_this, Argument.AType.Ref));
+                       args.Add (new Argument (new CompilerGeneratedThis (CurrentType, Location), Argument.AType.Ref));
                        mg.EmitCall (ec, args);
-
-                       temp_this.Release (ec);
                }
 
                public void EmitInitializer (EmitContext ec)
@@ -788,14 +782,14 @@ namespace Mono.CSharp
                        //
                        // stateMachine.$builder = AsyncTaskMethodBuilder<{task-type}>.Create();
                        //
-                       instance.Emit (ec); // .AddressOf (ec, AddressOp.Store);
+                       instance.AddressOf (ec, AddressOp.Store);
                        ec.Emit (OpCodes.Call, builder_factory);
                        ec.Emit (OpCodes.Stfld, builder_field);
 
                        //
                        // stateMachine.$builder.Start<{storey-type}>(ref stateMachine);
                        //
-                       instance.Emit (ec); //.AddressOf (ec, AddressOp.Store);
+                       instance.AddressOf (ec, AddressOp.Store);
                        ec.Emit (OpCodes.Ldflda, builder_field);
                        if (Task != null)
                                ec.Emit (OpCodes.Dup);
@@ -861,7 +855,7 @@ namespace Mono.CSharp
 
                protected override TypeSpec[] ResolveBaseTypes (out FullNamedExpression base_class)
                {
-                       base_type = Compiler.BuiltinTypes.Object; // ValueType;
+                       base_type = Compiler.BuiltinTypes.ValueType;
                        base_class = null;
 
                        var istate_machine = Module.PredefinedTypes.IAsyncStateMachine;
index 30c199f82e8e378f2e6ed4d5f08aeaf39869e53c..e988178c4343c6bf818d263cd83aee1ba5a83a4b 100644 (file)
@@ -397,10 +397,15 @@ namespace Mono.CSharp
 
                                if (ParsedParameters != null) {
                                        var old_printer = mc.Module.Compiler.Report.SetPrinter (new NullReportPrinter ());
-                                       foreach (var pp in ParsedParameters) {
-                                               pp.Resolve (mc);
+                                       try {
+                                               var context = new DocumentationMemberContext (mc, ParsedName ?? MemberName.Null);
+
+                                               foreach (var pp in ParsedParameters) {
+                                                       pp.Resolve (context);
+                                               }
+                                       } finally {
+                                               mc.Module.Compiler.Report.SetPrinter (old_printer);
                                        }
-                                       mc.Module.Compiler.Report.SetPrinter (old_printer);
                                }
 
                                if (type != null) {
@@ -433,13 +438,15 @@ namespace Mono.CSharp
                                                                        if (m.Kind == MemberKind.Operator && !ParsedOperator.HasValue)
                                                                                continue;
 
+                                                                       var pm_params = pm.Parameters;
+
                                                                        int i;
                                                                        for (i = 0; i < parsed_param_count; ++i) {
                                                                                var pparam = ParsedParameters[i];
 
-                                                                               if (i >= pm.Parameters.Count || pparam == null ||
-                                                                                       pparam.TypeSpec != pm.Parameters.Types[i] ||
-                                                                                       (pparam.Modifier & Parameter.Modifier.RefOutMask) != (pm.Parameters.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask)) {
+                                                                               if (i >= pm_params.Count || pparam == null || pparam.TypeSpec == null ||
+                                                                                       !TypeSpecComparer.Override.IsEqual (pparam.TypeSpec, pm_params.Types[i]) ||
+                                                                                       (pparam.Modifier & Parameter.Modifier.RefOutMask) != (pm_params.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask)) {
 
                                                                                        if (i > parameters_match) {
                                                                                                parameters_match = i;
@@ -459,7 +466,7 @@ namespace Mono.CSharp
                                                                                        continue;
                                                                                }
                                                                        } else {
-                                                                               if (parsed_param_count != pm.Parameters.Count)
+                                                                               if (parsed_param_count != pm_params.Count)
                                                                                        continue;
                                                                        }
                                                                }
@@ -612,6 +619,97 @@ namespace Mono.CSharp
                }
        }
 
+       //
+       // Type lookup of documentation references uses context of type where
+       // the reference is used but type parameters from cref value
+       //
+       sealed class DocumentationMemberContext : IMemberContext
+       {
+               readonly MemberCore host;
+               MemberName contextName;
+
+               public DocumentationMemberContext (MemberCore host, MemberName contextName)
+               {
+                       this.host = host;
+                       this.contextName = contextName;
+               }
+
+               public TypeSpec CurrentType {
+                       get {
+                               return host.CurrentType;
+                       }
+               }
+
+               public TypeParameters CurrentTypeParameters {
+                       get {
+                               return contextName.TypeParameters;
+                       }
+               }
+
+               public MemberCore CurrentMemberDefinition {
+                       get {
+                               return host.CurrentMemberDefinition;
+                       }
+               }
+
+               public bool IsObsolete {
+                       get {
+                               return false;
+                       }
+               }
+
+               public bool IsUnsafe {
+                       get {
+                               return host.IsStatic;
+                       }
+               }
+
+               public bool IsStatic {
+                       get {
+                               return host.IsStatic;
+                       }
+               }
+
+               public ModuleContainer Module {
+                       get {
+                               return host.Module;
+                       }
+               }
+
+               public string GetSignatureForError ()
+               {
+                       return host.GetSignatureForError ();
+               }
+
+               public ExtensionMethodCandidates LookupExtensionMethod (TypeSpec extensionType, string name, int arity)
+               {
+                       return null;
+               }
+
+               public FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
+               {
+                       if (arity == 0) {
+                               var tp = CurrentTypeParameters;
+                               if (tp != null) {
+                                       for (int i = 0; i < tp.Count; ++i) {
+                                               var t = tp[i];
+                                               if (t.Name == name) {
+                                                       t.Type.DeclaredPosition = i;
+                                                       return new TypeParameterExpr (t, loc);
+                                               }
+                                       }
+                               }
+                       }
+
+                       return host.Parent.LookupNamespaceOrType (name, arity, mode, loc);
+               }
+
+               public FullNamedExpression LookupNamespaceAlias (string name)
+               {
+                       throw new NotImplementedException ();
+               }
+       }
+
        class DocumentationParameter
        {
                public readonly Parameter.Modifier Modifier;
index 2146c03e8006aa46b05af57715df0e87147828bc..885326df6423d06a8a812ef829032ad07a88475d 100644 (file)
@@ -2469,8 +2469,8 @@ namespace Mono.CSharp {
                        // variables will be captured anyway we don't need to create
                        // another storey context
                        //
-                       if (ParametersBlock.am_storey is StateMachine) {
-                               return ParametersBlock.am_storey;
+                       if (ParametersBlock.StateMachine is IteratorStorey) {
+                               return ParametersBlock.StateMachine;
                        }
 
                        if (am_storey == null) {
@@ -2487,8 +2487,7 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
-                       // TODO: The is check should go once state machine is fully separated
-                       if (am_storey != null && !(am_storey is StateMachine)) {
+                       if (am_storey != null) {
                                DefineStoreyContainer (ec, am_storey);
                                am_storey.EmitStoreyInstantiation (ec, this);
                        }
@@ -2928,7 +2927,7 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
-                       if (state_machine != null) {
+                       if (state_machine != null && state_machine.OriginalSourceBlock != this) {
                                DefineStoreyContainer (ec, state_machine);
                                state_machine.EmitStoreyInstantiation (ec, this);
                        }
@@ -2938,7 +2937,7 @@ namespace Mono.CSharp {
 
                public void EmitEmbedded (EmitContext ec)
                {
-                       if (state_machine != null) {
+                       if (state_machine != null && state_machine.OriginalSourceBlock != this) {
                                DefineStoreyContainer (ec, state_machine);
                                state_machine.EmitStoreyInstantiation (ec, this);
                        }
@@ -3073,7 +3072,7 @@ namespace Mono.CSharp {
                        var iterator = new Iterator (this, method, host, iterator_type, is_enumerable);
                        var stateMachine = new IteratorStorey (iterator);
 
-                       am_storey = stateMachine;
+                       state_machine = stateMachine;
                        iterator.SetStateMachine (stateMachine);
 
                        var tlb = new ToplevelBlock (host.Compiler, Parameters, Location.Null);
@@ -3119,7 +3118,7 @@ namespace Mono.CSharp {
 
                        var stateMachine = new AsyncTaskStorey (this, context, initializer, returnType);
 
-                       am_storey = stateMachine;
+                       state_machine = stateMachine;
                        initializer.SetStateMachine (stateMachine);
 
                        var b = this is ToplevelBlock ?
index bc55a4be9a7950f53d76ab9398f724b36a395872..ae145805f9210a277fd98ac950cafb6b38cb4806 100644 (file)
@@ -69,7 +69,7 @@
       <sequencepoints>
         <entry il="0x21" row="11" file_ref="1" hidden="false" />
         <entry il="0x22" row="12" file_ref="1" hidden="false" />
-        <entry il="0x8c" row="13" file_ref="1" hidden="false" />
+        <entry il="0x89" row="13" file_ref="1" hidden="false" />
       </sequencepoints>
       <locals />
       <scopes />
       <scopes />
     </method>
     <method token="0x600000c">
-      <sequencepoints />
-      <locals />
-      <scopes />
-    </method>
-    <method token="0x600000d">
       <sequencepoints>
         <entry il="0x21" row="24" file_ref="1" hidden="false" />
         <entry il="0x22" row="25" file_ref="1" hidden="false" />
-        <entry il="0x92" row="26" file_ref="1" hidden="false" />
+        <entry il="0x8f" row="26" file_ref="1" hidden="false" />
       </sequencepoints>
       <locals />
       <scopes />
     </method>
-    <method token="0x600000e">
-      <sequencepoints />
-      <locals />
-      <scopes />
-    </method>
-    <method token="0x600000f">
+    <method token="0x600000d">
       <sequencepoints />
       <locals />
       <scopes />
     </method>
-    <method token="0x6000010">
+    <method token="0x600000e">
       <sequencepoints>
         <entry il="0x21" row="34" file_ref="1" hidden="false" />
         <entry il="0x22" row="35" file_ref="1" hidden="false" />
         <entry il="0x2d" row="36" file_ref="1" hidden="false" />
         <entry il="0x8b" row="37" file_ref="1" hidden="false" />
-        <entry il="0x3b1" row="38" file_ref="1" hidden="false" />
-        <entry il="0x4c1" row="39" file_ref="1" hidden="false" />
+        <entry il="0x3ab" row="38" file_ref="1" hidden="false" />
+        <entry il="0x4b9" row="39" file_ref="1" hidden="false" />
       </sequencepoints>
       <locals />
       <scopes />
     </method>
-    <method token="0x6000011">
-      <sequencepoints />
-      <locals />
-      <scopes />
-    </method>
-    <method token="0x6000012">
+    <method token="0x600000f">
       <sequencepoints />
       <locals />
       <scopes />
     </method>
-    <method token="0x6000013">
+    <method token="0x6000010">
       <sequencepoints>
         <entry il="0x0" row="37" file_ref="1" hidden="false" />
       </sequencepoints>
diff --git a/mcs/tests/test-xml-066-ref.xml b/mcs/tests/test-xml-066-ref.xml
new file mode 100644 (file)
index 0000000..946b754
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>\r
+<doc>\r
+    <assembly>\r
+        <name>test-xml-066</name>\r
+    </assembly>\r
+    <members>\r
+        <member name="M:C.Foo2``1(System.Int32,``0)">\r
+            <seealso cref="M:C.Foo``2(System.Int32,``0,``1[])" /></member>\r
+    </members>\r
+</doc>\r
diff --git a/mcs/tests/test-xml-066.cs b/mcs/tests/test-xml-066.cs
new file mode 100644 (file)
index 0000000..be2256e
--- /dev/null
@@ -0,0 +1,17 @@
+// Compiler options: -doc:xml-066.xml
+
+static class C
+{
+       static void Foo<T, U> (this int a, T t, U[] u)
+       {
+       }
+       
+       /// <seealso cref="Foo{T0,U2}(int,T0,U2[])"/>
+       static void Foo2<T> (this int a, T t)
+       {
+       }
+       
+       public static void Main ()
+       {
+       }
+}
\ No newline at end of file
index ba14025f0db14d9755f6be54f0687035a78e33dc..93c51d7814406e23f1184484dcea01a7d1d27e6a 100644 (file)
         <size>131</size>
       </method>
       <method name="Void TestAsync()" attrs="145">
-        <size>31</size>
+        <size>27</size>
       </method>
       <method name="System.Threading.Tasks.Task RunAsync()" attrs="145">
         <size>48</size>
     </type>
     <type name="Program+&lt;TestAsync&gt;c__async0">
       <method name="Void MoveNext()" attrs="486">
-        <size>215</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
+        <size>212</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
   <test name="test-async-02.cs">
     <type name="C">
       <method name="System.Threading.Tasks.Task TestTask()" attrs="134">
-        <size>44</size>
+        <size>41</size>
       </method>
       <method name="System.Threading.Tasks.Task TestTask2()" attrs="134">
-        <size>44</size>
+        <size>41</size>
       </method>
       <method name="System.Threading.Tasks.Task Call()" attrs="129">
         <size>31</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] TestTaskGeneric()" attrs="134">
-        <size>44</size>
+        <size>41</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] CallGeneric()" attrs="129">
         <size>31</size>
     </type>
     <type name="C+&lt;TestTask&gt;c__async0">
       <method name="Void MoveNext()" attrs="486">
-        <size>165</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
+        <size>162</size>
       </method>
     </type>
     <type name="C+&lt;TestTask2&gt;c__async1">
       <method name="Void MoveNext()" attrs="486">
-        <size>165</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
+        <size>162</size>
       </method>
     </type>
     <type name="C+&lt;TestTaskGeneric&gt;c__async2">
       <method name="Void MoveNext()" attrs="486">
-        <size>172</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
+        <size>169</size>
       </method>
     </type>
     <type name="C+&lt;TestTask&gt;c__async0">
         <size>10</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] Test1()" attrs="145">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] Test2()" attrs="145">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task Test3()" attrs="145">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="Int32 Main()" attrs="150">
         <size>88</size>
     </type>
     <type name="A+&lt;Test1&gt;c__async0">
       <method name="Void MoveNext()" attrs="486">
-        <size>239</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
+        <size>233</size>
       </method>
     </type>
     <type name="A+&lt;Test2&gt;c__async1">
       <method name="Void MoveNext()" attrs="486">
-        <size>164</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
+        <size>161</size>
       </method>
     </type>
     <type name="A+&lt;Test3&gt;c__async2">
       <method name="Void MoveNext()" attrs="486">
-        <size>156</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
+        <size>153</size>
       </method>
     </type>
     <type name="A">
   <test name="test-async-04.cs">
     <type name="C">
       <method name="System.Threading.Tasks.Task`1[System.Int32] TestTaskGeneric()" attrs="134">
-        <size>44</size>
+        <size>41</size>
       </method>
       <method name="Int32 Main()" attrs="150">
         <size>141</size>
     </type>
     <type name="C+&lt;TestTaskGeneric&gt;c__async0">
       <method name="Void MoveNext()" attrs="486">
-        <size>185</size>
-      </method>
-      <method name="Int32 &lt;&gt;m__0()" attrs="131">
-        <size>49</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
+        <size>187</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       </method>
     </type>
+    <type name="C">
+      <method name="Int32 &lt;TestTaskGeneric&gt;m__0()" attrs="129">
+        <size>39</size>
+      </method>
+    </type>
   </test>
   <test name="test-async-05.cs">
     <type name="C">
         <size>7</size>
       </method>
       <method name="System.Threading.Tasks.Task SynchronousCall(Int32)" attrs="134">
-        <size>51</size>
+        <size>49</size>
       </method>
       <method name="System.Threading.Tasks.Task AnotherTask(Int32)" attrs="129">
         <size>15</size>
       <method name="Void MoveNext()" attrs="486">
         <size>49</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       </method>
         <size>482</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Decimal] &lt;Main&gt;m__4(Decimal)" attrs="145">
-        <size>44</size>
+        <size>41</size>
       </method>
       <method name="Void .ctor()" attrs="6278">
         <size>7</size>
     </type>
     <type name="Program+&lt;Main&gt;c__AnonStorey1">
       <method name="Void &lt;&gt;m__0()" attrs="131">
-        <size>38</size>
+        <size>35</size>
       </method>
       <method name="Void &lt;&gt;m__1()" attrs="131">
-        <size>38</size>
+        <size>35</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.String] &lt;&gt;m__2(System.String)" attrs="131">
-        <size>51</size>
+        <size>49</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Decimal] &lt;&gt;m__3(Decimal)" attrs="131">
-        <size>51</size>
+        <size>49</size>
       </method>
       <method name="Void .ctor()" attrs="6278">
         <size>7</size>
     </type>
     <type name="Program+&lt;Main&gt;c__AnonStorey1+&lt;Main&gt;c__async0">
       <method name="Void MoveNext()" attrs="486">
-        <size>215</size>
-      </method>
-      <method name="Void &lt;&gt;m__5()" attrs="131">
-        <size>39</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
+        <size>217</size>
       </method>
     </type>
     <type name="Program+&lt;Main&gt;c__AnonStorey1+&lt;Main&gt;c__async2">
       <method name="Void MoveNext()" attrs="486">
-        <size>215</size>
-      </method>
-      <method name="Void &lt;&gt;m__6()" attrs="131">
-        <size>39</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
+        <size>217</size>
       </method>
     </type>
     <type name="Program+&lt;Main&gt;c__AnonStorey1+&lt;Main&gt;c__async3">
       <method name="Void MoveNext()" attrs="486">
-        <size>195</size>
-      </method>
-      <method name="System.String &lt;&gt;m__7()" attrs="131">
-        <size>52</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
-    </type>
-    <type name="Program+&lt;Main&gt;c__AnonStorey1+&lt;Main&gt;c__async4">
-      <method name="Void MoveNext()" attrs="486">
-        <size>195</size>
-      </method>
-      <method name="Decimal &lt;&gt;m__8()" attrs="131">
-        <size>52</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
-    </type>
-    <type name="Program+&lt;Main&gt;c__async5">
-      <method name="Void MoveNext()" attrs="486">
-        <size>44</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
+        <size>242</size>
       </method>
     </type>
     <type name="Program+&lt;Main&gt;c__AnonStorey1+&lt;Main&gt;c__async0">
         <size>13</size>
       </method>
     </type>
-    <type name="Program+&lt;Main&gt;c__AnonStorey1+&lt;Main&gt;c__async4">
+    <type name="Program+&lt;Main&gt;c__AnonStorey1">
+      <method name="Void &lt;&gt;m__5()" attrs="131">
+        <size>34</size>
+      </method>
+      <method name="Void &lt;&gt;m__6()" attrs="131">
+        <size>34</size>
+      </method>
+    </type>
+    <type name="Program+&lt;Main&gt;c__AnonStorey1+&lt;Main&gt;c__async5">
+      <method name="Void MoveNext()" attrs="486">
+        <size>242</size>
+      </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       </method>
     </type>
-    <type name="Program+&lt;Main&gt;c__async5">
+    <type name="Program+&lt;Main&gt;c__AnonStorey1+&lt;Main&gt;c__async3+&lt;Main&gt;c__AnonStorey4">
+      <method name="System.String &lt;&gt;m__7()" attrs="131">
+        <size>57</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="Program+&lt;Main&gt;c__AnonStorey1+&lt;Main&gt;c__async5+&lt;Main&gt;c__AnonStorey6">
+      <method name="Decimal &lt;&gt;m__8()" attrs="131">
+        <size>57</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="Program+&lt;Main&gt;c__async7">
+      <method name="Void MoveNext()" attrs="486">
+        <size>44</size>
+      </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       </method>
         <size>358</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int16] &lt;Main&gt;m__2(Int16)" attrs="145">
-        <size>44</size>
+        <size>41</size>
       </method>
       <method name="Void .ctor()" attrs="6278">
         <size>7</size>
     </type>
     <type name="Program+&lt;Main&gt;c__AnonStorey1">
       <method name="System.Threading.Tasks.Task`1[System.String] &lt;&gt;m__0(System.String)" attrs="131">
-        <size>51</size>
+        <size>49</size>
       </method>
       <method name="System.Threading.Tasks.Task &lt;&gt;m__1()" attrs="131">
-        <size>44</size>
+        <size>41</size>
       </method>
       <method name="Void &lt;&gt;m__3()" attrs="131">
-        <size>38</size>
+        <size>35</size>
       </method>
       <method name="Void .ctor()" attrs="6278">
         <size>7</size>
     </type>
     <type name="Program+&lt;Main&gt;c__AnonStorey1+&lt;Main&gt;c__async0">
       <method name="Void MoveNext()" attrs="486">
-        <size>182</size>
+        <size>229</size>
       </method>
-      <method name="System.String &lt;&gt;m__4()" attrs="131">
-        <size>52</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
+      <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
+        <size>13</size>
       </method>
     </type>
-    <type name="Program+&lt;Main&gt;c__AnonStorey1+&lt;Main&gt;c__async2">
-      <method name="Void MoveNext()" attrs="486">
-        <size>175</size>
-      </method>
+    <type name="Program+&lt;Main&gt;c__AnonStorey1">
       <method name="Void &lt;&gt;m__5()" attrs="131">
-        <size>39</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
-    </type>
-    <type name="Program+&lt;Main&gt;c__AnonStorey1+&lt;Main&gt;c__async4">
-      <method name="Void MoveNext()" attrs="486">
-        <size>180</size>
+        <size>34</size>
       </method>
       <method name="Void &lt;&gt;m__6()" attrs="131">
-        <size>56</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
+        <size>46</size>
       </method>
     </type>
-    <type name="Program+&lt;Main&gt;c__async3">
+    <type name="Program+&lt;Main&gt;c__AnonStorey1+&lt;Main&gt;c__async3">
       <method name="Void MoveNext()" attrs="486">
-        <size>43</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
+        <size>177</size>
       </method>
-    </type>
-    <type name="Program+&lt;Main&gt;c__AnonStorey1+&lt;Main&gt;c__async0">
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       </method>
     </type>
-    <type name="Program+&lt;Main&gt;c__AnonStorey1+&lt;Main&gt;c__async2">
+    <type name="Program+&lt;Main&gt;c__AnonStorey1+&lt;Main&gt;c__async5">
+      <method name="Void MoveNext()" attrs="486">
+        <size>182</size>
+      </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       </method>
     </type>
-    <type name="Program+&lt;Main&gt;c__AnonStorey1+&lt;Main&gt;c__async4">
-      <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
-        <size>13</size>
+    <type name="Program+&lt;Main&gt;c__AnonStorey1+&lt;Main&gt;c__async0+&lt;Main&gt;c__AnonStorey2">
+      <method name="System.String &lt;&gt;m__4()" attrs="131">
+        <size>57</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
       </method>
     </type>
-    <type name="Program+&lt;Main&gt;c__async3">
+    <type name="Program+&lt;Main&gt;c__async4">
+      <method name="Void MoveNext()" attrs="486">
+        <size>43</size>
+      </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       </method>
         <size>10</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] &lt;Main&gt;m__0(Int32)" attrs="145">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] &lt;Main&gt;m__1(Int32)" attrs="145">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task &lt;Main&gt;m__2(Int32)" attrs="145">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task &lt;Main&gt;m__3(Int32)" attrs="145">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="Int32 &lt;TT&gt;m__4()" attrs="145">
         <size>9</size>
     </type>
     <type name="AsyncTypeInference+&lt;Main&gt;c__async2">
       <method name="Void MoveNext()" attrs="486">
-        <size>199</size>
+        <size>196</size>
       </method>
       <method name="Int32 &lt;&gt;m__5()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="AsyncTypeInference+&lt;Main&gt;c__async5">
       <method name="Void MoveNext()" attrs="486">
-        <size>200</size>
+        <size>197</size>
       </method>
       <method name="Int32 &lt;&gt;m__6()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="AsyncTypeInference+&lt;Main&gt;c__async8">
       <method name="Void MoveNext()" attrs="486">
-        <size>160</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
+        <size>157</size>
       </method>
     </type>
     <type name="AsyncTypeInference+&lt;Main&gt;c__asyncB">
       <method name="Void MoveNext()" attrs="486">
         <size>38</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="AsyncTypeInference+&lt;Main&gt;c__async2">
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>57</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int16] &lt;Main&gt;m__0(System.String)" attrs="145">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="Void .ctor()" attrs="6278">
         <size>7</size>
       <method name="Void MoveNext()" attrs="486">
         <size>38</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       </method>
   <test name="test-async-10.cs">
     <type name="C">
       <method name="System.Threading.Tasks.Task`1[System.String] TestCompositionCall_1()" attrs="145">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.String] TestCompositionCall_2()" attrs="145">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] TestCompositionCall_3()" attrs="145">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] TestCompositionPair_1()" attrs="145">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] TestCompositionPair_2()" attrs="145">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] TestCompositionPair_3()" attrs="145">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] TestCompositionPair_4()" attrs="145">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Byte] M(Byte)" attrs="145">
         <size>44</size>
     </type>
     <type name="C+&lt;TestCompositionCall_1&gt;c__async0">
       <method name="Void MoveNext()" attrs="486">
-        <size>324</size>
+        <size>318</size>
       </method>
       <method name="System.String &lt;&gt;m__1()" attrs="145">
         <size>21</size>
       <method name="System.String &lt;&gt;m__2()" attrs="145">
         <size>13</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="C+&lt;TestCompositionCall_2&gt;c__async1">
       <method name="Void MoveNext()" attrs="486">
-        <size>251</size>
+        <size>246</size>
       </method>
       <method name="System.String &lt;&gt;m__3()" attrs="145">
         <size>13</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="C+&lt;TestCompositionCall_3&gt;c__async2">
       <method name="Void MoveNext()" attrs="486">
-        <size>296</size>
+        <size>288</size>
       </method>
       <method name="Byte &lt;&gt;m__4()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="C+&lt;TestCompositionPair_1&gt;c__async3">
       <method name="Void MoveNext()" attrs="486">
-        <size>202</size>
+        <size>199</size>
       </method>
       <method name="Int32 &lt;&gt;m__5()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="C+&lt;TestCompositionPair_2&gt;c__async4">
       <method name="Void MoveNext()" attrs="486">
-        <size>315</size>
+        <size>309</size>
       </method>
       <method name="Int32 &lt;&gt;m__6()" attrs="145">
         <size>17</size>
       <method name="Int32 &lt;&gt;m__7()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="C+&lt;TestCompositionPair_3&gt;c__async5">
       <method name="Void MoveNext()" attrs="486">
-        <size>203</size>
+        <size>200</size>
       </method>
       <method name="Int32 &lt;&gt;m__8()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="C+&lt;TestCompositionPair_4&gt;c__async6">
       <method name="Void MoveNext()" attrs="486">
-        <size>446</size>
+        <size>435</size>
       </method>
       <method name="Int32 &lt;&gt;m__9()" attrs="145">
         <size>9</size>
       <method name="Int32 &lt;&gt;m__B()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="C+&lt;M&gt;c__AnonStorey7">
       <method name="Byte &lt;&gt;m__0()" attrs="131">
   <test name="test-async-11.cs">
     <type name="G`1[T]">
       <method name="System.Threading.Tasks.Task`1[System.Int32] TestStack_1(T)" attrs="134">
-        <size>51</size>
+        <size>49</size>
       </method>
       <method name="Int32 Call(T, T, T ByRef, Int32)" attrs="129">
         <size>17</size>
         <size>90</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] TestStack_1()" attrs="145">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="Int32 TestCall2[T1,T2,T3,T4,T5,T6,T7](T1, T2, T3, T4, T5, T6, T7)" attrs="129">
         <size>10</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] TestStack_2(UInt64)" attrs="145">
-        <size>44</size>
+        <size>41</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] TestStack_3()" attrs="145">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="Int32 TestCall3(S ByRef, S ByRef, Int32, Int32)" attrs="145">
         <size>26</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] TestStack_4()" attrs="145">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="Int32 TestCall4(E, S, C, Int32)" attrs="145">
         <size>61</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] TestStack_5()" attrs="145">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="Int32 Main()" attrs="150">
         <size>370</size>
     </type>
     <type name="G`1+&lt;TestStack_1&gt;c__async0[T]">
       <method name="Void MoveNext()" attrs="486">
-        <size>260</size>
+        <size>257</size>
       </method>
       <method name="Int32 &lt;&gt;m__0()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="C+&lt;TestStack_1&gt;c__async1">
       <method name="Void MoveNext()" attrs="486">
-        <size>321</size>
+        <size>316</size>
       </method>
       <method name="Int32 &lt;&gt;m__1()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="C+&lt;TestStack_2&gt;c__async2">
       <method name="Void MoveNext()" attrs="486">
-        <size>296</size>
+        <size>291</size>
       </method>
       <method name="Int32 &lt;&gt;m__2()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="C+&lt;TestStack_3&gt;c__async3">
       <method name="Void MoveNext()" attrs="486">
-        <size>461</size>
+        <size>457</size>
       </method>
-      <method name="Int32 &lt;&gt;m__3()" attrs="145">
-        <size>9</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
+      <method name="Int32 &lt;&gt;m__3()" attrs="145">
+        <size>9</size>
       </method>
     </type>
     <type name="C+&lt;TestStack_4&gt;c__async4">
       <method name="Void MoveNext()" attrs="486">
-        <size>317</size>
+        <size>312</size>
       </method>
       <method name="Int32 &lt;&gt;m__4()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="C+&lt;TestStack_5&gt;c__async5">
       <method name="Void MoveNext()" attrs="486">
-        <size>295</size>
-      </method>
-      <method name="Int32 &lt;&gt;m__5()" attrs="131">
-        <size>48</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
+        <size>336</size>
       </method>
     </type>
     <type name="G`1+&lt;TestStack_1&gt;c__async0[T]">
         <size>13</size>
       </method>
     </type>
+    <type name="C+&lt;TestStack_5&gt;c__async5+&lt;TestStack_5&gt;c__AnonStorey6">
+      <method name="Int32 &lt;&gt;m__5()" attrs="131">
+        <size>48</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
   </test>
   <test name="test-async-12.cs">
     <type name="C">
       <method name="System.Threading.Tasks.Task`1[System.Int32] TestNested_1()" attrs="145">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="Int32 Call(Int32, Int32, Int32)" attrs="145">
         <size>53</size>
     </type>
     <type name="C+&lt;TestNested_1&gt;c__async0">
       <method name="Void MoveNext()" attrs="486">
-        <size>433</size>
+        <size>424</size>
       </method>
       <method name="Int32 &lt;&gt;m__0()" attrs="145">
         <size>17</size>
       <method name="Int32 &lt;&gt;m__2()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       </method>
     </type>
     <type name="Tester">
       <method name="System.Threading.Tasks.Task`1[System.Boolean] ArrayAccessTest_1()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] ArrayAccessTest_2()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] ArrayAccessTest_3()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] ArrayAccessTest_4()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] ArrayAccessTest_5()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] ArrayAccessTest_6()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] ArrayAccessTest_7()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] ArrayAccessTest_8()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] ArrayAccessTest_9()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] AssignTest_1()" attrs="129">
-        <size>44</size>
+        <size>41</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] AssignTest_2()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] AssignTest_3()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] BinaryTest_1()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] BinaryTest_2()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] BinaryTest_3()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] BinaryTest_4()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] CallTest_1()" attrs="129">
-        <size>44</size>
+        <size>41</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] CallTest_2()" attrs="129">
-        <size>44</size>
+        <size>41</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] CallTest_3()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] CallTest_4()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] CallTest_5()" attrs="129">
-        <size>44</size>
+        <size>41</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] CastTest_1()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] CastTest_2()" attrs="129">
-        <size>44</size>
+        <size>41</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] CoalescingTest_1()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] CoalescingTest_2()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] ConditionalTest_1()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] ConditionalTest_2()" attrs="129">
-        <size>44</size>
+        <size>41</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] ConditionalTest_3()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] ConditionalTest_4()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] DelegateInvoke_4()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] EventInvoke_1()" attrs="129">
-        <size>44</size>
+        <size>41</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] FieldTest_1()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] IndexerTest_1()" attrs="129">
-        <size>44</size>
+        <size>41</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] IndexerTest_2()" attrs="129">
-        <size>44</size>
+        <size>41</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] IndexerTest_3()" attrs="129">
-        <size>44</size>
+        <size>41</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] IndexerTest_4()" attrs="129">
-        <size>44</size>
+        <size>41</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] IndexerTest_5()" attrs="129">
-        <size>44</size>
+        <size>41</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] IndexerTest_6()" attrs="129">
-        <size>44</size>
+        <size>41</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] IndexerTest_7()" attrs="129">
-        <size>44</size>
+        <size>41</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] IsTest_1()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] IsTest_2()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] LogicalUserOperator_1()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] LogicalUserOperator_2()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] LogicalUserOperator_3()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] NewTest_1()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] NewTest_2()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] NewInitTest_1()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] NewInitTest_2()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] NewArrayInitTest_1()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] NewArrayInitTest_2()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] NewArrayInitTest_3()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] NewArrayInitTest_4()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] NewArrayInitTest_5()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] NewArrayInitTest_6()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] PropertyTest_1()" attrs="129">
-        <size>44</size>
+        <size>41</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] PropertyTest_2()" attrs="129">
-        <size>44</size>
+        <size>41</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] PropertyTest_3()" attrs="129">
-        <size>44</size>
+        <size>41</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] StringConcatTest_1()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] UnaryTest_1()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] UnaryTest_2()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] UnaryTest_3()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] VariableInitializer_1()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="Boolean RunTest(System.Reflection.MethodInfo)" attrs="145">
         <size>247</size>
     </type>
     <type name="Tester+&lt;ArrayAccessTest_1&gt;c__async0">
       <method name="Void MoveNext()" attrs="486">
-        <size>341</size>
+        <size>335</size>
       </method>
       <method name="Boolean &lt;&gt;m__4()" attrs="145">
         <size>9</size>
       <method name="Int32 &lt;&gt;m__5()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;ArrayAccessTest_2&gt;c__async1">
       <method name="Void MoveNext()" attrs="486">
-        <size>754</size>
+        <size>740</size>
       </method>
       <method name="Int32 &lt;&gt;m__6()" attrs="145">
         <size>9</size>
       <method name="Double &lt;&gt;m__9()" attrs="145">
         <size>17</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;ArrayAccessTest_3&gt;c__async2">
       <method name="Void MoveNext()" attrs="486">
-        <size>1117</size>
+        <size>1090</size>
       </method>
       <method name="Int32 &lt;&gt;m__A()" attrs="145">
         <size>9</size>
       <method name="Decimal &lt;&gt;m__E()" attrs="145">
         <size>19</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;ArrayAccessTest_4&gt;c__async3">
       <method name="Void MoveNext()" attrs="486">
-        <size>429</size>
+        <size>421</size>
       </method>
       <method name="Int32 &lt;&gt;m__F()" attrs="145">
         <size>9</size>
       <method name="System.String &lt;&gt;m__10()" attrs="145">
         <size>13</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;ArrayAccessTest_5&gt;c__async4">
       <method name="Void MoveNext()" attrs="486">
-        <size>413</size>
+        <size>428</size>
       </method>
       <method name="Int32 &lt;&gt;m__11()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Int32 &lt;&gt;m__12()" attrs="131">
-        <size>25</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;ArrayAccessTest_6&gt;c__async5">
       <method name="Void MoveNext()" attrs="486">
-        <size>262</size>
+        <size>257</size>
       </method>
       <method name="Int64 &lt;&gt;m__13()" attrs="145">
         <size>10</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;ArrayAccessTest_7&gt;c__async6">
       <method name="Void MoveNext()" attrs="486">
-        <size>392</size>
+        <size>385</size>
       </method>
       <method name="Int32 &lt;&gt;m__14()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;ArrayAccessTest_8&gt;c__async7">
       <method name="Void MoveNext()" attrs="486">
-        <size>678</size>
+        <size>670</size>
       </method>
       <method name="Int32 &lt;&gt;m__15()" attrs="145">
         <size>9</size>
       <method name="Byte &lt;&gt;m__16()" attrs="145">
         <size>10</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;ArrayAccessTest_9&gt;c__async8">
       <method name="Void MoveNext()" attrs="486">
-        <size>1233</size>
+        <size>1209</size>
       </method>
       <method name="Int32 &lt;&gt;m__17()" attrs="145">
         <size>9</size>
       <method name="S &lt;&gt;m__1D()" attrs="145">
         <size>25</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;AssignTest_1&gt;c__async9">
       <method name="Void MoveNext()" attrs="486">
-        <size>226</size>
+        <size>223</size>
       </method>
       <method name="Int32 &lt;&gt;m__1E()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;AssignTest_2&gt;c__asyncA">
       <method name="Void MoveNext()" attrs="486">
-        <size>278</size>
+        <size>273</size>
       </method>
       <method name="Nullable`1 &lt;&gt;m__1F()" attrs="145">
         <size>17</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;AssignTest_3&gt;c__asyncB">
       <method name="Void MoveNext()" attrs="486">
-        <size>370</size>
+        <size>364</size>
       </method>
       <method name="Int32 &lt;&gt;m__20()" attrs="145">
         <size>9</size>
       <method name="Int32 &lt;&gt;m__21()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;BinaryTest_1&gt;c__asyncC">
       <method name="Void MoveNext()" attrs="486">
-        <size>446</size>
+        <size>435</size>
       </method>
       <method name="Int32 &lt;&gt;m__22()" attrs="145">
         <size>17</size>
       <method name="Int32 &lt;&gt;m__24()" attrs="145">
         <size>10</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;BinaryTest_2&gt;c__asyncD">
       <method name="Void MoveNext()" attrs="486">
-        <size>477</size>
-      </method>
-      <method name="Boolean &lt;&gt;m__25()" attrs="131">
-        <size>24</size>
-      </method>
-      <method name="Boolean &lt;&gt;m__26()" attrs="131">
-        <size>24</size>
-      </method>
-      <method name="Boolean &lt;&gt;m__27()" attrs="131">
-        <size>24</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
+        <size>507</size>
       </method>
     </type>
     <type name="Tester+&lt;BinaryTest_3&gt;c__asyncE">
       <method name="Void MoveNext()" attrs="486">
-        <size>1104</size>
+        <size>1082</size>
       </method>
       <method name="Nullable`1 &lt;&gt;m__28()" attrs="145">
         <size>14</size>
       <method name="Nullable`1 &lt;&gt;m__2D()" attrs="145">
         <size>14</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;BinaryTest_4&gt;c__asyncF">
       <method name="Void MoveNext()" attrs="486">
-        <size>825</size>
+        <size>809</size>
       </method>
       <method name="Nullable`1 &lt;&gt;m__2E()" attrs="145">
         <size>14</size>
       <method name="Nullable`1 &lt;&gt;m__31()" attrs="145">
         <size>17</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;ArrayAccessTest_1&gt;c__async0">
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
     </type>
     <type name="Tester">
       <method name="System.Threading.Tasks.Task`1[System.Int32] BinaryTest_5()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
     </type>
     <type name="Tester+&lt;BinaryTest_5&gt;c__async10">
       <method name="Void MoveNext()" attrs="486">
-        <size>304</size>
+        <size>298</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;CallTest_1&gt;c__async11">
       <method name="Void MoveNext()" attrs="486">
-        <size>439</size>
+        <size>430</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Int32 &lt;&gt;m__34()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;CallTest_2&gt;c__async12">
       <method name="Void MoveNext()" attrs="486">
-        <size>272</size>
+        <size>267</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Int32 &lt;&gt;m__35()" attrs="145">
         <size>17</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;CallTest_3&gt;c__async13">
       <method name="Void MoveNext()" attrs="486">
-        <size>242</size>
+        <size>237</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Int32 &lt;&gt;m__36()" attrs="145">
         <size>10</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;CallTest_4&gt;c__async14">
       <method name="Void MoveNext()" attrs="486">
-        <size>239</size>
+        <size>234</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="E &lt;&gt;m__37()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;CallTest_5&gt;c__async15">
       <method name="Void MoveNext()" attrs="486">
-        <size>210</size>
+        <size>250</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       </method>
-      <method name="Int32 &lt;&gt;m__38()" attrs="131">
-        <size>25</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;CastTest_1&gt;c__async16">
       <method name="Void MoveNext()" attrs="486">
-        <size>251</size>
+        <size>246</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       </method>
-      <method name="Decimal &lt;&gt;m__39()" attrs="145">
-        <size>15</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
+      <method name="Decimal &lt;&gt;m__39()" attrs="145">
+        <size>15</size>
       </method>
     </type>
     <type name="Tester+&lt;CastTest_2&gt;c__async17">
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       </method>
-      <method name="Tester &lt;&gt;m__3A()" attrs="131">
-        <size>14</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;CoalescingTest_1&gt;c__async18">
       <method name="Void MoveNext()" attrs="486">
-        <size>366</size>
+        <size>358</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="System.String &lt;&gt;m__3C()" attrs="145">
         <size>13</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;CoalescingTest_2&gt;c__async19">
       <method name="Void MoveNext()" attrs="486">
-        <size>372</size>
+        <size>364</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Byte &lt;&gt;m__3E()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;ConditionalTest_1&gt;c__async1A">
       <method name="Void MoveNext()" attrs="486">
-        <size>200</size>
+        <size>197</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Int32 &lt;&gt;m__3F()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;ConditionalTest_2&gt;c__async1B">
       <method name="Void MoveNext()" attrs="486">
-        <size>335</size>
+        <size>329</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Int32 &lt;&gt;m__41()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;ConditionalTest_3&gt;c__async1C">
       <method name="Void MoveNext()" attrs="486">
-        <size>355</size>
+        <size>347</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Int32 &lt;&gt;m__43()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;ConditionalTest_4&gt;c__async1D">
       <method name="Void MoveNext()" attrs="486">
-        <size>248</size>
+        <size>243</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Int32 &lt;&gt;m__44()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;DelegateInvoke_4&gt;c__async1E">
       <method name="Void MoveNext()" attrs="486">
-        <size>276</size>
+        <size>271</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Int32 &lt;&gt;m__46()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;EventInvoke_1&gt;c__async1F">
       <method name="Void MoveNext()" attrs="486">
-        <size>220</size>
+        <size>260</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       </method>
-      <method name="System.Action &lt;&gt;m__47()" attrs="131">
-        <size>23</size>
-      </method>
-      <method name="Void &lt;&gt;m__48()" attrs="131">
-        <size>9</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;FieldTest_1&gt;c__async20">
       <method name="Void MoveNext()" attrs="486">
-        <size>543</size>
+        <size>535</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Int32 &lt;&gt;m__4A()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;IndexerTest_1&gt;c__async21">
       <method name="Void MoveNext()" attrs="486">
-        <size>228</size>
+        <size>225</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Int32 &lt;&gt;m__4B()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;IndexerTest_2&gt;c__async22">
       <method name="Void MoveNext()" attrs="486">
-        <size>341</size>
+        <size>335</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Int32 &lt;&gt;m__4D()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;IndexerTest_3&gt;c__async23">
       <method name="Void MoveNext()" attrs="486">
-        <size>372</size>
+        <size>402</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       </method>
-      <method name="Int32 &lt;&gt;m__4E()" attrs="131">
-        <size>25</size>
-      </method>
       <method name="Int32 &lt;&gt;m__4F()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;IndexerTest_4&gt;c__async24">
       <method name="Void MoveNext()" attrs="486">
-        <size>407</size>
+        <size>442</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       </method>
-      <method name="Int32 &lt;&gt;m__50()" attrs="131">
-        <size>25</size>
-      </method>
       <method name="Int32 &lt;&gt;m__51()" attrs="145">
         <size>10</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;IndexerTest_5&gt;c__async25">
       <method name="Void MoveNext()" attrs="486">
-        <size>520</size>
+        <size>548</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       </method>
-      <method name="Int32 &lt;&gt;m__52()" attrs="131">
-        <size>25</size>
-      </method>
       <method name="Int32 &lt;&gt;m__53()" attrs="145">
         <size>10</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;IndexerTest_6&gt;c__async26">
       <method name="Void MoveNext()" attrs="486">
-        <size>555</size>
+        <size>544</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Int32 &lt;&gt;m__56()" attrs="145">
         <size>10</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;IndexerTest_7&gt;c__async27">
       <method name="Void MoveNext()" attrs="486">
-        <size>262</size>
+        <size>295</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       </method>
-      <method name="Int32 &lt;&gt;m__57()" attrs="131">
-        <size>25</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;IsTest_1&gt;c__async28">
       <method name="Void MoveNext()" attrs="486">
-        <size>236</size>
+        <size>233</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Tester &lt;&gt;m__58()" attrs="145">
         <size>13</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;IsTest_2&gt;c__async29">
       <method name="Void MoveNext()" attrs="486">
-        <size>238</size>
+        <size>233</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Nullable`1 &lt;&gt;m__59()" attrs="145">
         <size>14</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;LogicalUserOperator_1&gt;c__async2A">
       <method name="Void MoveNext()" attrs="486">
-        <size>399</size>
+        <size>391</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Base &lt;&gt;m__5B()" attrs="145">
         <size>13</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;LogicalUserOperator_2&gt;c__async2B">
       <method name="Void MoveNext()" attrs="486">
-        <size>304</size>
+        <size>299</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Base &lt;&gt;m__5C()" attrs="145">
         <size>13</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;LogicalUserOperator_3&gt;c__async2C">
       <method name="Void MoveNext()" attrs="486">
-        <size>398</size>
+        <size>390</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Base &lt;&gt;m__5E()" attrs="145">
         <size>13</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;NewTest_1&gt;c__async2D">
       <method name="Void MoveNext()" attrs="486">
-        <size>265</size>
+        <size>260</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Int32 &lt;&gt;m__5F()" attrs="145">
         <size>10</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;NewTest_2&gt;c__async2E">
       <method name="Void MoveNext()" attrs="486">
-        <size>356</size>
+        <size>348</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="System.String &lt;&gt;m__61()" attrs="145">
         <size>13</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;NewInitTest_1&gt;c__async2F">
       <method name="Void MoveNext()" attrs="486">
-        <size>1046</size>
+        <size>1026</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Int32 &lt;&gt;m__67()" attrs="145">
         <size>10</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;NewInitTest_2&gt;c__async30">
       <method name="Void MoveNext()" attrs="486">
-        <size>753</size>
+        <size>739</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Int32 &lt;&gt;m__6B()" attrs="145">
         <size>10</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;NewArrayInitTest_1&gt;c__async31">
       <method name="Void MoveNext()" attrs="486">
-        <size>245</size>
+        <size>240</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Int32 &lt;&gt;m__6C()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;NewArrayInitTest_2&gt;c__async32">
       <method name="Void MoveNext()" attrs="486">
-        <size>363</size>
+        <size>355</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Int32 &lt;&gt;m__6E()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;NewArrayInitTest_3&gt;c__async33">
       <method name="Void MoveNext()" attrs="486">
-        <size>249</size>
+        <size>246</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Byte &lt;&gt;m__6F()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;NewArrayInitTest_4&gt;c__async34">
       <method name="Void MoveNext()" attrs="486">
-        <size>433</size>
+        <size>427</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="UInt16 &lt;&gt;m__71()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;NewArrayInitTest_5&gt;c__async35">
       <method name="Void MoveNext()" attrs="486">
-        <size>267</size>
+        <size>264</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="S &lt;&gt;m__72()" attrs="145">
         <size>25</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;NewArrayInitTest_6&gt;c__async36">
       <method name="Void MoveNext()" attrs="486">
-        <size>269</size>
+        <size>266</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Int32 &lt;&gt;m__73()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;PropertyTest_1&gt;c__async37">
       <method name="Void MoveNext()" attrs="486">
-        <size>225</size>
+        <size>222</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Int32 &lt;&gt;m__74()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;PropertyTest_2&gt;c__async38">
       <method name="Void MoveNext()" attrs="486">
-        <size>300</size>
+        <size>295</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Int32 &lt;&gt;m__75()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;PropertyTest_3&gt;c__async39">
       <method name="Void MoveNext()" attrs="486">
-        <size>656</size>
+        <size>645</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Int32 &lt;&gt;m__78()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;StringConcatTest_1&gt;c__async3A">
       <method name="Void MoveNext()" attrs="486">
-        <size>466</size>
+        <size>455</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="System.String &lt;&gt;m__7B()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;UnaryTest_1&gt;c__async3B">
       <method name="Void MoveNext()" attrs="486">
-        <size>238</size>
+        <size>233</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Int32 &lt;&gt;m__7C()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;UnaryTest_2&gt;c__async3C">
       <method name="Void MoveNext()" attrs="486">
-        <size>338</size>
+        <size>354</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       </method>
-      <method name="Nullable`1 &lt;&gt;m__7D()" attrs="131">
-        <size>14</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;UnaryTest_3&gt;c__async3D">
       <method name="Void MoveNext()" attrs="486">
-        <size>378</size>
+        <size>369</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Int32 &lt;&gt;m__7E()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;VariableInitializer_1&gt;c__async3E">
       <method name="Void MoveNext()" attrs="486">
-        <size>354</size>
+        <size>348</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Int32 &lt;&gt;m__80()" attrs="145">
         <size>9</size>
       </method>
+    </type>
+    <type name="Tester">
+      <method name="Tester &lt;CastTest_2&gt;m__3A()" attrs="129">
+        <size>9</size>
+      </method>
+    </type>
+    <type name="Tester+&lt;ArrayAccessTest_5&gt;c__async4+&lt;ArrayAccessTest_5&gt;c__AnonStorey3F">
+      <method name="Int32 &lt;&gt;m__12()" attrs="131">
+        <size>25</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="Tester+&lt;BinaryTest_2&gt;c__asyncD+&lt;BinaryTest_2&gt;c__AnonStorey40">
+      <method name="Boolean &lt;&gt;m__25()" attrs="131">
+        <size>24</size>
+      </method>
+      <method name="Boolean &lt;&gt;m__26()" attrs="131">
+        <size>24</size>
+      </method>
+      <method name="Boolean &lt;&gt;m__27()" attrs="131">
+        <size>24</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="Tester+&lt;CallTest_5&gt;c__async15+&lt;CallTest_5&gt;c__AnonStorey41">
+      <method name="Int32 &lt;&gt;m__38()" attrs="131">
+        <size>25</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="Tester+&lt;EventInvoke_1&gt;c__async1F+&lt;EventInvoke_1&gt;c__AnonStorey42">
+      <method name="System.Action &lt;&gt;m__47()" attrs="131">
+        <size>23</size>
+      </method>
+      <method name="Void &lt;&gt;m__48()" attrs="131">
+        <size>9</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="Tester+&lt;IndexerTest_3&gt;c__async23+&lt;IndexerTest_3&gt;c__AnonStorey43">
+      <method name="Int32 &lt;&gt;m__4E()" attrs="131">
+        <size>25</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="Tester+&lt;IndexerTest_4&gt;c__async24+&lt;IndexerTest_4&gt;c__AnonStorey44">
+      <method name="Int32 &lt;&gt;m__50()" attrs="131">
+        <size>25</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="Tester+&lt;IndexerTest_5&gt;c__async25+&lt;IndexerTest_5&gt;c__AnonStorey45">
+      <method name="Int32 &lt;&gt;m__52()" attrs="131">
+        <size>25</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="Tester+&lt;IndexerTest_7&gt;c__async27+&lt;IndexerTest_7&gt;c__AnonStorey46">
+      <method name="Int32 &lt;&gt;m__57()" attrs="131">
+        <size>25</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="Tester+&lt;UnaryTest_2&gt;c__async3C+&lt;UnaryTest_2&gt;c__AnonStorey47">
+      <method name="Nullable`1 &lt;&gt;m__7D()" attrs="131">
+        <size>14</size>
+      </method>
       <method name="Void .ctor()" attrs="6278">
         <size>7</size>
       </method>
   <test name="test-async-14.cs">
     <type name="C">
       <method name="System.Threading.Tasks.Task`1[System.Int32] TestResult()" attrs="134">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="Int32 Main()" attrs="150">
         <size>214</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] &lt;Main&gt;m__0()" attrs="145">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="Void .ctor()" attrs="6278">
         <size>7</size>
     </type>
     <type name="C+&lt;TestResult&gt;c__async0">
       <method name="Void MoveNext()" attrs="486">
-        <size>216</size>
+        <size>213</size>
       </method>
       <method name="Int32 &lt;&gt;m__1()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="C+&lt;Main&gt;c__async1">
       <method name="Void MoveNext()" attrs="486">
-        <size>226</size>
+        <size>223</size>
       </method>
       <method name="Int32 &lt;&gt;m__2()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="C+&lt;TestResult&gt;c__async0">
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
     </type>
     <type name="Tester">
       <method name="System.Threading.Tasks.Task`1[T] NewInitTestGen[T]()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="Int32 Main()" attrs="150">
         <size>82</size>
     </type>
     <type name="Tester+&lt;NewInitTestGen&gt;c__async0`1[T]">
       <method name="Void MoveNext()" attrs="486">
-        <size>300</size>
+        <size>294</size>
       </method>
       <method name="Int32 &lt;&gt;m__0()" attrs="145">
         <size>10</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       </method>
     </type>
     <type name="Tester">
       <method name="System.Threading.Tasks.Task`1[System.Int32] SwitchTest_1()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] Using_1()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] Foreach_1()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="Boolean RunTest(System.Reflection.MethodInfo)" attrs="145">
         <size>247</size>
     </type>
     <type name="Tester+&lt;SwitchTest_1&gt;c__async0">
       <method name="Void MoveNext()" attrs="486">
-        <size>340</size>
+        <size>335</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="System.String &lt;&gt;m__4()" attrs="145">
         <size>13</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;Using_1&gt;c__async1">
       <method name="Void MoveNext()" attrs="486">
-        <size>780</size>
+        <size>766</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Base &lt;&gt;m__8()" attrs="145">
         <size>13</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;Foreach_1&gt;c__async2">
       <method name="Void MoveNext()" attrs="486">
-        <size>325</size>
+        <size>320</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="System.Collections.Generic.List`1[System.Int32] &lt;&gt;m__9()" attrs="145">
         <size>36</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
   </test>
   <test name="test-async-17.cs">
     <type name="Tester">
       <method name="System.Threading.Tasks.Task`1[System.Int32] TestException_1()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task TestException_2()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task TestException_3()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] TestException_4()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] TestException_5()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] TestException_6()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="Boolean RunTest(System.Reflection.MethodInfo)" attrs="145">
         <size>223</size>
     </type>
     <type name="Tester+&lt;TestException_1&gt;c__async0">
       <method name="Void MoveNext()" attrs="486">
-        <size>201</size>
+        <size>198</size>
       </method>
       <method name="Void &lt;&gt;m__4()" attrs="145">
         <size>7</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;TestException_2&gt;c__async1">
       <method name="Void MoveNext()" attrs="486">
-        <size>193</size>
+        <size>190</size>
       </method>
       <method name="Void &lt;&gt;m__5()" attrs="145">
         <size>7</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;TestException_3&gt;c__async2">
       <method name="Void MoveNext()" attrs="486">
-        <size>200</size>
+        <size>197</size>
       </method>
       <method name="System.Threading.Tasks.Task &lt;&gt;m__6()" attrs="145">
-        <size>37</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
+        <size>33</size>
       </method>
     </type>
     <type name="Tester+&lt;TestException_4&gt;c__async3">
       <method name="Void MoveNext()" attrs="486">
-        <size>234</size>
+        <size>229</size>
       </method>
       <method name="Int32 &lt;&gt;m__8()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;TestException_5&gt;c__async4">
       <method name="Void MoveNext()" attrs="486">
-        <size>283</size>
+        <size>278</size>
       </method>
       <method name="Void &lt;&gt;m__9()" attrs="145">
         <size>7</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;TestException_6&gt;c__async5">
       <method name="Void MoveNext()" attrs="486">
-        <size>237</size>
+        <size>232</size>
       </method>
       <method name="Void &lt;&gt;m__A()" attrs="145">
         <size>7</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;TestException_3&gt;c__async2+&lt;TestException_3&gt;c__async6">
       <method name="Void MoveNext()" attrs="486">
-        <size>192</size>
+        <size>189</size>
       </method>
       <method name="Void &lt;&gt;m__7()" attrs="145">
         <size>7</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;TestException_1&gt;c__async0">
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
   <test name="test-async-18.cs">
     <type name="Tester">
       <method name="System.Threading.Tasks.Task`1[System.Int32] Lambda_1()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] Lambda_2()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] Lambda_3[T]()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="Int32 Main()" attrs="150">
         <size>203</size>
     </type>
     <type name="Tester+&lt;Lambda_1&gt;c__async0">
       <method name="Void MoveNext()" attrs="486">
-        <size>250</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
+        <size>285</size>
       </method>
     </type>
     <type name="Tester+&lt;Lambda_2&gt;c__async1">
       <method name="Void MoveNext()" attrs="486">
-        <size>250</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
+        <size>321</size>
       </method>
     </type>
     <type name="Tester+&lt;Lambda_3&gt;c__async2`1[T]">
       <method name="Void MoveNext()" attrs="486">
-        <size>250</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
+        <size>285</size>
       </method>
     </type>
     <type name="Tester+&lt;Lambda_1&gt;c__async0">
         <size>13</size>
       </method>
     </type>
-    <type name="Tester+&lt;Lambda_1&gt;c__async0">
+    <type name="Tester+&lt;Lambda_1&gt;c__async0+&lt;Lambda_1&gt;c__AnonStorey3">
       <method name="Int32 &lt;&gt;m__0()" attrs="131">
         <size>14</size>
       </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
     </type>
-    <type name="Tester+&lt;Lambda_2&gt;c__async1">
+    <type name="Tester+&lt;Lambda_2&gt;c__async1+&lt;Lambda_2&gt;c__AnonStorey5">
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="Tester+&lt;Lambda_2&gt;c__async1+&lt;Lambda_2&gt;c__AnonStorey4">
       <method name="Int32 &lt;&gt;m__1()" attrs="131">
-        <size>21</size>
+        <size>26</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
       </method>
     </type>
-    <type name="Tester+&lt;Lambda_3&gt;c__async2`1[T]">
+    <type name="Tester+&lt;Lambda_3&gt;c__async2`1+&lt;Lambda_3&gt;c__AnonStorey6`1[T]">
       <method name="Int32 &lt;&gt;m__2()" attrs="131">
         <size>14</size>
       </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
     </type>
   </test>
   <test name="test-async-19.cs">
     <type name="C">
       <method name="Void Test(System.Threading.ManualResetEvent)" attrs="145">
-        <size>38</size>
+        <size>35</size>
       </method>
       <method name="Int32 Main()" attrs="150">
         <size>96</size>
     </type>
     <type name="C+&lt;Test&gt;c__async0">
       <method name="Void MoveNext()" attrs="486">
-        <size>188</size>
+        <size>218</size>
+      </method>
+      <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
+        <size>13</size>
       </method>
+    </type>
+    <type name="C+&lt;Test&gt;c__async0+&lt;Test&gt;c__AnonStorey1">
       <method name="Void &lt;&gt;m__0()" attrs="131">
-        <size>29</size>
+        <size>34</size>
       </method>
       <method name="Void .ctor()" attrs="6278">
         <size>7</size>
       </method>
-      <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
-        <size>13</size>
-      </method>
     </type>
   </test>
   <test name="test-async-20.cs">
     </type>
     <type name="Tester">
       <method name="System.Threading.Tasks.Task`1[System.Boolean] Add_1()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] AssignCompound_1()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] Convert_1()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] Invocation_1()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="Boolean RunTest(System.Reflection.MethodInfo)" attrs="145">
         <size>183</size>
     </type>
     <type name="Tester+&lt;Add_1&gt;c__async0">
       <method name="Void MoveNext()" attrs="486">
-        <size>497</size>
+        <size>492</size>
       </method>
       <method name="Int32 &lt;&gt;m__4()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;AssignCompound_1&gt;c__async1">
       <method name="Void MoveNext()" attrs="486">
-        <size>1237</size>
+        <size>1229</size>
       </method>
       <method name="Int32 &lt;&gt;m__5()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;Convert_1&gt;c__async2">
       <method name="Void MoveNext()" attrs="486">
-        <size>349</size>
+        <size>344</size>
       </method>
       <method name="System.Object &lt;&gt;m__6()" attrs="145">
         <size>13</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;Invocation_1&gt;c__async3">
       <method name="Void MoveNext()" attrs="486">
-        <size>601</size>
+        <size>596</size>
       </method>
       <method name="System.Object &lt;&gt;m__7()" attrs="145">
         <size>13</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;Add_1&gt;c__async0">
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>10</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] Test1()" attrs="145">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="Int32 Main()" attrs="150">
         <size>58</size>
     </type>
     <type name="A+&lt;Test1&gt;c__async0">
       <method name="Void MoveNext()" attrs="486">
-        <size>612</size>
+        <size>604</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
   </test>
   <test name="test-async-22.cs">
     <type name="A">
       <method name="System.Threading.Tasks.Task`1[System.Int32] async()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task async(Int32)" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="Int32 Main()" attrs="150">
         <size>10</size>
       <method name="Void MoveNext()" attrs="486">
         <size>38</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="A+&lt;async&gt;c__async1">
       <method name="Void MoveNext()" attrs="486">
         <size>37</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="A">
       <method name="Void CastTest()" attrs="129">
-        <size>38</size>
+        <size>35</size>
       </method>
     </type>
     <type name="A+&lt;CastTest&gt;c__async2">
       <method name="Void MoveNext()" attrs="486">
-        <size>291</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
+        <size>285</size>
       </method>
     </type>
     <type name="A+&lt;async&gt;c__async0">
     </type>
     <type name="TestPostContext">
       <method name="System.Threading.Tasks.Task`1[System.Int32] Test()" attrs="145">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="Int32 Main()" attrs="150">
         <size>136</size>
     </type>
     <type name="TestPostContext+&lt;Test&gt;c__async0">
       <method name="Void MoveNext()" attrs="486">
-        <size>200</size>
+        <size>197</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       <method name="Int32 &lt;&gt;m__0()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
   </test>
   <test name="test-async-24.cs">
     <type name="Struct">
       <method name="System.Threading.Tasks.Task`1[System.Boolean] AsyncMethod()" attrs="134">
-        <size>49</size>
+        <size>46</size>
       </method>
       <method name="Void .ctor(Object)" attrs="6278">
         <size>9</size>
     </type>
     <type name="Struct+&lt;AsyncMethod&gt;c__async0">
       <method name="Void MoveNext()" attrs="486">
-        <size>278</size>
+        <size>275</size>
       </method>
       <method name="Int32 &lt;&gt;m__0()" attrs="145">
         <size>10</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       </method>
         <size>27</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[TResult] GetTaskResult[TResult](System.Threading.Tasks.Task`1[System.Threading.Tasks.Task`1[TResult]])" attrs="145">
-        <size>44</size>
+        <size>41</size>
       </method>
       <method name="Int32 Main()" attrs="145">
         <size>95</size>
     </type>
     <type name="ConsoleApplication1.Program+&lt;GetTaskResult&gt;c__async0`1[TResult]">
       <method name="Void MoveNext()" attrs="486">
-        <size>172</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
+        <size>169</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
   <test name="test-async-27.cs">
     <type name="MainClass">
       <method name="System.Threading.Tasks.Task AsyncTest()" attrs="145">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="Void Main(System.String[])" attrs="150">
         <size>31</size>
     </type>
     <type name="MainClass+&lt;AsyncTest&gt;c__async0">
       <method name="Void MoveNext()" attrs="486">
-        <size>199</size>
+        <size>196</size>
       </method>
       <method name="Int32 &lt;&gt;m__0()" attrs="145">
         <size>10</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       </method>
   <test name="test-async-28.cs">
     <type name="C">
       <method name="System.Threading.Tasks.Task Test()" attrs="150">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="Void Main()" attrs="150">
         <size>12</size>
     </type>
     <type name="C+&lt;Test&gt;c__async0">
       <method name="Void MoveNext()" attrs="486">
-        <size>285</size>
+        <size>282</size>
       </method>
       <method name="Int32 &lt;&gt;m__0(Int32)" attrs="145">
         <size>10</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       </method>
   <test name="test-async-29.cs">
     <type name="C">
       <method name="System.Threading.Tasks.Task`1[System.Int32] Test()" attrs="145">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="Int32 Main()" attrs="150">
         <size>20</size>
     </type>
     <type name="C+&lt;Test&gt;c__async0">
       <method name="Void MoveNext()" attrs="486">
-        <size>341</size>
+        <size>331</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
   </test>
   <test name="test-async-30.cs">
         <size>6</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.String] &lt;&gt;m__0()" attrs="131">
-        <size>44</size>
+        <size>41</size>
       </method>
       <method name="Void .ctor()" attrs="6278">
         <size>7</size>
         <size>6</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.String] &lt;&gt;m__1()" attrs="131">
-        <size>44</size>
+        <size>41</size>
       </method>
       <method name="Void .ctor()" attrs="6278">
         <size>7</size>
     </type>
     <type name="C+&lt;Test&gt;c__Iterator0+&lt;Test&gt;c__async2">
       <method name="Void MoveNext()" attrs="486">
-        <size>186</size>
+        <size>183</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="C+&lt;Test2&gt;c__Iterator1+&lt;Test2&gt;c__async3">
       <method name="Void MoveNext()" attrs="486">
-        <size>186</size>
+        <size>183</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
   </test>
   <test name="test-cls-00.cs">
         <size>2</size>
       </method>
       <method name="Void Test_1()" attrs="145">
-        <size>31</size>
+        <size>27</size>
       </method>
       <method name="System.Threading.Tasks.Task RunAsync()" attrs="145">
         <size>48</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] Test_2()" attrs="145">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Int32] RunAsync_2()" attrs="145">
         <size>48</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Boolean] Test_3()" attrs="129">
-        <size>37</size>
+        <size>33</size>
       </method>
       <method name="Void &lt;RunAsync&gt;m__0()" attrs="145">
         <size>2</size>
     </type>
     <type name="C+&lt;Test_1&gt;c__async0">
       <method name="Void MoveNext()" attrs="486">
-        <size>159</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
+        <size>156</size>
       </method>
     </type>
     <type name="C+&lt;Test_2&gt;c__async1">
       <method name="Void MoveNext()" attrs="486">
-        <size>166</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
+        <size>163</size>
       </method>
     </type>
     <type name="C+&lt;Test_3&gt;c__async2">
       <method name="Void MoveNext()" attrs="486">
-        <size>1237</size>
+        <size>1229</size>
       </method>
       <method name="Int32 &lt;&gt;m__2()" attrs="145">
         <size>9</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="C+&lt;Test_1&gt;c__async0">
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
index 6d44358bf327b3d0dd2bb9f48073f314af2e8809..30da3733f47470efc1ff848cb3d93013a6f67ffd 100644 (file)
@@ -875,6 +875,7 @@ Mono implementation of ASP.NET, Remoting and Web Services.
 %_prefix/lib/mono/4.0/System.Web.Abstractions.dll
 %_prefix/lib/mono/4.0/System.Web.ApplicationServices.dll
 %_prefix/lib/mono/4.0/System.Web.Routing.dll
+%_prefix/lib/mono/4.0/System.Web.Razor.dll
 %_prefix/lib/mono/4.0/System.Web.Services.dll
 %_prefix/lib/mono/4.0/System.Web.dll
 %_prefix/lib/mono/4.5/Mono.Http.dll
index c77c244fa0e89b7e0e02feb0dd61c7eba09b1d41..5a12af08f87d5383589eb67868e3c2c0f1a1a782 100644 (file)
@@ -4241,10 +4241,7 @@ mono_backtrace (int limit)
 }
 #endif
 
-#ifndef __GNUC__
-/*#define __alignof__(a) sizeof(a)*/
-#define __alignof__(type) G_STRUCT_OFFSET(struct { char c; type x; }, x)
-#endif
+#define abi__alignof__(type) G_STRUCT_OFFSET(struct { char c; type x; }, x)
 
 /*
  * mono_type_size:
@@ -4261,7 +4258,7 @@ mono_type_size (MonoType *t, int *align)
                return 0;
        }
        if (t->byref) {
-               *align = __alignof__(gpointer);
+               *align = abi__alignof__(gpointer);
                return sizeof (gpointer);
        }
 
@@ -4270,23 +4267,23 @@ mono_type_size (MonoType *t, int *align)
                *align = 1;
                return 0;
        case MONO_TYPE_BOOLEAN:
-               *align = __alignof__(gint8);
+               *align = abi__alignof__(gint8);
                return 1;
        case MONO_TYPE_I1:
        case MONO_TYPE_U1:
-               *align = __alignof__(gint8);
+               *align = abi__alignof__(gint8);
                return 1;
        case MONO_TYPE_CHAR:
        case MONO_TYPE_I2:
        case MONO_TYPE_U2:
-               *align = __alignof__(gint16);
+               *align = abi__alignof__(gint16);
                return 2;               
        case MONO_TYPE_I4:
        case MONO_TYPE_U4:
-               *align = __alignof__(gint32);
+               *align = abi__alignof__(gint32);
                return 4;
        case MONO_TYPE_R4:
-               *align = __alignof__(float);
+               *align = abi__alignof__(float);
                return 4;
        case MONO_TYPE_I8:
        case MONO_TYPE_U8:
@@ -4294,21 +4291,21 @@ mono_type_size (MonoType *t, int *align)
                /* xcode 4.3 llvm-gcc bug */
                *align = 4;
 #else          
-               *align = __alignof__(gint64);
+               *align = abi__alignof__(gint64);
 #endif
                return 8;               
        case MONO_TYPE_R8:
-               *align = __alignof__(double);
+               *align = abi__alignof__(double);
                return 8;               
        case MONO_TYPE_I:
        case MONO_TYPE_U:
-               *align = __alignof__(gpointer);
+               *align = abi__alignof__(gpointer);
                return sizeof (gpointer);
        case MONO_TYPE_STRING:
-               *align = __alignof__(gpointer);
+               *align = abi__alignof__(gpointer);
                return sizeof (gpointer);
        case MONO_TYPE_OBJECT:
-               *align = __alignof__(gpointer);
+               *align = abi__alignof__(gpointer);
                return sizeof (gpointer);
        case MONO_TYPE_VALUETYPE: {
                if (t->data.klass->enumtype)
@@ -4321,7 +4318,7 @@ mono_type_size (MonoType *t, int *align)
        case MONO_TYPE_PTR:
        case MONO_TYPE_FNPTR:
        case MONO_TYPE_ARRAY:
-               *align = __alignof__(gpointer);
+               *align = abi__alignof__(gpointer);
                return sizeof (gpointer);
        case MONO_TYPE_TYPEDBYREF:
                return mono_class_value_size (mono_defaults.typed_reference_class, (guint32*)align);
@@ -4337,14 +4334,14 @@ mono_type_size (MonoType *t, int *align)
                        else
                                return mono_class_value_size (mono_class_from_mono_type (t), (guint32*)align);
                } else {
-                       *align = __alignof__(gpointer);
+                       *align = abi__alignof__(gpointer);
                        return sizeof (gpointer);
                }
        }
        case MONO_TYPE_VAR:
        case MONO_TYPE_MVAR:
                /* FIXME: Martin, this is wrong. */
-               *align = __alignof__(gpointer);
+               *align = abi__alignof__(gpointer);
                return sizeof (gpointer);
        default:
                g_error ("mono_type_size: type 0x%02x unknown", t->type);
@@ -4371,7 +4368,7 @@ mono_type_stack_size_internal (MonoType *t, int *align, gboolean allow_open)
        int tmp;
 #if SIZEOF_VOID_P == SIZEOF_REGISTER
        int stack_slot_size = sizeof (gpointer);
-       int stack_slot_align = __alignof__ (gpointer);
+       int stack_slot_align = abi__alignof__ (gpointer);
 #elif SIZEOF_VOID_P < SIZEOF_REGISTER
        int stack_slot_size = SIZEOF_REGISTER;
        int stack_slot_align = SIZEOF_REGISTER;
@@ -4416,14 +4413,14 @@ mono_type_stack_size_internal (MonoType *t, int *align, gboolean allow_open)
                *align = stack_slot_align;
                return stack_slot_size * 3;
        case MONO_TYPE_R4:
-               *align = __alignof__(float);
+               *align = abi__alignof__(float);
                return sizeof (float);          
        case MONO_TYPE_I8:
        case MONO_TYPE_U8:
-               *align = __alignof__(gint64);
+               *align = abi__alignof__(gint64);
                return sizeof (gint64);         
        case MONO_TYPE_R8:
-               *align = __alignof__(double);
+               *align = abi__alignof__(double);
                return sizeof (double);
        case MONO_TYPE_VALUETYPE: {
                guint32 size;
index 7d562d98e23b48c2b1f3e80ddd4cb5f2b1f7930d..4ffd33ffcf714214afc1eedbf35f22ac0476bb90 100644 (file)
@@ -2060,6 +2060,54 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *class, gboolean
                }
        }
 
+       /* Initialize vtable */
+       if (callbacks.get_vtable_trampoline) {
+               // This also covers the AOT case
+               for (i = 0; i < class->vtable_size; ++i) {
+                       vt->vtable [i] = callbacks.get_vtable_trampoline (i);
+               }
+       } else {
+               mono_class_setup_vtable (class);
+
+               for (i = 0; i < class->vtable_size; ++i) {
+                       MonoMethod *cm;
+
+                       if ((cm = class->vtable [i]))
+                               vt->vtable [i] = arch_create_jit_trampoline (cm);
+               }
+       }
+
+       if (ARCH_USE_IMT && imt_table_bytes) {
+               /* Now that the vtable is full, we can actually fill up the IMT */
+               if (callbacks.get_imt_trampoline) {
+                       /* lazy construction of the IMT entries enabled */
+                       for (i = 0; i < MONO_IMT_SIZE; ++i)
+                               interface_offsets [i] = callbacks.get_imt_trampoline (i);
+               } else {
+                       build_imt (class, vt, domain, interface_offsets, NULL);
+               }
+       }
+
+       /*
+        * FIXME: Is it ok to allocate while holding the domain/loader locks ? If not, we can release them, allocate, then
+        * re-acquire them and check if another thread has created the vtable in the meantime.
+        */
+       /* Special case System.MonoType to avoid infinite recursion */
+       if (class != mono_defaults.monotype_class) {
+               /*FIXME check for OOM*/
+               vt->type = mono_type_get_object (domain, &class->byval_arg);
+               if (mono_object_get_class (vt->type) != mono_defaults.monotype_class)
+                       /* This is unregistered in
+                          unregister_vtable_reflection_type() in
+                          domain.c. */
+                       MONO_GC_REGISTER_ROOT_IF_MOVING(vt->type);
+       }
+
+       if (class->contextbound)
+               vt->remote = 1;
+       else
+               vt->remote = 0;
+
        /*  class_vtable_array keeps an array of created vtables
         */
        g_ptr_array_add (domain->class_vtable_array, vt);
@@ -2067,10 +2115,15 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *class, gboolean
         * it it enlarged and when it is stored info.
         */
 
+       /*
+        * Store the vtable in class->runtime_info.
+        * class->runtime_info is accessed without locking, so this do this last after the vtable has been constructed.
+        */
+       mono_memory_barrier ();
+
        old_info = class->runtime_info;
        if (old_info && old_info->max_domain >= domain->domain_id) {
                /* someone already created a large enough runtime info */
-               mono_memory_barrier ();
                old_info->domain_vtables [domain->domain_id] = vt;
        } else {
                int new_size = domain->domain_id;
@@ -2097,32 +2150,14 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *class, gboolean
                class->runtime_info = runtime_info;
        }
 
-       /* Initialize vtable */
-       if (callbacks.get_vtable_trampoline) {
-               // This also covers the AOT case
-               for (i = 0; i < class->vtable_size; ++i) {
-                       vt->vtable [i] = callbacks.get_vtable_trampoline (i);
-               }
-       } else {
-               mono_class_setup_vtable (class);
-
-               for (i = 0; i < class->vtable_size; ++i) {
-                       MonoMethod *cm;
-
-                       if ((cm = class->vtable [i]))
-                               vt->vtable [i] = arch_create_jit_trampoline (cm);
-               }
-       }
-
-       if (ARCH_USE_IMT && imt_table_bytes) {
-               /* Now that the vtable is full, we can actually fill up the IMT */
-               if (callbacks.get_imt_trampoline) {
-                       /* lazy construction of the IMT entries enabled */
-                       for (i = 0; i < MONO_IMT_SIZE; ++i)
-                               interface_offsets [i] = callbacks.get_imt_trampoline (i);
-               } else {
-                       build_imt (class, vt, domain, interface_offsets, NULL);
-               }
+       if (class == mono_defaults.monotype_class) {
+               /*FIXME check for OOM*/
+               vt->type = mono_type_get_object (domain, &class->byval_arg);
+               if (mono_object_get_class (vt->type) != mono_defaults.monotype_class)
+                       /* This is unregistered in
+                          unregister_vtable_reflection_type() in
+                          domain.c. */
+                       MONO_GC_REGISTER_ROOT_IF_MOVING(vt->type);
        }
 
        mono_domain_unlock (domain);
@@ -2137,18 +2172,6 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *class, gboolean
        if (class->parent)
                mono_class_vtable_full (domain, class->parent, raise_on_error);
 
-       /*FIXME check for OOM*/
-       vt->type = mono_type_get_object (domain, &class->byval_arg);
-       if (mono_object_get_class (vt->type) != mono_defaults.monotype_class)
-               /* This is unregistered in
-                  unregister_vtable_reflection_type() in
-                  domain.c. */
-               MONO_GC_REGISTER_ROOT_IF_MOVING(vt->type);
-       if (class->contextbound)
-               vt->remote = 1;
-       else
-               vt->remote = 0;
-
        return vt;
 }
 
index 54adfa9e2a7b9745ed739b62b651bcd55398d661..d255bab435e5cfdb4183819290805614ab2ef5b4 100644 (file)
@@ -89,7 +89,7 @@ collect_bridge_objects (CopyOrMarkObjectFunc copy_func, char *start, char *end,
                        continue;
 
                /* Nursery says the object is dead. */
-               if (!object_is_fin_ready (object))
+               if (!mono_sgen_gc_is_object_ready_for_finalization (object))
                        continue;
 
                if (!mono_sgen_is_bridge_object (object))
@@ -133,7 +133,7 @@ finalize_in_range (CopyOrMarkObjectFunc copy_func, char *start, char *end, int g
                int tag = tagged_object_get_tag (object);
                object = tagged_object_get_object (object);
                if ((char*)object >= start && (char*)object < end && !major_collector.is_object_live ((char*)object)) {
-                       gboolean is_fin_ready = object_is_fin_ready (object);
+                       gboolean is_fin_ready = mono_sgen_gc_is_object_ready_for_finalization (object);
                        MonoObject *copy = object;
                        copy_func ((void**)&copy, queue);
                        if (is_fin_ready) {
@@ -408,7 +408,7 @@ null_link_in_range (CopyOrMarkObjectFunc copy_func, char *start, char *end, int
                        object = DISLINK_OBJECT (link);
 
                        if (object >= start && object < end && !major_collector.is_object_live (object)) {
-                               if (object_is_fin_ready (object)) {
+                               if (mono_sgen_gc_is_object_ready_for_finalization (object)) {
                                        *link = NULL;
                                        DEBUG (5, fprintf (gc_debug_file, "Dislink nullified at %p to GCed object %p\n", link, object));
                                        SGEN_HASH_TABLE_FOREACH_REMOVE (TRUE);
index 295922e320f08c5720819871b3d902d143c6c501..829faf2bd6b0e5ad29d9d91706aa7b1d4247d80c 100644 (file)
@@ -3205,17 +3205,23 @@ report_internal_mem_usage (void)
  */
 
 /*
- * this is valid for the nursery: if the object has been forwarded it means it's
- * still refrenced from a root. If it is pinned it's still alive as well.
+ * If the object has been forwarded it means it's still referenced from a root. 
+ * If it is pinned it's still alive as well.
+ * A LOS object is only alive if we have pinned it.
  * Return TRUE if @obj is ready to be finalized.
  */
-#define object_is_fin_ready(obj) (!object_is_pinned (obj) && !object_is_forwarded (obj))
-
+static inline gboolean
+mono_sgen_nursery_is_object_alive (void *object)
+{
+       if (SGEN_OBJECT_IS_PINNED (object) || SGEN_OBJECT_IS_FORWARDED (object))
+               return TRUE;
+       return major_collector.is_object_live (object);
+}
 
 gboolean
 mono_sgen_gc_is_object_ready_for_finalization (void *object)
 {
-       return !major_collector.is_object_live (object) && object_is_fin_ready (object);
+       return !mono_sgen_nursery_is_object_alive (object);
 }
 
 static gboolean
@@ -3250,7 +3256,8 @@ object_is_reachable (char *object, char *start, char *end)
        /*This happens for non nursery objects during minor collections. We just treat all objects as alive.*/
        if (object < start || object >= end)
                return TRUE;
-       return !object_is_fin_ready (object) || major_collector.is_object_live (object);
+
+       return mono_sgen_nursery_is_object_alive (object);
 }
 
 #include "sgen-fin-weak-hash.c"
@@ -3260,6 +3267,7 @@ mono_sgen_object_is_live (void *obj)
 {
        if (ptr_in_nursery (obj))
                return object_is_pinned (obj);
+       /* FIXME This is semantically wrong! All tenured object are considered alive during a nursery collection. */
        if (current_collection_generation == GENERATION_NURSERY)
                return FALSE;
        return major_collector.is_object_live (obj);
index cf1cf6f8087bb6f89b71a7ecb5645d4a352f8b08..d8fb3f041a4ff99b5bf1abcbc1190191d8068292 100644 (file)
@@ -109,12 +109,17 @@ struct _Fragment {
        Fragment *next_in_order; /* We use a different entry for all active fragments so we can avoid SMR. */
 };
 
+typedef struct {
+       Fragment *alloc_head; /* List head to be used when allocating memory. Walk with fragment_next. */
+       Fragment *region_head; /* List head of the region used by this allocator. Walk with next_in_order. */
+} FragmentAllocator;
+
 /* Enable it so nursery allocation diagnostic data is collected */
 //#define NALLOC_DEBUG 1
 
 /* fragments that are free and ready to be used for allocation */
-static Fragment *nursery_fragments = NULL;
-static Fragment *nursery_fragments_start = NULL;
+static FragmentAllocator nursery_allocator;
+
 /* freeelist of fragment structures */
 static Fragment *fragment_freelist = NULL;
 
@@ -301,7 +306,7 @@ alloc_fragment (void)
 }
 
 static void
-add_fragment (char *start, char *end)
+add_fragment (FragmentAllocator *allocator, char *start, char *end)
 {
        Fragment *fragment;
 
@@ -309,15 +314,15 @@ add_fragment (char *start, char *end)
        fragment->fragment_start = start;
        fragment->fragment_next = start;
        fragment->fragment_end = end;
-       fragment->next_in_order = fragment->next = unmask (nursery_fragments);
+       fragment->next_in_order = fragment->next = unmask (allocator->region_head);
 
-       nursery_fragments_start = nursery_fragments = fragment;
+       allocator->region_head = allocator->alloc_head = fragment;
 }
 
 static void
-release_fragment_list (Fragment **root)
+release_fragment_list (FragmentAllocator *allocator)
 {
-       Fragment *last = *root;
+       Fragment *last = allocator->region_head;
        if (!last)
                return;
 
@@ -325,21 +330,25 @@ release_fragment_list (Fragment **root)
        for (; last->next_in_order; last = last->next_in_order) ;
 
        last->next_in_order = fragment_freelist;
-       fragment_freelist = *root;
-       *root = NULL;
+       fragment_freelist = allocator->region_head;
+       allocator->alloc_head = allocator->region_head = NULL;
 }
 
 static Fragment**
-find_previous_pointer_fragment (Fragment *frag)
+find_previous_pointer_fragment (FragmentAllocator *allocator, Fragment *frag)
 {
        Fragment **prev;
        Fragment *cur, *next;
+#ifdef NALLOC_DEBUG
        int count = 0;
+#endif
 
 try_again:
-       prev = &nursery_fragments;
+       prev = &allocator->alloc_head;
+#ifdef NALLOC_DEBUG
        if (count++ > 5)
                printf ("retry count for fppf is %d\n", count);
+#endif
 
        cur = unmask (*prev);
 
@@ -387,7 +396,7 @@ claim_remaining_size (Fragment *frag, char *alloc_end)
 }
 
 static void*
-alloc_from_fragment (Fragment *frag, size_t size)
+alloc_from_fragment (FragmentAllocator *allocator, Fragment *frag, size_t size)
 {
        char *p = frag->fragment_next;
        char *end = p + size;
@@ -418,7 +427,7 @@ alloc_from_fragment (Fragment *frag, size_t size)
 #endif
                }
 
-               prev_ptr = find_previous_pointer_fragment (frag);
+               prev_ptr = find_previous_pointer_fragment (allocator, frag);
 
                /*Use Michaels linked list remove*/
 
@@ -442,7 +451,7 @@ alloc_from_fragment (Fragment *frag, size_t size)
 
                        /* Fail if the previous node was deleted and its CAS wins */
                        if (InterlockedCompareExchangePointer ((volatile gpointer*)prev_ptr, next, frag) != frag) {
-                               prev_ptr = find_previous_pointer_fragment (frag);
+                               prev_ptr = find_previous_pointer_fragment (allocator, frag);
                                continue;
                        }
                        break;
@@ -457,22 +466,28 @@ mono_sgen_clear_current_nursery_fragment (void)
 {
 }
 
+static void
+clear_allocator_fragments (FragmentAllocator *allocator)
+{
+       Fragment *frag;
+
+       for (frag = unmask (allocator->alloc_head); frag; frag = unmask (frag->next)) {
+               DEBUG (4, fprintf (gc_debug_file, "Clear nursery frag %p-%p\n", frag->fragment_next, frag->fragment_end));
+               mono_sgen_clear_range (frag->fragment_next, frag->fragment_end);
+#ifdef NALLOC_DEBUG
+               add_alloc_record (frag->fragment_next, frag->fragment_end - frag->fragment_next, CLEAR_NURSERY_FRAGS);
+#endif
+       }       
+}
+
 /* Clear all remaining nursery fragments */
 void
 mono_sgen_clear_nursery_fragments (void)
 {
-       Fragment *frag;
-
        if (mono_sgen_get_nursery_clear_policy () == CLEAR_AT_TLAB_CREATION) {
                mono_sgen_clear_current_nursery_fragment ();
 
-               for (frag = unmask (nursery_fragments); frag; frag = unmask (frag->next)) {
-                       DEBUG (4, fprintf (gc_debug_file, "Clear nursery frag %p-%p\n", frag->fragment_next, frag->fragment_end));
-                       mono_sgen_clear_range (frag->fragment_next, frag->fragment_end);
-#ifdef NALLOC_DEBUG
-                       add_alloc_record (frag->fragment_next, frag->fragment_end - frag->fragment_next, CLEAR_NURSERY_FRAGS);
-#endif
-               }
+               clear_allocator_fragments (&nursery_allocator);
        }
 }
 
@@ -500,19 +515,7 @@ mono_sgen_clear_range (char *start, char *end)
 void
 mono_sgen_nursery_allocator_prepare_for_pinning (void)
 {
-       Fragment *frag;
-
-       /*
-        * The code below starts the search from an entry in scan_starts, which might point into a nursery
-        * fragment containing random data. Clearing the nursery fragments takes a lot of time, and searching
-        * though them too, so lay arrays at each location inside a fragment where a search can start:
-        * - scan_locations[i]
-        * - start_nursery
-        * - the start of each fragment (the last_obj + last_obj case)
-        * The third encompasses the first two, since scan_locations [i] can't point inside a nursery fragment.
-        */
-       for (frag = unmask (nursery_fragments); frag; frag = unmask (frag->next))
-               mono_sgen_clear_range (frag->fragment_next, frag->fragment_end);
+       clear_allocator_fragments (&nursery_allocator);
 }
 
 static mword fragment_total = 0;
@@ -522,7 +525,7 @@ static mword fragment_total = 0;
  * allocation.
  */
 static void
-add_nursery_frag (size_t frag_size, char* frag_start, char* frag_end)
+add_nursery_frag (FragmentAllocator *allocator, size_t frag_size, char* frag_start, char* frag_end)
 {
        DEBUG (4, fprintf (gc_debug_file, "Found empty fragment: %p-%p, size: %zd\n", frag_start, frag_end, frag_size));
        binary_protocol_empty (frag_start, frag_size);
@@ -537,7 +540,7 @@ add_nursery_frag (size_t frag_size, char* frag_start, char* frag_end)
                printf ("\tfragment [%p %p] size %zd\n", frag_start, frag_end, frag_size);
                */
 #endif
-               add_fragment (frag_start, frag_end);
+               add_fragment (allocator, frag_start, frag_end);
                fragment_total += frag_size;
        } else {
                /* Clear unused fragments, pinning depends on this */
@@ -557,8 +560,7 @@ mono_sgen_build_nursery_fragments (GCMemSection *nursery_section, void **start,
        reset_alloc_records ();
 #endif
 
-       release_fragment_list (&nursery_fragments_start);
-       nursery_fragments = NULL;
+       release_fragment_list (&nursery_allocator);
 
        frag_start = mono_sgen_nursery_start;
        fragment_total = 0;
@@ -571,7 +573,7 @@ mono_sgen_build_nursery_fragments (GCMemSection *nursery_section, void **start,
                mono_sgen_set_nursery_scan_start (frag_end);
                frag_size = frag_end - frag_start;
                if (frag_size)
-                       add_nursery_frag (frag_size, frag_start, frag_end);
+                       add_nursery_frag (&nursery_allocator, frag_size, frag_start, frag_end);
                frag_size = SGEN_ALIGN_UP (mono_sgen_safe_object_get_size ((MonoObject*)start [i]));
 #ifdef NALLOC_DEBUG
                add_alloc_record (start [i], frag_size, PINNING);
@@ -582,8 +584,8 @@ mono_sgen_build_nursery_fragments (GCMemSection *nursery_section, void **start,
        frag_end = mono_sgen_nursery_end;
        frag_size = frag_end - frag_start;
        if (frag_size)
-               add_nursery_frag (frag_size, frag_start, frag_end);
-       if (!unmask (nursery_fragments)) {
+               add_nursery_frag (&nursery_allocator, frag_size, frag_start, frag_end);
+       if (!unmask (nursery_allocator.alloc_head)) {
                DEBUG (1, fprintf (gc_debug_file, "Nursery fully pinned (%d)\n", num_entries));
                for (i = 0; i < num_entries; ++i) {
                        DEBUG (3, fprintf (gc_debug_file, "Bastard pinning obj %p (%s), size: %d\n", start [i], mono_sgen_safe_name (start [i]), mono_sgen_safe_object_get_size (start [i])));
@@ -598,7 +600,7 @@ mono_sgen_nursery_alloc_get_upper_alloc_bound (void)
        char *p = NULL;
        Fragment *frag;
 
-       for (frag = unmask (nursery_fragments); frag; frag = unmask (frag->next))
+       for (frag = unmask (nursery_allocator.alloc_head); frag; frag = unmask (frag->next))
                p = MAX (p, frag->fragment_next);
 
        return MAX (p, nursery_last_pinned_end);
@@ -617,7 +619,7 @@ mono_sgen_can_alloc_size (size_t size)
        Fragment *frag;
        size = SGEN_ALIGN_UP (size);
 
-       for (frag = unmask (nursery_fragments); frag; frag = unmask (frag->next)) {
+       for (frag = unmask (nursery_allocator.alloc_head); frag; frag = unmask (frag->next)) {
                if ((frag->fragment_end - frag->fragment_next) >= size)
                        return TRUE;
        }
@@ -638,11 +640,11 @@ mono_sgen_nursery_alloc (size_t size)
 #endif
 
 restart:
-       for (frag = unmask (nursery_fragments); frag; frag = unmask (frag->next)) {
+       for (frag = unmask (nursery_allocator.alloc_head); frag; frag = unmask (frag->next)) {
                HEAVY_STAT (InterlockedIncrement (&stat_alloc_iterations));
 
                if (size <= (frag->fragment_end - frag->fragment_next)) {
-                       void *p = alloc_from_fragment (frag, size);
+                       void *p = alloc_from_fragment (&nursery_allocator, frag, size);
                        if (!p) {
                                HEAVY_STAT (InterlockedIncrement (&stat_alloc_retries));
                                goto restart;
@@ -671,7 +673,7 @@ restart:
        InterlockedIncrement (&alloc_count);
 #endif
 
-       for (frag = unmask (nursery_fragments); frag; frag = unmask (frag->next)) {
+       for (frag = unmask (nursery_allocator.alloc_head); frag; frag = unmask (frag->next)) {
                int frag_size = frag->fragment_end - frag->fragment_next;
 
                HEAVY_STAT (InterlockedIncrement (&stat_alloc_range_iterations));
@@ -680,7 +682,7 @@ restart:
                        void *p;
                        *out_alloc_size = desired_size;
 
-                       p = alloc_from_fragment (frag, desired_size);
+                       p = alloc_from_fragment (&nursery_allocator, frag, desired_size);
                        if (!p) {
                                HEAVY_STAT (InterlockedIncrement (&stat_alloc_range_retries));
                                goto restart;
@@ -708,7 +710,7 @@ restart:
                *out_alloc_size = frag_size;
 
                mono_memory_barrier ();
-               p = alloc_from_fragment (min_frag, frag_size);
+               p = alloc_from_fragment (&nursery_allocator, min_frag, frag_size);
 
                /*XXX restarting here is quite dubious given this is already second chance allocation. */
                if (!p) {
@@ -759,7 +761,7 @@ void
 mono_sgen_nursery_allocator_set_nursery_bounds (char *start, char *end)
 {
        /* Setup the single first large fragment */
-       add_fragment (start, end);
+       add_fragment (&nursery_allocator, start, end);
        mono_sgen_nursery_start = start;
        mono_sgen_nursery_end = end;
 }
index 67dbf058853b68dd40fd0458eb2095e0db397551..20daf88d352fcad687a2ed706c3574c49f090c37 100644 (file)
@@ -6194,7 +6194,7 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf)
                 * resumed.
                 */
                if (tls->pending_invoke)
-                       NOT_IMPLEMENTED;
+                       return ERR_NOT_SUSPENDED;
                tls->pending_invoke = g_new0 (InvokeData, 1);
                tls->pending_invoke->id = id;
                tls->pending_invoke->flags = flags;
index 40106503986ffe01b8b3c732d968b9b74b247275..b23fd4f6d64f9e0f5f3eaba8d4613f837e249f96 100644 (file)
@@ -1455,7 +1455,7 @@ mono_main (int argc, char* argv[])
                        char *build = mono_get_runtime_build_info ();
                        char *gc_descr;
 
-                       g_print ("Mono JIT compiler version %s\nCopyright (C) 2002-2011 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com\n", build);
+                       g_print ("Mono JIT compiler version %s\nCopyright (C) 2002-2012 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com\n", build);
                        g_free (build);
                        g_print (info);
                        gc_descr = mono_gc_get_description ();
index d710537588dff8e1619671ee57757fddb6f03527..8cda0dc806994a30ea8e52089e5b8874794bc541 100644 (file)
@@ -3276,7 +3276,7 @@ mono_test_marshal_ccw_itest (MonoComObject *pUnk)
 /* thunks.cs:TestStruct */
 typedef struct _TestStruct {
        int A;
-       double B ALIGN(8);  /* align according to  mono's struct layout */
+       double B;
 } TestStruct;
 
 /* Searches for mono symbols in all loaded modules */