Merge pull request #249 from pcc/xgetinputfocus
authorAndreia Gaita <shana.ufie@gmail.com>
Tue, 3 Apr 2012 01:11:13 +0000 (18:11 -0700)
committerAndreia Gaita <shana.ufie@gmail.com>
Tue, 3 Apr 2012 01:11:13 +0000 (18:11 -0700)
If the window manager does not support _NET_ACTIVE_WINDOW, fall back to ...

567 files changed:
.gitmodules [new file with mode: 0644]
LICENSE
Makefile.am
configure.in
eglib/src/gstr.c
eglib/test/string-util.c
external/Newtonsoft.Json [new submodule]
external/aspnetwebstack [new submodule]
man/mcs.1
mcs/.gitignore
mcs/class/Makefile
mcs/class/Managed.Windows.Forms/Test/System.Windows.Forms/DataGridViewRowCollectionTest.cs
mcs/class/Microsoft.CSharp/Microsoft.CSharp.RuntimeBinder/DynamicContext.cs
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/System.Core/Test/System.Security.Cryptography/SHA1CngTest.cs
mcs/class/System.Core/Test/System.Security.Cryptography/SHA256CngTest.cs
mcs/class/System.Core/Test/System.Security.Cryptography/SHA256CryptoServiceProviderTest.cs
mcs/class/System.Core/Test/System.Security.Cryptography/SHA384CngTest.cs
mcs/class/System.Core/Test/System.Security.Cryptography/SHA384CryptoServiceProviderTest.cs
mcs/class/System.Core/Test/System.Security.Cryptography/SHA512CngTest.cs
mcs/class/System.Core/Test/System.Security.Cryptography/SHA512CryptoServiceProviderTest.cs
mcs/class/System.Data.Services.Client/.gitignore [new file with mode: 0644]
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.Json/Test/System.Json/JsonValueTest.cs
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.Runtime.Serialization/Test/System.Runtime.Serialization/Bug2843Test.cs
mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/JsonReaderWriterFactory.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/GlobalAssemblyInfo.cs [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/System.Net/EndPointManager.cs
mcs/class/System/System.Net/UploadProgressChangedEventArgs.cs
mcs/class/System/System.Net/WebClient.cs
mcs/class/System/System.Security.Cryptography.X509Certificates/X509Certificate2Collection.cs
mcs/class/System/Test/System.ComponentModel/DateTimeOffsetConverterTests.cs
mcs/class/System/Test/System.Configuration/ApplicationSettingsBaseTest.cs
mcs/class/System/Test/System.Net/DnsTest.cs
mcs/class/System/Test/System.Security.Cryptography.X509Certificates/X509Certificate2CollectionTest.cs
mcs/class/System/mobile_System.dll.sources
mcs/class/WindowsBase/System.ComponentModel/DependencyPropertyDescriptor.cs
mcs/class/WindowsBase/System.IO.Packaging/Package.cs
mcs/class/WindowsBase/System.IO.Packaging/PackageDigitalSignatureManager.cs
mcs/class/WindowsBase/System.Security.Permissions/MediaPermission.cs
mcs/class/WindowsBase/System.Security.Permissions/MediaPermissionAttribute.cs
mcs/class/WindowsBase/System.Windows.Input/Key.cs
mcs/class/WindowsBase/System.Windows.Input/KeyConverter.cs
mcs/class/WindowsBase/System.Windows.Input/ModifierKeysConverter.cs
mcs/class/WindowsBase/System.Windows.Markup/InternalTypeHelper.cs
mcs/class/WindowsBase/System.Windows.Media/DisableDpiAwarenessAttribute.cs
mcs/class/WindowsBase/System.Windows.Media/MatrixConverter.cs
mcs/class/WindowsBase/System.Windows.Threading/Dispatcher.cs
mcs/class/WindowsBase/System.Windows.Threading/DispatcherSynchronizationContext.cs
mcs/class/WindowsBase/System.Windows/DependencyObjectType.cs
mcs/class/WindowsBase/System.Windows/DependencyProperty.cs
mcs/class/WindowsBase/System.Windows/Point.cs
mcs/class/WindowsBase/System.Windows/Rect.cs
mcs/class/WindowsBase/System.Windows/Size.cs
mcs/class/corlib/Makefile
mcs/class/corlib/Microsoft.Win32/RegistryKey.cs
mcs/class/corlib/Mono.Security.Cryptography/PKCS1.cs
mcs/class/corlib/System.IO.IsolatedStorage/IsolatedStorageFile.cs
mcs/class/corlib/System.IO/LogcatTextWriter.cs
mcs/class/corlib/System.Security.Cryptography/PasswordDeriveBytes.cs
mcs/class/corlib/System.Security.Cryptography/RijndaelManaged.cs
mcs/class/corlib/System.Security.Cryptography/RijndaelManagedTransform.cs
mcs/class/corlib/Test/System.Collections.Generic/ComparerTest.cs
mcs/class/corlib/Test/System.IO.IsolatedStorage/IsolatedStorageFileTest.cs
mcs/class/corlib/Test/System.Security.Cryptography/CryptoStreamTest.cs
mcs/class/corlib/Test/System.Security.Cryptography/DSACryptoServiceProviderTest.cs
mcs/class/corlib/Test/System.Security.Cryptography/DSASignatureDeformatterTest.cs
mcs/class/corlib/Test/System.Security.Cryptography/DSASignatureFormatterTest.cs
mcs/class/corlib/Test/System.Security.Cryptography/HMACMD5Test.cs
mcs/class/corlib/Test/System.Security.Cryptography/HMACRIPEMD160Test.cs
mcs/class/corlib/Test/System.Security.Cryptography/HMACSHA1Test.cs
mcs/class/corlib/Test/System.Security.Cryptography/HMACSHA256Test.cs
mcs/class/corlib/Test/System.Security.Cryptography/HMACSHA384Test.cs
mcs/class/corlib/Test/System.Security.Cryptography/HMACSHA512Test.cs
mcs/class/corlib/Test/System.Security.Cryptography/HashAlgorithmTest.cs
mcs/class/corlib/Test/System.Security.Cryptography/KeyedHashAlgorithmTest.cs
mcs/class/corlib/Test/System.Security.Cryptography/PKCS1MaskGenerationMethodTest.cs
mcs/class/corlib/Test/System.Security.Cryptography/PasswordDeriveBytesTest.cs
mcs/class/corlib/Test/System.Security.Cryptography/RNGCryptoServiceProviderTest.cs
mcs/class/corlib/Test/System.Security.Cryptography/RSACryptoServiceProviderTest.cs
mcs/class/corlib/Test/System.Security.Cryptography/RijndaelManagedTest.cs
mcs/class/corlib/Test/System.Security.Cryptography/SHA1CryptoServiceProviderTest.cs
mcs/class/corlib/Test/System.Security.Cryptography/SHA1Test.cs
mcs/class/corlib/Test/System.Security.Cryptography/SHA256ManagedTest.cs
mcs/class/corlib/Test/System.Security.Cryptography/SHA256Test.cs
mcs/class/corlib/Test/System.Security.Cryptography/SHA384ManagedTest.cs
mcs/class/corlib/Test/System.Security.Cryptography/SHA384Test.cs
mcs/class/corlib/Test/System.Security.Cryptography/SHA512ManagedTest.cs
mcs/class/corlib/Test/System.Security.Cryptography/SHA512Test.cs
mcs/errors/cs0023-18.cs [new file with mode: 0644]
mcs/errors/cs0219-6.cs [new file with mode: 0644]
mcs/errors/cs2021-2.cs [new file with mode: 0644]
mcs/errors/cs2021.cs [new file with mode: 0644]
mcs/errors/cs4005-2.cs [new file with mode: 0644]
mcs/mcs/anonymous.cs
mcs/mcs/assign.cs
mcs/mcs/async.cs
mcs/mcs/cfold.cs
mcs/mcs/codegen.cs
mcs/mcs/const.cs
mcs/mcs/constant.cs
mcs/mcs/convert.cs
mcs/mcs/doc.cs
mcs/mcs/driver.cs
mcs/mcs/ecore.cs
mcs/mcs/expression.cs
mcs/mcs/iterators.cs
mcs/mcs/lambda.cs
mcs/mcs/literal.cs
mcs/mcs/method.cs
mcs/mcs/parameter.cs
mcs/mcs/statement.cs
mcs/tests/dtest-error-04.cs [new file with mode: 0644]
mcs/tests/gtest-iter-21.cs [new file with mode: 0644]
mcs/tests/gtest-iter-22.cs [new file with mode: 0644]
mcs/tests/test-129.cs
mcs/tests/test-anon-170.cs [new file with mode: 0644]
mcs/tests/test-async-29.cs [new file with mode: 0644]
mcs/tests/test-async-30.cs [new file with mode: 0644]
mcs/tests/test-async-31.cs [new file with mode: 0644]
mcs/tests/test-debug-13-ref.xml
mcs/tests/test-debug-14-ref.xml
mcs/tests/test-debug-19-ref.xml
mcs/tests/test-debug-21-ref.xml [new file with mode: 0644]
mcs/tests/test-debug-21.cs [new file with mode: 0644]
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
mcs/tools/Makefile
mcs/tools/mdoc/Makefile
mcs/tools/mdoc/Resources/monodoc-ecma.xsd
mcs/tools/mkbundle/mkbundle.cs
mcs/tools/mod/Makefile
mcs/tools/monodoc/Monodoc/ecma-provider.cs
mcs/tools/monodoc/Resources/mdoc-html-utils.xsl
mono-core.spec.in
mono/arch/s390x/s390x-codegen.h
mono/dis/Makefile.am
mono/io-layer/wthreads.c
mono/metadata/Makefile.am
mono/metadata/class.c
mono/metadata/cominterop.c
mono/metadata/gc.c
mono/metadata/loader.c
mono/metadata/marshal.c
mono/metadata/metadata.c
mono/metadata/object.c
mono/metadata/reflection.c
mono/metadata/sgen-alloc.c
mono/metadata/sgen-bridge.c
mono/metadata/sgen-bridge.h
mono/metadata/sgen-fin-weak-hash.c
mono/metadata/sgen-gc.c
mono/metadata/sgen-gc.h
mono/metadata/sgen-major-copy-object.h
mono/metadata/sgen-marksweep.c
mono/metadata/sgen-nursery-allocator.c
mono/metadata/sgen-os-posix.c
mono/metadata/sgen-pinning.c
mono/metadata/sgen-pinning.h
mono/metadata/threads.c
mono/mini/.gitignore
mono/mini/Makefile.am
mono/mini/aot-runtime.c
mono/mini/cpu-s390x.md
mono/mini/debugger-agent.c
mono/mini/driver.c
mono/mini/mini-amd64.c
mono/mini/mini-gc.c
mono/mini/mini-s390x.c
mono/mini/mini-s390x.h
mono/mini/mini-unwind.h
mono/mini/mini-x86.c
mono/mini/unwind.c
mono/profiler/proflog.c
mono/tests/Makefile.am
mono/tests/cominterop.cs
mono/tests/libtest.c
mono/tests/mono-path.cs [new file with mode: 0644]
mono/utils/mono-context.h
mono/utils/mono-path.c
scripts/.gitignore

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 c276e939df6c25df244e91150349c2d3a5a27aa9..5895fcb87c27486b8aead73bafeac55c102c2bec 100644 (file)
@@ -859,6 +859,9 @@ if test "x$mono_feature_disable_shared_perfcounters" = "xyes"; then
        AC_MSG_NOTICE([Disabled Shared perfcounters.])
 fi
 
+AC_ARG_ENABLE(executables, [  --disable-executables disable the build of the runtime executables], enable_executables=$enableval, enable_executables=yes)
+AM_CONDITIONAL(DISABLE_EXECUTABLES, test x$enable_executables = xno)
+
 AC_MSG_CHECKING(for visibility __attribute__)
 AC_COMPILE_IFELSE([
        AC_LANG_SOURCE([[
@@ -3144,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
index fccf2651db26b05678dea8a5e4b1472f6d5a0753..0f66a43372e96e0f2ad6db4ac0ec3ef76290ecd6 100644 (file)
@@ -357,6 +357,9 @@ g_strreverse (gchar *str)
        if (str == NULL)
                return NULL;
 
+       if (*str == 0)
+               return str;
+
        for (i = 0, j = strlen (str) - 1; i < j; i++, j--) {
                c = str [i];
                str [i] = str [j];
index 14d24d6ac772f2933455747c1247f7adb2589eff..3dbd738aba7fc7de580460d2a1942b9b573eab87 100644 (file)
@@ -296,27 +296,37 @@ test_split_set ()
 RESULT
 test_strreverse ()
 {
+       RESULT res = OK;
        gchar *a = g_strdup ("onetwothree");
        gchar *a_target = "eerhtowteno";
        gchar *b = g_strdup ("onetwothre");
        gchar *b_target = "erhtowteno";
+       gchar *c = g_strdup ("");
+       gchar *c_target = "";
 
        g_strreverse (a);
        if (strcmp (a, a_target)) {
-               g_free (b);
-               g_free (a);
-               return FAILED("strreverse failed. Expecting: '%s' and got '%s'\n", a, a_target);
+               res = FAILED("strreverse failed. Expecting: '%s' and got '%s'\n", a, a_target);
+               goto cleanup;
        }
 
        g_strreverse (b);
        if (strcmp (b, b_target)) {
-               g_free (b);
-               g_free (a);
-               return FAILED("strreverse failed. Expecting: '%s' and got '%s'\n", b, b_target);
+               res = FAILED("strreverse failed. Expecting: '%s' and got '%s'\n", b, b_target);
+               goto cleanup;
        }
+
+       g_strreverse (c);
+       if (strcmp (c, c_target)) {
+               res = FAILED("strreverse failed. Expecting: '%s' and got '%s'\n", b, b_target);
+               goto cleanup;
+       }
+
+cleanup:
+       g_free (c);
        g_free (b);
        g_free (a);
-       return OK;
+       return res;
 }
 
 RESULT
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 e8bd4599999b5eeb26f9f48598818b380a590065..dc1e5f42386c59597f3795c5f3e643baf53ce108 100644 (file)
--- a/man/mcs.1
+++ b/man/mcs.1
@@ -543,7 +543,7 @@ http://www.mono-project.com/Bugs
 The Mono Mailing lists are listed at http://www.mono-project.com/Mailing_Lists
 .SH MORE INFORMATION
 The Mono C# compiler was developed by Novell, Inc
-(http://www.novell.com) and Xamarin Int (http://www.xamarin.com) is based on the
+(http://www.novell.com) and Xamarin Inc (http://www.xamarin.com) is based on the
 ECMA C# language standard available here:
 http://www.ecma.ch/ecma1/STAND/ecma-334.htm
 .PP
index 76cdc5efbad87eafc5cf6c0261f812b6e8e64b40..404aa14ef19436d698ad8a398d3beafdcd632ea6 100644 (file)
@@ -6,6 +6,7 @@
 *_test_*.dll.config
 *_test_*.xml
 *.o
+*.resources
 TestResult-*.log
 TestResult-*.xml
 TestResult*.xml
index 0f2b9f949faac93b2a2a89747d57ef239e8dd566..186ec2417f8660c0601716f1425ad7e64db3bda0 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,15 @@ 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 \
+       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 8952b7a0e95259c3f107937ecd3f06fffb40e53f..ad5df152bbf754baca44fcb433bf7bb7d16fe122 100644 (file)
@@ -165,9 +165,9 @@ namespace MonoTests.System.Windows.Forms
                        foreach (DataGridViewRow row in dgv.Rows)
                        {
                                int index = row.Index;
-                               Assert.IsInstanceOf (typeof (DataGridViewCheckBoxCell), row.Cells[0], "#" + index + "A");
-                               Assert.IsInstanceOf (typeof (DataGridViewTextBoxCell), row.Cells[1], "#" + index + "B");
-                               Assert.IsInstanceOf (typeof (DataGridViewTextBoxCell), row.Cells[2], "#" + index + "C");
+                               Assert.IsInstanceOfType (typeof (DataGridViewCheckBoxCell), row.Cells[0], "#" + index + "A");
+                               Assert.IsInstanceOfType (typeof (DataGridViewTextBoxCell), row.Cells[1], "#" + index + "B");
+                               Assert.IsInstanceOfType (typeof (DataGridViewTextBoxCell), row.Cells[2], "#" + index + "C");
                        }
                }
        }
index f42783e4cd769f2d166e5eef0a8b1c3508dfdfd1..d77c9ff6d22196eb29397421583065824e115913 100644 (file)
@@ -150,8 +150,14 @@ namespace Microsoft.CSharp.RuntimeBinder
                        Type value_type = (info.Flags & CSharpArgumentInfoFlags.UseCompileTimeType) != 0 ? value.Expression.Type : value.LimitType;
                        var type = ImportType (value_type);
 
-                       if ((info.Flags & CSharpArgumentInfoFlags.Constant) != 0)
-                               return Compiler.Constant.CreateConstantFromValue (type, value.Value, Compiler.Location.Null);
+                       if ((info.Flags & CSharpArgumentInfoFlags.Constant) != 0) {
+                               var c = Compiler.Constant.CreateConstantFromValue (type, value.Value, Compiler.Location.Null);
+                               //
+                               // It can be null for misused Constant flag
+                               //
+                               if (c != null)
+                                       return c;
+                       }
 
                        return new Compiler.RuntimeValueExpression (value, type);
                }
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");
index 01677c2cf58db3d0f1e9544278e9d3fc8e10a27b..a8c5b066230aeb405853eaff5ec9d821e1f0a1ad 100644 (file)
@@ -26,7 +26,7 @@ namespace MonoTests.System.Security.Cryptography {
        public class SHA1CngTest : SHA1Test {
 
                [SetUp]
-               protected override void SetUp ()
+               public override void SetUp ()
                {
                        hash = new SHA1Cng ();
                }
index b45f2f85d36d4c836d4761e6e0a80015f8f06022..4d85b9276dedfb1a74f46b3fc4c991a651989286 100644 (file)
@@ -26,7 +26,7 @@ namespace MonoTests.System.Security.Cryptography {
        public class SHA256CngTest : SHA256Test {
 
                [SetUp]
-               protected override void SetUp ()
+               public override void SetUp ()
                {
                        hash = new SHA256Cng ();
                }
index 4a70937d99fd95a60caa5e137a25f3202b20f4a8..99caa9e354f7d4bd94fe11aca4010deea95ddef9 100644 (file)
@@ -26,7 +26,7 @@ namespace MonoTests.System.Security.Cryptography {
        public class SHA256CryptoServiceProviderTest : SHA256Test {
 
                [SetUp]
-               protected override void SetUp ()
+               public override void SetUp ()
                {
                        hash = new SHA256CryptoServiceProvider ();
                }
index b92bf0fb668a592e197617dbf3d7519cb03a740d..fa09371ef1311f34303d08d9fda0842665b47b84 100644 (file)
@@ -26,7 +26,7 @@ namespace MonoTests.System.Security.Cryptography {
        public class SHA384CngTest : SHA384Test {
 
                [SetUp]
-               protected override void SetUp ()
+               public override void SetUp ()
                {
                        hash = new SHA384Cng ();
                }
index ab41701d113f5381e1d1d3ae484aabaf8f2e7a40..32be53e5f042d439a8960ec065b38bf86ff5f660 100644 (file)
@@ -26,7 +26,7 @@ namespace MonoTests.System.Security.Cryptography {
        public class SHA384CryptoServiceProviderTest : SHA384Test {
 
                [SetUp]
-               protected override void SetUp ()
+               public override void SetUp ()
                {
                        hash = new SHA384CryptoServiceProvider ();
                }
index e516ed572d9e5cf660d9bb4aaefe15190d3c7dea..61766e92b15d229739e37ac70f3ca19a63844a1f 100644 (file)
@@ -26,7 +26,7 @@ namespace MonoTests.System.Security.Cryptography {
        public class SHA512CngTest : SHA512Test {
 
                [SetUp]
-               protected override void SetUp ()
+               public override void SetUp ()
                {
                        hash = new SHA512Cng ();
                }
index 53b04a15cd746290cb70b2789ec6d5dc73910e23..0579f40a850f513a2d00d8fb46d7fcda0d6a8df1 100644 (file)
@@ -26,7 +26,7 @@ namespace MonoTests.System.Security.Cryptography {
        public class SHA512CryptoServiceProviderTest : SHA512Test {
 
                [SetUp]
-               protected override void SetUp ()
+               public override void SetUp ()
                {
                        hash = new SHA512CryptoServiceProvider ();
                }
diff --git a/mcs/class/System.Data.Services.Client/.gitignore b/mcs/class/System.Data.Services.Client/.gitignore
new file mode 100644 (file)
index 0000000..e32d2b0
--- /dev/null
@@ -0,0 +1 @@
+System.Data.Services.Client.resources
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..f83e3ed6a98e4a0f91039d278c8d9721538c4290 100644 (file)
@@ -2,24 +2,24 @@ thisdir = class/System.Json
 SUBDIRS = 
 include ../../build/rules.make
 
+System.Json.Properties.Resources.resources: ../../../external/aspnetwebstack/src/System.Json/Properties/Resources.resx
+       $(RESGEN) "$<" "$@"
+
 LIBRARY = System.Json.dll
-LIB_MCS_FLAGS = \
+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
-
-TEST_MCS_FLAGS = $(LIB_MCS_FLAGS)
-
-EXTRA_DISTFILES =
+               /r:System.Runtime.Serialization.dll \
+               /r:System.ServiceModel.Web.dll \
+               /resource:System.Json.Properties.Resources.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
+ifeq (4, $(FRAMEWORK_VERSION_MAJOR))
+LIB_MCS_FLAGS += /r:Microsoft.CSharp.dll
 endif
 
+TEST_MCS_FLAGS = $(LIB_MCS_FLAGS)
+
 include ../../build/library.make
+
+$(the_lib): System.Json.Properties.Resources.resources
index 47a9ceed63acc60eeff70671bb6a16c17d727b69..f829400c4a53cfa861c13d0f4da4d4cb898ce065 100644 (file)
@@ -1,8 +1,23 @@
 ../../build/common/Consts.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 4901068..0000000
+++ /dev/null
@@ -1,130 +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++) {
-                               list [i].Save (stream);
-                               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 4c6dc5e..0000000
+++ /dev/null
@@ -1,457 +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 (", ");
-                                       v.SaveInternal (w);
-                                       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;
-               }
-       }
-}
index 754f8556a5fea0dbef54f21fdc055342afd69f8e..2459c1fc3ad0f27478d902ffaccc6f2ec3f0d371 100644 (file)
@@ -25,5 +25,15 @@ namespace MonoTests.System
                        Assert.AreEqual (JsonType.String, j ["a"].JsonType, "type");
                        Assert.AreEqual ("b", (string) j ["a"], "value");
                }
+
+               // Test that we correctly serialize JsonArray with null elements.
+               [Test]
+               public void ToStringOnJsonArrayWithNulls () {
+                       var j = JsonValue.Load (new StringReader ("[1,2,3,null]"));
+                       Assert.AreEqual (4, j.Count, "itemcount");
+                       Assert.AreEqual (JsonType.Array, j.JsonType, "type");
+                       var str = j.ToString ();
+                       Assert.AreEqual (str, "[1, 2, 3, null]");
+               }
        }
 }
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..69eeabb
--- /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:System.Xml.Linq.dll -r:System.Data.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..9026a6e
--- /dev/null
@@ -0,0 +1,238 @@
+../../../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
+
+../../../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/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.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 0f33c30b25fcd62290b87219e128429ffc42cd23..9176fc922c8e18675fae662ee04607fbe4172fd5 100644 (file)
@@ -21,7 +21,7 @@ using NUnit.Framework;
 // </auto-generated>
 //------------------------------------------------------------------------------
 
-namespace Client.EvalServiceReference {
+namespace Client2843.EvalServiceReference {
     using System.Runtime.Serialization;
     using System;
     
@@ -48,10 +48,10 @@ namespace Client.EvalServiceReference {
         private System.Nullable<System.DateTime> TimeSubmittedField;
         
         [System.Runtime.Serialization.OptionalFieldAttribute()]
-        private System.Nullable<Client.EvalServiceReference.EvalType> etypeField;
+        private System.Nullable<Client2843.EvalServiceReference.EvalType> etypeField;
         
         [System.Runtime.Serialization.OptionalFieldAttribute()]
-        private System.Nullable<Client.EvalServiceReference.EvalType> etype2Field;
+        private System.Nullable<Client2843.EvalServiceReference.EvalType> etype2Field;
         
         [global::System.ComponentModel.BrowsableAttribute(false)]
         public System.Runtime.Serialization.ExtensionDataObject ExtensionData {
@@ -116,7 +116,7 @@ namespace Client.EvalServiceReference {
         }
         
         [System.Runtime.Serialization.DataMemberAttribute()]
-        public System.Nullable<Client.EvalServiceReference.EvalType> etype {
+        public System.Nullable<Client2843.EvalServiceReference.EvalType> etype {
             get {
                 return this.etypeField;
             }
@@ -129,7 +129,7 @@ namespace Client.EvalServiceReference {
         }
         
         [System.Runtime.Serialization.DataMemberAttribute()]
-        public System.Nullable<Client.EvalServiceReference.EvalType> etype2 {
+        public System.Nullable<Client2843.EvalServiceReference.EvalType> etype2 {
             get {
                 return this.etype2Field;
             }
@@ -170,22 +170,22 @@ namespace Client.EvalServiceReference {
     public interface IEvalService {
         
         [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IEvalService/SubmitEval", ReplyAction="http://tempuri.org/IEvalService/SubmitEvalResponse")]
-        void SubmitEval(Client.EvalServiceReference.Eval eval);
+        void SubmitEval(Client2843.EvalServiceReference.Eval eval);
         
         [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IEvalService/GetEvals", ReplyAction="http://tempuri.org/IEvalService/GetEvalsResponse")]
-        Client.EvalServiceReference.Eval[] GetEvals();
+        Client2843.EvalServiceReference.Eval[] GetEvals();
         
         [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IEvalService/RemoveEval", ReplyAction="http://tempuri.org/IEvalService/RemoveEvalResponse")]
         void RemoveEval(string id);
     }
     
     [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
-    public interface IEvalServiceChannel : Client.EvalServiceReference.IEvalService, System.ServiceModel.IClientChannel {
+    public interface IEvalServiceChannel : Client2843.EvalServiceReference.IEvalService, System.ServiceModel.IClientChannel {
     }
     
     [System.Diagnostics.DebuggerStepThroughAttribute()]
     [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
-    public partial class EvalServiceClient : System.ServiceModel.ClientBase<Client.EvalServiceReference.IEvalService>, Client.EvalServiceReference.IEvalService {
+    public partial class EvalServiceClient : System.ServiceModel.ClientBase<Client2843.EvalServiceReference.IEvalService>, Client2843.EvalServiceReference.IEvalService {
         
         public EvalServiceClient() {
         }
@@ -206,11 +206,11 @@ namespace Client.EvalServiceReference {
                 base(binding, remoteAddress) {
         }
         
-        public void SubmitEval(Client.EvalServiceReference.Eval eval) {
+        public void SubmitEval(Client2843.EvalServiceReference.Eval eval) {
             base.Channel.SubmitEval(eval);
         }
         
-        public Client.EvalServiceReference.Eval[] GetEvals() {
+        public Client2843.EvalServiceReference.Eval[] GetEvals() {
             return base.Channel.GetEvals();
         }
         
@@ -233,13 +233,13 @@ namespace MonoTests.System.Runtime.Serialization
                        string Wrapper   = "GetEvalsResponse";
                        string Namespace = "http://tempuri.org/";
                        
-                       Type type = typeof(Client.EvalServiceReference.Eval[]);
+                       Type type = typeof(Client2843.EvalServiceReference.Eval[]);
                        IEnumerable<Type> know_types = new List<Type>();
                        
                        // This is the XML generated by WCF Server
                        string xml = "<GetEvalsResponse xmlns=\"http://tempuri.org/\">      <GetEvalsResult xmlns:a=\"http://schemas.datacontract.org/2004/07/WcfServiceLibrary1\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">        <a:Eval>          <a:Comments>Comment 1</a:Comments>          <a:Id>04836718-41a7-45fe-8c0b-ac3fc613b0f8</a:Id>          <a:Submitter>Submitter 1</a:Submitter>          <a:TimeSubmitted i:nil=\"true\" />          <a:etype>SIMPLE</a:etype>          <a:etype2>COMPLEX</a:etype2>        </a:Eval>        <a:Eval>          <a:Comments>Comment 2</a:Comments>          <a:Id>fd17a406-4c2c-41ca-9a5d-1a1019d07535</a:Id>          <a:Submitter>Submitter 2</a:Submitter>          <a:TimeSubmitted>2012-02-26T13:41:00</a:TimeSubmitted>          <a:etype i:nil=\"true\" />          <a:etype2>COMPLEX</a:etype2>        </a:Eval>      </GetEvalsResult>    </GetEvalsResponse>";
                        
-                       Client.EvalServiceReference.Eval[] evals = null;
+                       Client2843.EvalServiceReference.Eval[] evals = null;
                        
                        StringBuilder stringBuilder = new StringBuilder ();
                        
@@ -256,7 +256,7 @@ namespace MonoTests.System.Runtime.Serialization
                                        break;
                                }
                                        
-                               evals = (Client.EvalServiceReference.Eval[])ds.ReadObject (xr, true);                           
+                               evals = (Client2843.EvalServiceReference.Eval[])ds.ReadObject (xr, true);                               
                        }
                        
                        using (var xw = XmlDictionaryWriter.CreateDictionaryWriter ( XmlWriter.Create( new StringWriter(stringBuilder)))) {
@@ -267,44 +267,44 @@ namespace MonoTests.System.Runtime.Serialization
                        
                        Assert.AreEqual (evals.Length, 2, "Comment 1" , "Eval 1 Comment missmatch");
                        
-                       Client.EvalServiceReference.Eval ev1 = evals[0];
-                       Client.EvalServiceReference.Eval ev2 = evals[1];
+                       Client2843.EvalServiceReference.Eval ev1 = evals[0];
+                       Client2843.EvalServiceReference.Eval ev2 = evals[1];
                        
                        // Assert that object deserilized matches each value attribute.
                        Assert.AreEqual (ev1.Comments, "Comment 1" , "ev1.Comments missmatch");
                        Assert.AreEqual (ev1.Submitter, "Submitter 1", "ev1.Submitter missmatch");
                        Assert.IsNull   (ev1.TimeSubmitted, "ev1.TimeSubmitted missmatch");
-                       Assert.AreEqual (ev1.etype, Client.EvalServiceReference.EvalType.SIMPLE, "ev1.etype missmatch");
-                       Assert.AreEqual (ev1.etype2, Client.EvalServiceReference.EvalType.COMPLEX, "ev1.etype2 missmatch");
+                       Assert.AreEqual (ev1.etype, Client2843.EvalServiceReference.EvalType.SIMPLE, "ev1.etype missmatch");
+                       Assert.AreEqual (ev1.etype2, Client2843.EvalServiceReference.EvalType.COMPLEX, "ev1.etype2 missmatch");
                        
                        Assert.AreEqual (ev2.Comments, "Comment 2", "ev2.Comments missmatch");
                        Assert.AreEqual (ev2.Submitter, "Submitter 2","ev2.Submitter missmatch");
                        Assert.AreEqual (ev2.TimeSubmitted, DateTime.Parse("2012-02-26T13:41:00"), "ev2.TimeSubmitted missmatch");
                        Assert.IsNull (ev2.etype, "ev2.etype missmatch");
-                       Assert.AreEqual (ev2.etype2, Client.EvalServiceReference.EvalType.COMPLEX, "ev2.etype2 missmatch");
+                       Assert.AreEqual (ev2.etype2, Client2843.EvalServiceReference.EvalType.COMPLEX, "ev2.etype2 missmatch");
                        
                        
-                       Client.EvalServiceReference.Eval[] evals2 = null;
+                       Client2843.EvalServiceReference.Eval[] evals2 = null;
                        
                        using (var xr = XmlDictionaryReader.CreateDictionaryReader ( XmlReader.Create (new StringReader (actualXml))))
                        {
-                               evals2 = (Client.EvalServiceReference.Eval[])ds.ReadObject (xr, true);  
+                               evals2 = (Client2843.EvalServiceReference.Eval[])ds.ReadObject (xr, true);      
                        }
                        
-                       Client.EvalServiceReference.Eval e1 = evals2[0];
-                       Client.EvalServiceReference.Eval e2 = evals2[1];
+                       Client2843.EvalServiceReference.Eval e1 = evals2[0];
+                       Client2843.EvalServiceReference.Eval e2 = evals2[1];
                        
                        Assert.AreEqual (e1.Comments, "Comment 1" , "e1.Comments missmatch");
                        Assert.AreEqual (e1.Submitter, "Submitter 1", "e1.Submitter missmatch");
                        Assert.IsNull   (e1.TimeSubmitted, "e1.TimeSubmitted missmatch");
-                       Assert.AreEqual (e1.etype, Client.EvalServiceReference.EvalType.SIMPLE, "e1.etype missmatch");
-                       Assert.AreEqual (e1.etype2, Client.EvalServiceReference.EvalType.COMPLEX, "e1.etype2 missmatch");
+                       Assert.AreEqual (e1.etype, Client2843.EvalServiceReference.EvalType.SIMPLE, "e1.etype missmatch");
+                       Assert.AreEqual (e1.etype2, Client2843.EvalServiceReference.EvalType.COMPLEX, "e1.etype2 missmatch");
                        
                        Assert.AreEqual (e2.Comments, "Comment 2", "e2.Comments missmatch");
                        Assert.AreEqual (e2.Submitter, "Submitter 2","e2.Submitter missmatch");
                        Assert.AreEqual (e2.TimeSubmitted, DateTime.Parse("2012-02-26T13:41:00"), "e2.TimeSubmitted missmatch");
                        Assert.IsNull   (e2.etype, "e2.etype missmatch");
-                       Assert.AreEqual (e2.etype2, Client.EvalServiceReference.EvalType.COMPLEX, "e2.etype2 missmatch");
+                       Assert.AreEqual (e2.etype2, Client2843.EvalServiceReference.EvalType.COMPLEX, "e2.etype2 missmatch");
                }
        }
 }
index 58084224c311b7be148485e2db7e88d41b0d5f6d..804eeebd3206d129561c55e111b520e208be4fb6 100644 (file)
@@ -34,31 +34,31 @@ namespace System.Runtime.Serialization.Json
 {
        public static class JsonReaderWriterFactory
        {
-               public static XmlDictionaryReader CreateJsonReader (byte [] source, XmlDictionaryReaderQuotas quotas)
+               public static XmlDictionaryReader CreateJsonReader (byte [] buffer, XmlDictionaryReaderQuotas quotas)
                {
-                       if (source == null)
-                               throw new ArgumentNullException ("source");
-                       return CreateJsonReader (source, 0, source.Length, quotas);
+                       if (buffer == null)
+                               throw new ArgumentNullException ("buffer");
+                       return CreateJsonReader (buffer, 0, buffer.Length, quotas);
                }
 
-               public static XmlDictionaryReader CreateJsonReader (byte [] source, int offset, int length, XmlDictionaryReaderQuotas quotas)
+               public static XmlDictionaryReader CreateJsonReader (byte [] buffer, int offset, int count, XmlDictionaryReaderQuotas quotas)
                {
-                       return CreateJsonReader (source, offset, length, null, quotas, null);
+                       return CreateJsonReader (buffer, offset, count, null, quotas, null);
                }
 
-               public static XmlDictionaryReader CreateJsonReader (byte [] source, int offset, int length, Encoding encoding, XmlDictionaryReaderQuotas quotas, OnXmlDictionaryReaderClose readerClose)
+               public static XmlDictionaryReader CreateJsonReader (byte [] buffer, int offset, int count, Encoding encoding, XmlDictionaryReaderQuotas quotas, OnXmlDictionaryReaderClose onClose)
                {
-                       return new JsonReader (source, offset, length, encoding, quotas, readerClose);
+                       return new JsonReader (buffer, offset, count, encoding, quotas, onClose);
                }
 
-               public static XmlDictionaryReader CreateJsonReader (Stream source, XmlDictionaryReaderQuotas quotas)
+               public static XmlDictionaryReader CreateJsonReader (Stream stream, XmlDictionaryReaderQuotas quotas)
                {
-                       return CreateJsonReader (source, null, quotas, null);
+                       return CreateJsonReader (stream, null, quotas, null);
                }
 
-               public static XmlDictionaryReader CreateJsonReader (Stream source, Encoding encoding, XmlDictionaryReaderQuotas quotas, OnXmlDictionaryReaderClose readerClose)
+               public static XmlDictionaryReader CreateJsonReader (Stream stream, Encoding encoding, XmlDictionaryReaderQuotas quotas, OnXmlDictionaryReaderClose onClose)
                {
-                       return new JsonReader (source, encoding, quotas, readerClose);
+                       return new JsonReader (stream, encoding, quotas, onClose);
                }
 
                public static XmlDictionaryWriter CreateJsonWriter (Stream stream)
@@ -71,9 +71,9 @@ namespace System.Runtime.Serialization.Json
                        return CreateJsonWriter (stream, encoding, false);
                }
 
-               public static XmlDictionaryWriter CreateJsonWriter (Stream stream, Encoding encoding, bool closeOutput)
+               public static XmlDictionaryWriter CreateJsonWriter (Stream stream, Encoding encoding, bool ownsStream)
                {
-                       return new JsonWriter (stream, encoding, closeOutput);
+                       return new JsonWriter (stream, encoding, ownsStream);
                }
        }
 }
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/GlobalAssemblyInfo.cs b/mcs/class/System.Web.Mvc3/GlobalAssemblyInfo.cs
new file mode 100644 (file)
index 0000000..322630d
--- /dev/null
@@ -0,0 +1,12 @@
+using System.Reflection;
+using System.Resources;
+
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft Corporation")]
+[assembly: AssemblyProduct("Microsoft® .NET Framework")]
+[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+[assembly: AssemblyVersion("3.0.0.0")]
+[assembly: AssemblyFileVersion("3.0.20107.0")]
+[assembly: NeutralResourcesLanguage("en-US")]
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..d65c2ff
--- /dev/null
@@ -0,0 +1,341 @@
+./GlobalSuppressions.cs
+./GlobalAssemblyInfo.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..2ff684c
--- /dev/null
@@ -0,0 +1,27 @@
+thisdir = class/System.Web.Razor
+SUBDIRS = 
+include ../../build/rules.make
+
+LIBRARY = System.Web.Razor.dll
+LIBRARY_NAME = System.Web.Razor.dll
+
+System.Web.Razor.Common.CommonResources.resources: ../../../external/aspnetwebstack/src/CommonResources.resx
+       $(RESGEN) "$<" "$@"
+       
+System.Web.Razor.Resources.RazorResources.resources: ../../../external/aspnetwebstack/src/System.Web.Razor/Resources/RazorResources.resx
+       $(RESGEN) "$<" "$@"
+
+LIB_MCS_FLAGS = \
+               /warn:1 \
+               /noconfig \
+               /keyfile:../winfx.pub -delaysign \
+               /r:System.dll \
+               /r:System.Core.dll \
+               /d:ASPNETWEBPAGES \
+               /resource:System.Web.Razor.Resources.RazorResources.resources \
+               /resource:System.Web.Razor.Common.CommonResources.resources
+
+include ../../build/library.make
+
+$(build_lib): System.Web.Razor.Resources.RazorResources.resources \
+               System.Web.Razor.Common.CommonResources.resources
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..f828d7b
--- /dev/null
@@ -0,0 +1,30 @@
+thisdir = class/System.Web.WebPages.Deployment
+SUBDIRS = 
+include ../../build/rules.make
+
+LIBRARY = System.Web.WebPages.Deployment.dll
+LIBRARY_NAME = System.Web.WebPages.Deployment.dll
+
+System.Web.WebPages.Deployment.Common.CommonResources.resources: ../../../external/aspnetwebstack/src/CommonResources.resx
+       $(RESGEN) "$<" "$@"
+       
+System.Web.WebPages.Deployment.Resources.ConfigurationResources.resources: ../../../external/aspnetwebstack/src/System.Web.WebPages.Deployment/Resources/ConfigurationResources.resx
+       $(RESGEN) "$<" "$@"
+
+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 \
+               /resource:System.Web.WebPages.Deployment.Common.CommonResources.resources \
+               /resource:System.Web.WebPages.Deployment.Resources.ConfigurationResources.resources
+
+include ../../build/library.make
+
+$(build_lib): System.Web.WebPages.Deployment.Common.CommonResources.resources \
+               System.Web.WebPages.Deployment.Resources.ConfigurationResources.resources
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..d56f4d8
--- /dev/null
@@ -0,0 +1,34 @@
+thisdir = class/System.Web.WebPages.Razor
+SUBDIRS = 
+include ../../build/rules.make
+
+LIBRARY = System.Web.WebPages.Razor.dll
+LIBRARY_NAME = System.Web.WebPages.Razor.dll
+
+System.Web.WebPages.Razor.Common.CommonResources.resources: ../../../external/aspnetwebstack/src/CommonResources.resx
+       $(RESGEN) "$<" "$@"
+       
+System.Web.WebPages.Razor.Resources.RazorWebResources.resources: ../../../external/aspnetwebstack/src/System.Web.WebPages.Razor/Resources/RazorWebResources.resx
+       $(RESGEN) "$<" "$@"
+
+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 \
+               /resource:System.Web.WebPages.Razor.Resources.RazorWebResources.resources \
+               /resource:System.Web.WebPages.Razor.Common.CommonResources.resources
+
+include ../../build/library.make
+
+$(build_lib): System.Web.WebPages.Razor.Resources.RazorWebResources.resources \
+               System.Web.WebPages.Razor.Common.CommonResources.resources
+
+
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..7bcf43b
--- /dev/null
@@ -0,0 +1,40 @@
+thisdir = class/System.Web.WebPages
+SUBDIRS = 
+include ../../build/rules.make
+
+LIBRARY = System.Web.WebPages.dll
+LIBRARY_NAME = System.Web.WebPages.dll
+
+System.Web.WebPages.Common.CommonResources.resources: ../../../external/aspnetwebstack/src/CommonResources.resx
+       $(RESGEN) "$<" "$@"
+       
+System.Web.WebPages.Resources.WebPageResources.resources: ../../../external/aspnetwebstack/src/System.Web.WebPages/Resources/WebPageResources.resx
+       $(RESGEN) "$<" "$@"
+
+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 \
+               /resource:System.Web.WebPages.Resources.WebPageResources.resources \
+               /resource:System.Web.WebPages.Common.CommonResources.resources
+
+EXTRA_DISTFILES = $(RESX_DIST)
+
+include ../../build/library.make
+
+$(build_lib): System.Web.WebPages.Resources.WebPageResources.resources \
+               System.Web.WebPages.Common.CommonResources.resources
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 dc05a339acd27dbb3591acb9d0ea94bfa790ad60..eb87c998b0717190d9855da2d75643ba1f40bd28 100644 (file)
@@ -74,13 +74,17 @@ namespace System.Net {
                        if (lp.Path.IndexOf ("//", StringComparison.Ordinal) != -1) // TODO: Code?
                                throw new HttpListenerException (400, "Invalid path.");
 
-                       // Always listens on all the interfaces, no matter the host name/ip used.
-                       EndPointListener epl = GetEPListener (IPAddress.Any, lp.Port, listener, lp.Secure);
+                       // listens on all the interfaces if host name cannot be parsed by IPAddress.
+                       EndPointListener epl = GetEPListener (lp.Host, lp.Port, listener, lp.Secure);
                        epl.AddPrefix (lp, listener);
                }
 
-               static EndPointListener GetEPListener (IPAddress addr, int port, HttpListener listener, bool secure)
+               static EndPointListener GetEPListener (string host, int port, HttpListener listener, bool secure)
                {
+                       IPAddress addr;
+                       if (IPAddress.TryParse(host, out addr) == false)
+                               addr = IPAddress.Any;
+
                        Hashtable p = null;  // Dictionary<int, EndPointListener>
                        if (ip_to_endpoints.ContainsKey (addr)) {
                                p = (Hashtable) ip_to_endpoints [addr];
@@ -139,7 +143,7 @@ namespace System.Net {
                        if (lp.Path.IndexOf ("//", StringComparison.Ordinal) != -1)
                                return;
 
-                       EndPointListener epl = GetEPListener (IPAddress.Any, lp.Port, listener, lp.Secure);
+                       EndPointListener epl = GetEPListener (lp.Host, lp.Port, listener, lp.Secure);
                        epl.RemovePrefix (lp, listener);
                }
        }
index 4169b6ef698d6458d7786de2779bfb7c407dd81e..c6cf36c0fc5901d3bffd03b6fcba1907b6d42994 100644 (file)
@@ -27,8 +27,6 @@
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
-#if NET_2_0
-
 using System.ComponentModel;
 using System.IO;
 
@@ -68,4 +66,4 @@ namespace System.Net
        }
 }
 
-#endif
+
index a20b867d35b681a60e97e29a962832dd0e833d66..07abdc8b9400680c70e86d2f1d67ef2218a38ac5 100644 (file)
@@ -563,9 +563,30 @@ namespace System.Net
                                        reqStream.Write (partHeadersBytes, 0, partHeadersBytes.Length);
                                }
                                int nread;
+                               long bytes_sent = 0;
+                               long file_size = -1;
+                               long step = 16384; // every 16kB
+                               if (fStream.CanSeek) {
+                                       file_size = fStream.Length;
+                                       step = file_size / 100;
+                               }
+                               var upload_args = new UploadProgressChangedEventArgs (0, 0, bytes_sent, file_size, 0, userToken);
+                               OnUploadProgressChanged (upload_args);
                                byte [] buffer = new byte [4096];
-                               while ((nread = fStream.Read (buffer, 0, 4096)) != 0)
+                               long sum = 0;
+                               while ((nread = fStream.Read (buffer, 0, 4096)) > 0) {
                                        reqStream.Write (buffer, 0, nread);
+                                       bytes_sent += nread;
+                                       sum += nread;
+                                       if (sum >= step || nread < 4096) {
+                                               int percent = 0;
+                                               if (file_size > 0)
+                                                       percent = (int) (bytes_sent * 100 / file_size);
+                                               upload_args = new UploadProgressChangedEventArgs (0, 0, bytes_sent, file_size, percent, userToken);
+                                               OnUploadProgressChanged (upload_args);
+                                               sum = 0;
+                                       }
+                               }
 
                                if (needs_boundary) {
                                        reqStream.WriteByte ((byte) '\r');
index 9f52e366bc0c6a9f0d9b770a6c3ce90184eece3f..5932efb758dea0a9eed2a5485a119d1b3003b292 100644 (file)
@@ -148,6 +148,8 @@ namespace System.Security.Cryptography.X509Certificates {
                        return null;
                }
 
+               static string[] newline_split = new string[] { Environment.NewLine };
+               
                [MonoTODO ("Does not support X509FindType.FindByTemplateName, FindByApplicationPolicy and FindByCertificatePolicy")]
                public X509Certificate2Collection Find (X509FindType findType, object findValue, bool validOnly) 
                {
@@ -238,8 +240,13 @@ namespace System.Security.Cryptography.X509Certificates {
                                                (String.Compare (str, x.GetCertHashString (), true, cinv) == 0));
                                        break;
                                case X509FindType.FindBySubjectName:
-                                       string sname = x.GetNameInfo (X509NameType.SimpleName, false);
-                                       value_match = (sname.IndexOf (str, StringComparison.InvariantCultureIgnoreCase) >= 0);
+                                       string [] names = x.SubjectName.Format (true).Split (newline_split, StringSplitOptions.RemoveEmptyEntries);
+                                       foreach (string name in names) {
+                                               int pos = name.IndexOf ('=');
+                                               value_match = (name.IndexOf (str, pos, StringComparison.InvariantCultureIgnoreCase) >= 0);
+                                               if (value_match)
+                                                       break;
+                                       }
                                        break;
                                case X509FindType.FindBySubjectDistinguishedName:
                                        value_match = (String.Compare (str, x.Subject, true, cinv) == 0);
index c3a1162c01d1e55c193f9437763c0702d86d2ce2..5fb4a9c5c65e50a4de5c14cb6d30f85aac4c10a6 100644 (file)
@@ -172,7 +172,7 @@ namespace MonoTests.System.ComponentModel
                        CultureInfo ciDE = new CultureInfo("de-DE");
 
                        DateTimeOffset dateOffset = new DateTimeOffset (2008, 12, 31, 23, 59, 58, 5, new TimeSpan (3, 6, 0));
-                       DoTestToString ("12/31/2008 11:59 p.m. +03:06", dateOffset, ciUS);
+                       DoTestToString ("12/31/2008 11:59 PM +03:06", dateOffset, ciUS);
                        DoTestToString ("31/12/2008 23:59 +03:06", dateOffset, ciGB);
                        DoTestToString ("31.12.2008 23:59 +03:06", dateOffset, ciDE);
                        DoTestToString ("12/31/2008 23:59:58 +03:06", dateOffset, CultureInfo.InvariantCulture);
index d3011f16688af858a55cd08199fdd75111dad039..4325fad2ff486b8a9d861b411573fa969ec6348a 100644 (file)
@@ -290,13 +290,12 @@ namespace MonoTests.System.Configuration {
                        // such cases.
 #if TARGET_JVM
                        string expected = "MonoTests.System.Configuration.ProviderPoker, System.Test, Version=0.0.0.0";
-#else #if NET_4_5
+#elif NET_4_5
                        string expected = "MonoTests.System.Configuration.ProviderPoker, System_test_net_4_5, Version=0.0.0.0";
-#else #if NET_4_0
+#elif NET_4_0
                        string expected = "MonoTests.System.Configuration.ProviderPoker, System_test_net_4_0, Version=0.0.0.0";
 #else
                        string expected = "MonoTests.System.Configuration.ProviderPoker, System_test_net_2_0, Version=0.0.0.0";
-#endif
 #endif
                        Assert.AreEqual (expected, new SettingsProviderAttribute (typeof (ProviderPoker)).ProviderTypeName.Substring (0, expected.Length), "#1");
                        TestSettings2 settings = new TestSettings2 ();
index 957e977724f57289eaba8c9b57cfd4d8f7dd49a4..6b8e87f533d6be238ada2dc2e9c9a82a80443fea 100644 (file)
@@ -28,12 +28,12 @@ namespace MonoTests.System.Net
        [TestFixture]\r
        public class DnsTest\r
        {\r
-               private String site1Name = "www.go-mono.com",\r
-                       site1Dot = "130.57.21.18",\r
+               private String site1Name = "go-mono.com",\r
+                       site1Dot = "74.208.222.19",\r
                        site2Name = "info.diku.dk",\r
                        site2Dot = "130.225.96.4",\r
                        noneExistingSite = "www.unlikely.novell.com";\r
-               private uint site1IP = 2180692201, site2IP = 2195808260; // Big-Endian\r
+               private uint site1IP = 1255202323, site2IP = 2195808260; // Big-Endian\r
 \r
                [Test]\r
                public void AsyncGetHostByName ()\r
@@ -44,7 +44,7 @@ namespace MonoTests.System.Net
                        IAsyncResult async = Dns.BeginGetHostByName (site1Name, null, null);\r
                        IPHostEntry entry = Dns.EndGetHostByName (async);\r
                        SubTestValidIPHostEntry (entry);\r
-                       Assert.AreEqual ("www.go-mono.com", entry.HostName);\r
+                       Assert.AreEqual ("go-mono.com", entry.HostName);\r
                }\r
 \r
                void GetHostByNameCallback (IAsyncResult ar)\r
@@ -285,7 +285,6 @@ namespace MonoTests.System.Net
                }\r
 \r
                [Test]\r
-               [Ignore ("Fails on both Mono and MS")]\r
                public void GetHostByAddressIPAddress2 ()\r
                {\r
                        IPAddress addr = new IPAddress (IPAddress.NetworkToHostOrder ((int) site1IP));\r
index 63d230dc80517cc2d87289aa63f95f96a35de61f..745d13b5a4eec4d0f6f95c2caefa97ebc1d33ecd 100644 (file)
@@ -2,8 +2,9 @@
 // X509CertificateCollection2Test.cs 
 //     - NUnit tests for X509CertificateCollection2
 //
-// Author:
+// Authors:
 //     Sebastien Pouliot  <sebastien@ximian.com>
+//     David Ferguson  <davecferguson@gmail.com>
 //
 // Copyright (C) 2006 Novell, Inc (http://www.novell.com)
 //
@@ -895,6 +896,48 @@ namespace MonoTests.System.Security.Cryptography.X509Certificates {
                                Assert.IsTrue ((o is X509Certificate), "X509Certificate");
                        }
                }
+
+               [Test]
+               public void X509Certificate2CollectionFindBySubjectName_Test ()
+               {
+                       // Created with mono makecert
+                       // makecert -n "O=Root, CN=MyCNName, T=SomeElse" -r <filename>
+                       const string Cert = "MIIB6zCCAVSgAwIBAgIQEshQw4bf1kSsYsUoLCjlpTANBgkqhkiG9w0BAQUFADA1MQ0wCwYDVQQKEwRSb290MREwDwYDVQQDEwhNeUNOTmFtZTERMA8GA1UEDBMIU29tZUVsc2UwHhcNMTIwMzE1MTUzNjE0WhcNMzkxMjMxMjM1OTU5WjA1MQ0wCwYDVQQKEwRSb290MREwDwYDVQQDEwhNeUNOTmFtZTERMA8GA1UEDBMIU29tZUVsc2UwgZ0wDQYJKoZIhvcNAQEBBQADgYsAMIGHAoGBAI8A3ay+oRKRBAD4oojA2s4feHBHn5OafJ+Vxap7wsd3IF/qBrXdnFLxfvLltCSZDarajwTjxX2rhT7Q0hm3Yyy6DnyaMoL8u//c6HCv47SFNJ4JEgu2WP9M/xNU2m+JiABX+K/nwoWfE1VIYueJWL9ftCBOG099QBCsCrpdFUcbAgERMA0GCSqGSIb3DQEBBQUAA4GBAHV+uMPliZPhfLdcMGIbYQnWY2m4YrU/IvqZK4HTKyzG/heAp7+OvkGiC0YJHtvWehgZUV9ukVEbl93rCKmXlb6BuPgN60U1iLYJQ9nAVHm7fRoAjvjDj3CGFtmYb81sYu8sc5GHqsCbvTKHwW/x2O3uLJBM5ApDlcczmgdm8xqQ";
+
+                       var cerBytes = Convert.FromBase64String (Cert);
+                       var cert = new X509Certificate2 (cerBytes);
+                       var collection = new X509Certificate2Collection ();
+
+                       var found = collection.Find (X509FindType.FindBySubjectName, "SomeElse", false);
+                       Assert.IsEmpty (found, "empty");
+                       
+                       collection.Add (cert);
+
+                       collection.Find (X509FindType.FindBySubjectName, "T=SomeElse", false);
+                       Assert.IsEmpty (found, "with prefix");
+                       
+                       found = collection.Find (X509FindType.FindBySubjectName, "SomeElse", false);
+                       Assert.That (found.Count == 1, "full");
+                       
+                       found = collection.Find (X509FindType.FindBySubjectName, "Else", false);
+                       Assert.That (found.Count == 1, "partial");
+                       
+                       Assert.That (found [0].SubjectName.Name.Contains ("O=Root"));
+                       Assert.That (found [0].SubjectName.Name.Contains ("T=SomeElse"));
+                       Assert.That (found [0].SubjectName.Name.Contains ("CN=MyCNName"));
+                       found = collection.Find (X509FindType.FindBySubjectName, "MyCNName", false);
+                       Assert.IsTrue (found.Count == 1);
+                       Assert.That (found [0].SubjectName.Name.Contains ("O=Root"));
+                       Assert.That (found [0].SubjectName.Name.Contains ("T=SomeElse"));
+                       Assert.That (found [0].SubjectName.Name.Contains ("CN=MyCNName"));
+                       found = collection.Find (X509FindType.FindBySubjectName, "Root", false);
+                       Assert.IsTrue (found.Count == 1);
+                       Assert.That (found [0].SubjectName.Name.Contains ("O=Root"));
+                       Assert.That (found [0].SubjectName.Name.Contains ("T=SomeElse"));
+                       Assert.That (found [0].SubjectName.Name.Contains ("CN=MyCNName"));
+                       found = collection.Find (X509FindType.FindBySubjectName, "SomeRandomStringThatDoesn'tExist", false);
+                       Assert.IsEmpty (found);
+               }
        }
 }
 
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 0d0dbce898b3d7517a158db2812f5abb872f8e66..77fda6e3c134bcbdcae882843ecb5c865425e157 100644 (file)
@@ -147,7 +147,7 @@ namespace System.ComponentModel {
                {
                        throw new NotImplementedException ();
                }
-               public static DependencyPropertyDescriptor FromProperty (PropertyDescriptor Property)
+               public static DependencyPropertyDescriptor FromProperty (PropertyDescriptor property)
                {
                        throw new NotImplementedException ();
                }
index d7b71c3a535644f27b6187471228a93a72665f8d..96ea9a5403b45bdae370068ca187d7763be6b3d8 100644 (file)
@@ -94,15 +94,15 @@ namespace System.IO.Packaging {
                }
                
                
-               protected Package (FileAccess fileOpenAccess)
-                       : this (fileOpenAccess, false)
+               protected Package (FileAccess openFileAccess)
+                       : this (openFileAccess, false)
                {
                        
                }
 
-               protected Package (FileAccess fileOpenAccess, bool streaming)
+               protected Package (FileAccess openFileAccess, bool streaming)
                {
-                       FileOpenAccess = fileOpenAccess;
+                       FileOpenAccess = openFileAccess;
                        Streaming = streaming;
                }
 
@@ -138,7 +138,7 @@ namespace System.IO.Packaging {
                        return part;
                }
                
-               protected abstract PackagePart CreatePartCore (Uri parentUri, string contentType, CompressionOption compressionOption);
+               protected abstract PackagePart CreatePartCore (Uri partUri, string contentType, CompressionOption compressionOption);
 
                public PackageRelationship CreateRelationship (Uri targetUri, TargetMode targetMode, string relationshipType)
                {
index eb0c44c6004869d583d4b766d64dee0404ad33a2..3f30749d72dfdeedf7495e1f6dd9520baf2a2033 100644 (file)
@@ -34,7 +34,7 @@ using System.Security.Cryptography.Xml;
 
 namespace System.IO.Packaging {
 
-       public class PackageDigitalSignatureManager
+       public sealed class PackageDigitalSignatureManager
        {
                public static string DefaultHashAlgorithm {
                        get { throw new NotImplementedException (); }
index 1ded5c74316d614a618a2e33a429b7b921af51e7..105d272fadff2c6fd505996b126716b8cf3698b5 100644 (file)
@@ -28,7 +28,7 @@ using System.Security;
 
 namespace System.Security.Permissions {
 
-       public class MediaPermission : CodeAccessPermission, IUnrestrictedPermission
+       public sealed class MediaPermission : CodeAccessPermission, IUnrestrictedPermission
        {
                public MediaPermission ()
                {
index 097e4efa51602b13a92c150a4550e9d1490d3582..c116cf4e6fccf44db717e049062b8d3f9143f021 100644 (file)
@@ -29,7 +29,7 @@ using System.Security;
 namespace System.Security.Permissions {
 
        [AttributeUsage (AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Struct | AttributeTargets.Class | AttributeTargets.Assembly)]
-       public class MediaPermissionAttribute : CodeAccessSecurityAttribute
+       public sealed class MediaPermissionAttribute : CodeAccessSecurityAttribute
        {
                public MediaPermissionAttribute (SecurityAction action)
                        : base (action)
index ba590a9b29cedd8f03d3c4a04886660fe7011ff8..40f1a932d1acb7f2df60318b61c3b0eebc965b22 100644 (file)
@@ -233,6 +233,7 @@ namespace System.Windows.Input {
                DbeDetermineString = NoName,
                Pa1,
                DbeEnterDialogConversionMode = Pa1,
-               OemClear
+               OemClear,
+               DeadCharProcessed
        }
 }
index 6c4ca4f685c50efac846e43ea51b10f8da76a91c..4855371974259e290828dd900569e297d07b166a 100644 (file)
@@ -41,7 +41,7 @@ namespace System.Windows.Input {
                        throw new NotImplementedException ();
                }
 
-               public override object ConvertFrom (ITypeDescriptorContext context, CultureInfo culture, object value)
+               public override object ConvertFrom (ITypeDescriptorContext context, CultureInfo culture, object source)
                {
                        throw new NotImplementedException ();
                }
index e7495ab687fe8ad66ccbad1575a920302edfbdd8..3752b9d6ab3761c9d39b08999c68a888bfd69c51 100644 (file)
@@ -41,7 +41,7 @@ namespace System.Windows.Input {
                        throw new NotImplementedException ();
                }
 
-               public override object ConvertFrom (ITypeDescriptorContext context, CultureInfo culture, object value)
+               public override object ConvertFrom (ITypeDescriptorContext context, CultureInfo culture, object source)
                {
                        throw new NotImplementedException ();
                }
index 179f04a808f53b25e92a0813ba2b5a319346c0f5..af8b91d4269ae98c668177c8d0ac66943e05d11e 100644 (file)
@@ -38,7 +38,7 @@ namespace System.Windows.Markup {
                }
 
                protected internal abstract void AddEventHandler (EventInfo eventInfo, object target, Delegate handler);
-               protected internal abstract Delegate CreateDelegate (Type delegateTYpe, object target, string handler);
+               protected internal abstract Delegate CreateDelegate (Type delegateType, object target, string handler);
                protected internal abstract object CreateInstance (Type type, CultureInfo culture);
                protected internal abstract object GetPropertyValue (PropertyInfo propertyInfo, object target, CultureInfo culture);
                protected internal abstract void SetPropertyValue (PropertyInfo propertyInfo, object target, object value, CultureInfo culture);
index 5934b0a2a045a7fd678d7ea2d7a7375b1d57dc56..00c2be59ddc46b906dfbff2b2d26979599043810 100644 (file)
@@ -28,7 +28,7 @@ using System;
 namespace System.Windows.Media {
 
        [AttributeUsage (AttributeTargets.Assembly, AllowMultiple = false)]
-       public class DisableDpiAwarenessAttribute : Attribute
+       public sealed class DisableDpiAwarenessAttribute : Attribute
        {
        }
 }
index 61ede28a27cbc369b4aedc7ac973873a0cb3f472..e5ab056a14f95f7c45b2720f5b0fd55cb8f4aca0 100644 (file)
@@ -29,7 +29,7 @@ using System.Globalization;
 
 namespace System.Windows.Media {
 
-       public class MatrixConverter : TypeConverter
+       public sealed class MatrixConverter : TypeConverter
        {
                public override bool CanConvertFrom (ITypeDescriptorContext context, Type sourceType)
                {
index 6d17a28d8e3244bdf24288190317c4b269b111bc..031f8081e8783012feefc630e14ac3c86cfb1717 100644 (file)
@@ -119,12 +119,12 @@ namespace System.Windows.Threading {
                                throw new InvalidEnumArgumentException (parameterName);
                }
 
-               public DispatcherOperation BeginInvoke (Delegate method, object[] args)
+               public DispatcherOperation BeginInvoke (Delegate method, params object[] args)
                {
                        throw new NotImplementedException ();
                }
                
-               public DispatcherOperation BeginInvoke (Delegate method, DispatcherPriority priority, object[] args)
+               public DispatcherOperation BeginInvoke (Delegate method, DispatcherPriority priority, params object[] args)
                {
                        throw new NotImplementedException ();
                }
@@ -181,22 +181,22 @@ namespace System.Windows.Threading {
                        return op;
                }
 
-               public object Invoke (Delegate method, object[] args)
+               public object Invoke (Delegate method, params object[] args)
                {
                        throw new NotImplementedException ();
                }
 
-               public object Invoke (Delegate method, TimeSpan timeout, object[] args)
+               public object Invoke (Delegate method, TimeSpan timeout, params object[] args)
                {
                        throw new NotImplementedException ();
                }
 
-               public object Invoke (Delegate method, TimeSpan timeout, DispatcherPriority priority, object[] args)
+               public object Invoke (Delegate method, TimeSpan timeout, DispatcherPriority priority, params object[] args)
                {
                        throw new NotImplementedException ();
                }
 
-               public object Invoke (Delegate method, DispatcherPriority priority, object[] args)
+               public object Invoke (Delegate method, DispatcherPriority priority, params object[] args)
                {
                        throw new NotImplementedException ();
                }
index e914b94aa991119314b9e5d2de3179cffc446b6f..d62c3aae149837f922e184bc04c451d186362e8e 100644 (file)
@@ -29,7 +29,7 @@ using System.Threading;
 
 namespace System.Windows.Threading {
 
-       public class DispatcherSynchronizationContext : SynchronizationContext
+       public sealed class DispatcherSynchronizationContext : SynchronizationContext
        {
                public DispatcherSynchronizationContext ()
                {
index e8280d4f9fb237e6432ed88d0839120ee046d4c0..53ec8ab222b9b47d26574f66f3c86863fb108ab1 100644 (file)
@@ -71,9 +71,9 @@ namespace System.Windows {
                        return dot;
                }
 
-               public bool IsInstanceOfType(DependencyObject d)
+               public bool IsInstanceOfType(DependencyObject dependencyObject)
                {
-                       return systemType.IsInstanceOfType (d);
+                       return systemType.IsInstanceOfType (dependencyObject);
                }
 
                public bool IsSubclassOf(DependencyObjectType dependencyObjectType)
index 3f968eaa83acf96da4f871385ccee0410a0d7d4e..71a1ead1f9732643e35c493be9645dd0eca67bc5 100644 (file)
@@ -80,10 +80,10 @@ namespace System.Windows {
                        return null;
                }
 
-               public PropertyMetadata GetMetadata(DependencyObject d)
+               public PropertyMetadata GetMetadata(DependencyObject dependencyObject)
                {
-                       if (metadataByType.ContainsKey (d.GetType()))
-                               return metadataByType[d.GetType()];
+                       if (metadataByType.ContainsKey (dependencyObject.GetType()))
+                               return metadataByType[dependencyObject.GetType()];
                        return null;
                }
 
index 1784e65adb55249213b16b92c9401ac990d93e36..e5296c6f1d8e141969d3efa65bb16f2f43d52466 100644 (file)
@@ -163,9 +163,9 @@ namespace System.Windows {
                        return this.ToString(null, null);
                }
 
-               public string ToString (IFormatProvider formatProvider)
+               public string ToString (IFormatProvider provider)
                {
-                       return this.ToString(null,formatProvider);
+                       return this.ToString(null, provider);
                }
 
                private string ToString(string format,IFormatProvider formatProvider)
index 260348daaf235ae1b03041d51534232427ae633d..4cf00e73576b78c9d2c2507d65be3dda6efd4f73 100644 (file)
@@ -88,12 +88,12 @@ namespace System.Windows {
                        height = size.Height;
                }
 
-               public bool Equals (Rect rect)
+               public bool Equals (Rect value)
                {
-                       return (x == rect.X &&
-                               y == rect.Y &&
-                               width == rect.Width &&
-                               height == rect.Height);
+                       return (x == value.X &&
+                               y == value.Y &&
+                               width == value.Width &&
+                               height == value.Height);
                }
 
                public static bool operator != (Rect rect1, Rect rect2)
@@ -147,9 +147,9 @@ namespace System.Windows {
                        return true;
                }
 
-               public bool Contains (Point p)
+               public bool Contains (Point point)
                {
-                       return Contains (p.X, p.Y);
+                       return Contains (point.X, point.Y);
                }
 
                public static Rect Inflate (Rect rect, double width, double height)
index d5345f59d40e61b7fda7fd35bc327a6428f0b9c6..9e45b1a81d1f1199dcdb077998b6796e8ddac8db 100644 (file)
@@ -79,7 +79,7 @@ namespace System.Windows {
                        return String.Format ("{0},{1}", width, height);
                }
 
-               public string ToString (IFormatProvider formatProvider)
+               public string ToString (IFormatProvider provider)
                {
                        throw new NotImplementedException ();
                }
index 4b29fb153e197b91a10b92035ff9e8b5ac41a992..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
@@ -125,4 +125,5 @@ EXTRA_DISTFILES += \
        $(vtsdir)/$(vts)TestLib/3.0/Address.cs \
        $(vtsdir)/$(vts)TestLib/4.0/Address.cs \
        $(vtsdir)/$(vts)TestLib/5.0/Address.cs \
+       $(vtsdir)/$(vts)TestLib/6.0/Address.cs \
        $(vtsdir)/BinarySerializationOverVersions.cs
index cb8bfb23266dd8e3978abcdc186c193f37e4c070..b85512ed2cbd3066d657febac25517b53956aae0 100644 (file)
@@ -565,14 +565,13 @@ namespace Microsoft.Win32
 #endif
 
                [ComVisible (false)]
-               [MonoLimitation ("permissionCheck is ignored in Mono")]
                public RegistryKey OpenSubKey (string name, RegistryKeyPermissionCheck permissionCheck)
                {
                        return OpenSubKey (name, permissionCheck == RegistryKeyPermissionCheck.ReadWriteSubTree);
                }
                
                [ComVisible (false)]
-               [MonoLimitation ("permissionCheck and rights are ignored in Mono")]
+               [MonoLimitation ("rights are ignored in Mono")]
                public RegistryKey OpenSubKey (string name, RegistryKeyPermissionCheck permissionCheck, RegistryRights rights)
                {
                        return OpenSubKey (name, permissionCheck == RegistryKeyPermissionCheck.ReadWriteSubTree);
index 6cf82682f7be2d92c319b1be2931d1a375bfd17d..ca979eec32c39318131cd5a3954727c113fb9208 100644 (file)
@@ -408,7 +408,7 @@ namespace Mono.Security.Cryptography {
                                Buffer.BlockCopy (C, 0, toBeHashed, mgfSeedLength, 4);
                                byte[] output = hash.ComputeHash (toBeHashed);
                                Buffer.BlockCopy (output, 0, T, pos, hLen);
-                               pos += mgfSeedLength;
+                               pos += hLen;
                        }
                        
                        // 4. Output the leading maskLen octets of T as the octet string mask.
index 0695e4a2249001646bce6000a4efab3b497dc3f2..4bc72182f7679e586aab36bdc8021c1ff7a8f59d 100644 (file)
@@ -764,7 +764,7 @@ namespace System.IO.IsolatedStorage {
                        return Directory.GetLastWriteTime (full_path);
                }
 #endif
-
+               
                public string[] GetDirectoryNames (string searchPattern)
                {
                        if (searchPattern == null)
@@ -782,16 +782,25 @@ namespace System.IO.IsolatedStorage {
                        if (path == null || path.Length == 0) {
                                adi = directory.GetDirectories (searchPattern);
                        } else {
-                               DirectoryInfo[] subdirs = directory.GetDirectories (path);
                                // we're looking for a single result, identical to path (no pattern here)
+                               DirectoryInfo[] subdirs = directory.GetDirectories (path);
+                               DirectoryInfo di = subdirs [0];
                                // we're also looking for something under the current path (not outside isolated storage)
-                               if ((subdirs.Length == 1) && (subdirs [0].Name == path) && (subdirs [0].FullName.IndexOf (directory.FullName) >= 0)) {
-                                       adi = subdirs [0].GetDirectories (pattern);
-                               } else {
-                                       // CAS, even in FullTrust, normally enforce IsolatedStorage
-                                       throw new SecurityException ();
+                               if (di.FullName.IndexOf (directory.FullName) >= 0) {
+                                       adi = di.GetDirectories (pattern);
+                                       string[] segments = path.Split (new char [] { Path.DirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries);
+                                       for (int i = segments.Length - 1; i >= 0; i--) {
+                                               if (di.Name != segments [i]) {
+                                                       adi = null;
+                                                       break;
+                                               }
+                                               di = di.Parent;
+                                       }
                                }
                        }
+                       // CAS, even in FullTrust, normally enforce IsolatedStorage
+                       if (adi == null)
+                               throw new SecurityException ();
                         
                        return GetNames (adi);
                }
@@ -989,7 +998,7 @@ namespace System.IO.IsolatedStorage {
                        return Path.GetFullPath (path).StartsWith (directory.FullName);
                }
 #endif
-               
+
 #if !MOBILE
                private string GetNameFromIdentity (object identity)
                {
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 66d18aeb0ec35bfeb16d3602f41c275f41e97b74..a8e76b48e01f8e6a2d2309371b571096e031dbff 100644 (file)
@@ -125,7 +125,10 @@ public class PasswordDeriveBytes : DeriveBytes {
                        initial = null;
                }
                // zeroize temporary password storage
-               Array.Clear (password, 0, password.Length);
+               if (password != null) {
+                       Array.Clear (password, 0, password.Length);
+                       password = null;
+               }
 #if NET_4_0
                base.Dispose (disposing);
 #endif
index f92a6a54f54d962b15b9df9cc7f989b77c679bf5..511e35d146d770552607ce2816417d378c4faec2 100644 (file)
@@ -71,1386 +71,6 @@ namespace System.Security.Cryptography {
                        return new RijndaelManagedTransform (this, true, rgbKey, rgbIV);
                }
        }
-       
-       
-       internal class RijndaelTransform : SymmetricTransform
-       {
-               private uint[] expandedKey;
-       
-               private int Nb;
-               private int Nk;
-               private int Nr;
-       
-               public RijndaelTransform (Rijndael algo, bool encryption, byte[] key, byte[] iv) : base (algo, encryption, iv)
-               {
-                       if (key == null)
-                               throw new CryptographicException ("key is null");
-                       if ((iv != null) && (iv.Length != (algo.BlockSize >> 3))) {
-                               string msg = Locale.GetText ("IV length is invalid ({0} bytes), it should be {1} bytes long.",
-                                       iv.Length, (algo.BlockSize >> 3));
-                               throw new CryptographicException (msg);
-                       }
-
-                       int keySize = key.Length;
-                       if (keySize != 16 && keySize != 24 && keySize != 32) {
-                               string msg = Locale.GetText ("Key is too small ({0} bytes), it should be {1}, {2} or {3} bytes long.",
-                                       keySize, 16, 24, 32);
-                               throw new CryptographicException (msg);
-                       }
-                       keySize <<= 3; // bytes -> bits
-                       int blockSize = algo.BlockSize;
-
-                       this.Nb = (blockSize >> 5); // div 32
-                       this.Nk = (keySize >> 5); // div 32
-       
-                       if (Nb == 8 || Nk == 8) {
-                               Nr = 14;
-                       } else if (Nb == 6 || Nk == 6) {
-                               Nr = 12;
-                       } else {
-                               Nr = 10;
-                       }
-       
-                       // Setup Expanded Key
-                       int exKeySize = Nb * (Nr+1);
-                       UInt32[] exKey = new UInt32[exKeySize];
-                       int pos = 0;
-                       for (int i=0; i < Nk; i++) {
-                               UInt32 value = ((UInt32)key [pos++] << 24);
-                               value |= ((UInt32)key[pos++] << 16);
-                               value |= ((UInt32)key[pos++] << 8);
-                               value |= ((UInt32)key[pos++]);
-                               exKey [i] = value;
-                       }
-       
-                       for (int i = Nk; i < exKeySize; i++) {
-                               UInt32 temp = exKey [i-1];
-                               if (i % Nk == 0) {
-                                       UInt32 rot = (UInt32) ((temp << 8) | ((temp >> 24) & 0xff));
-                                       temp = SubByte (rot) ^ Rcon [i / Nk];
-                               } else if (Nk > 6 && (i % Nk) == 4) {
-                                       temp = SubByte (temp);
-                               }
-                               exKey [i] = exKey [i-Nk] ^ temp;
-                       }
-
-                       if (!encryption && (algo.Mode == CipherMode.ECB || algo.Mode == CipherMode.CBC)) {
-                               for (int i = 0, k = exKeySize - Nb; i < k; i += Nb, k -= Nb) {
-                                       for (int j = 0; j < Nb; j ++) {
-                                               uint temp = exKey[i + j];
-                                               exKey[i + j] = exKey[k + j];
-                                               exKey[k + j] = temp;
-                                       }
-                               }
-
-                               for (int i = Nb; i < exKey.Length - Nb; i ++) {
-                                       exKey[i] =
-                                               iT0[SBox[(exKey[i] >> 24)]] ^
-                                               iT1[SBox[(byte)(exKey[i] >> 16)]] ^
-                                               iT2[SBox[(byte)(exKey[i] >> 8)]] ^
-                                               iT3[SBox[(byte)exKey[i]]];
-                               }
-                       }
-                       expandedKey = exKey;
-               }
-
-               public void Clear () 
-               {
-                       Dispose (true);
-               }
-       
-               // note: this method is guaranteed to be called with a valid blocksize
-               // for both input and output
-               protected override void ECB (byte[] input, byte[] output) 
-               {
-                       if (encrypt) {
-                               switch (Nb) {
-                                       case 4:
-                                               Encrypt128 (input, output, expandedKey);
-                                               return;
-                                       case 6:
-                                               Encrypt192 (input, output, expandedKey);
-                                               return;
-                                       case 8:
-                                               Encrypt256 (input, output, expandedKey);
-                                               return;
-                               }
-                       } else {
-                               switch (Nb) {
-                                       case 4:
-                                               Decrypt128 (input, output, expandedKey);
-                                               return;
-                                       case 6:
-                                               Decrypt192 (input, output, expandedKey);
-                                               return;
-                                       case 8:
-                                               Decrypt256 (input, output, expandedKey);
-                                               return;
-                               }
-                       }
-               }
-
-               private UInt32 SubByte (UInt32 a)
-               {
-                       UInt32 value = 0xff & a;
-                       UInt32 result = SBox[value];
-                       value = 0xff & (a >> 8);
-                       result |= (UInt32)SBox[value] << 8;
-                       value = 0xff & (a >> 16);
-                       result |= (UInt32)SBox[value] << 16;
-                       value = 0xff & (a >> 24);
-                       return result | (UInt32)(SBox[value] << 24);
-               }
-
-               #region Encrypt
-               private void Encrypt128 (byte[] indata, byte[] outdata, uint[] ekey)
-               {
-                       uint a0, a1, a2, a3, b0, b1, b2, b3;
-                       int ei = 40;
-
-                       /* Round 0 */
-                       a0 = (((uint)indata[0] << 24) | ((uint)indata[1] << 16) | ((uint)indata[2] << 8) | (uint)indata[3]) ^ ekey[0];
-                       a1 = (((uint)indata[4] << 24) | ((uint)indata[5] << 16) | ((uint)indata[6] << 8) | (uint)indata[7]) ^ ekey[1];
-                       a2 = (((uint)indata[8] << 24) | ((uint)indata[9] << 16) | ((uint)indata[10] << 8) | (uint)indata[11]) ^ ekey[2];
-                       a3 = (((uint)indata[12] << 24) | ((uint)indata[13] << 16) | ((uint)indata[14] << 8) | (uint)indata[15]) ^ ekey[3];
-
-                       /* Round 1 */
-                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[4];
-                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a0] ^ ekey[5];
-                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[6];
-                       b3 = T0[a3 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[7];
-
-                       /* Round 2 */
-                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[8];
-                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b0] ^ ekey[9];
-                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[10];
-                       a3 = T0[b3 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[11];
-
-                       /* Round 3 */
-                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[12];
-                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a0] ^ ekey[13];
-                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[14];
-                       b3 = T0[a3 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[15];
-
-                       /* Round 4 */
-                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[16];
-                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b0] ^ ekey[17];
-                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[18];
-                       a3 = T0[b3 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[19];
-
-                       /* Round 5 */
-                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[20];
-                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a0] ^ ekey[21];
-                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[22];
-                       b3 = T0[a3 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[23];
-
-                       /* Round 6 */
-                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[24];
-                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b0] ^ ekey[25];
-                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[26];
-                       a3 = T0[b3 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[27];
-
-                       /* Round 7 */
-                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[28];
-                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a0] ^ ekey[29];
-                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[30];
-                       b3 = T0[a3 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[31];
-
-                       /* Round 8 */
-                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[32];
-                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b0] ^ ekey[33];
-                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[34];
-                       a3 = T0[b3 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[35];
-
-                       /* Round 9 */
-                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[36];
-                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a0] ^ ekey[37];
-                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[38];
-                       b3 = T0[a3 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[39];
-
-                       if (Nr > 10) {
-
-                               /* Round 10 */
-                               a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[40];
-                               a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b0] ^ ekey[41];
-                               a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[42];
-                               a3 = T0[b3 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[43];
-
-                               /* Round 11 */
-                               b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[44];
-                               b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a0] ^ ekey[45];
-                               b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[46];
-                               b3 = T0[a3 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[47];
-
-                               ei = 48;
-
-                               if (Nr > 12) {
-
-                                       /* Round 12 */
-                                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[48];
-                                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b0] ^ ekey[49];
-                                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[50];
-                                       a3 = T0[b3 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[51];
-
-                                       /* Round 13 */
-                                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[52];
-                                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a0] ^ ekey[53];
-                                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[54];
-                                       b3 = T0[a3 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[55];
-
-                                       ei = 56;
-                               }
-                       }
-
-                       /* Final Round */
-                       outdata[0] = (byte)(SBox[b0 >> 24] ^ (byte)(ekey[ei] >> 24));
-                       outdata[1] = (byte)(SBox[(byte)(b1 >> 16)] ^ (byte)(ekey[ei] >> 16));
-                       outdata[2] = (byte)(SBox[(byte)(b2 >> 8)] ^ (byte)(ekey[ei] >> 8));
-                       outdata[3] = (byte)(SBox[(byte)b3] ^ (byte)ekey[ei++]);
-
-                       outdata[4] = (byte)(SBox[b1 >> 24] ^ (byte)(ekey[ei] >> 24));
-                       outdata[5] = (byte)(SBox[(byte)(b2 >> 16)] ^ (byte)(ekey[ei] >> 16));
-                       outdata[6] = (byte)(SBox[(byte)(b3 >> 8)] ^ (byte)(ekey[ei] >> 8));
-                       outdata[7] = (byte)(SBox[(byte)b0] ^ (byte)ekey[ei++]);
-
-                       outdata[8] = (byte)(SBox[b2 >> 24] ^ (byte)(ekey[ei] >> 24));
-                       outdata[9] = (byte)(SBox[(byte)(b3 >> 16)] ^ (byte)(ekey[ei] >> 16));
-                       outdata[10] = (byte)(SBox[(byte)(b0 >> 8)] ^ (byte)(ekey[ei] >> 8));
-                       outdata[11] = (byte)(SBox[(byte)b1] ^ (byte)ekey[ei++]);
-
-                       outdata[12] = (byte)(SBox[b3 >> 24] ^ (byte)(ekey[ei] >> 24));
-                       outdata[13] = (byte)(SBox[(byte)(b0 >> 16)] ^ (byte)(ekey[ei] >> 16));
-                       outdata[14] = (byte)(SBox[(byte)(b1 >> 8)] ^ (byte)(ekey[ei] >> 8));
-                       outdata[15] = (byte)(SBox[(byte)b2] ^ (byte)ekey[ei++]);
-               }
-               private void Encrypt192 (byte[] indata, byte[] outdata, uint[] ekey)
-               {
-                       uint a0, a1, a2, a3, a4, a5, b0, b1, b2, b3, b4, b5;
-                       int ei = 72;
-
-                       /* Round 0 */
-                       a0 = (((uint)indata[0] << 24) | ((uint)indata[1] << 16) | ((uint)indata[2] << 8) | (uint)indata[3]) ^ ekey[0];
-                       a1 = (((uint)indata[4] << 24) | ((uint)indata[5] << 16) | ((uint)indata[6] << 8) | (uint)indata[7]) ^ ekey[1];
-                       a2 = (((uint)indata[8] << 24) | ((uint)indata[9] << 16) | ((uint)indata[10] << 8) | (uint)indata[11]) ^ ekey[2];
-                       a3 = (((uint)indata[12] << 24) | ((uint)indata[13] << 16) | ((uint)indata[14] << 8) | (uint)indata[15]) ^ ekey[3];
-                       a4 = (((uint)indata[16] << 24) | ((uint)indata[17] << 16) | ((uint)indata[18] << 8) | (uint)indata[19]) ^ ekey[4];
-                       a5 = (((uint)indata[20] << 24) | ((uint)indata[21] << 16) | ((uint)indata[22] << 8) | (uint)indata[23]) ^ ekey[5];
-
-                       /* Round 1 */
-                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[6];
-                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a4] ^ ekey[7];
-                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a4 >> 8)] ^ T3[(byte)a5] ^ ekey[8];
-                       b3 = T0[a3 >> 24] ^ T1[(byte)(a4 >> 16)] ^ T2[(byte)(a5 >> 8)] ^ T3[(byte)a0] ^ ekey[9];
-                       b4 = T0[a4 >> 24] ^ T1[(byte)(a5 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[10];
-                       b5 = T0[a5 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[11];
-
-                       /* Round 2 */
-                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[12];
-                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b4] ^ ekey[13];
-                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b4 >> 8)] ^ T3[(byte)b5] ^ ekey[14];
-                       a3 = T0[b3 >> 24] ^ T1[(byte)(b4 >> 16)] ^ T2[(byte)(b5 >> 8)] ^ T3[(byte)b0] ^ ekey[15];
-                       a4 = T0[b4 >> 24] ^ T1[(byte)(b5 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[16];
-                       a5 = T0[b5 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[17];
-
-                       /* Round 3 */
-                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[18];
-                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a4] ^ ekey[19];
-                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a4 >> 8)] ^ T3[(byte)a5] ^ ekey[20];
-                       b3 = T0[a3 >> 24] ^ T1[(byte)(a4 >> 16)] ^ T2[(byte)(a5 >> 8)] ^ T3[(byte)a0] ^ ekey[21];
-                       b4 = T0[a4 >> 24] ^ T1[(byte)(a5 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[22];
-                       b5 = T0[a5 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[23];
-
-                       /* Round 4 */
-                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[24];
-                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b4] ^ ekey[25];
-                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b4 >> 8)] ^ T3[(byte)b5] ^ ekey[26];
-                       a3 = T0[b3 >> 24] ^ T1[(byte)(b4 >> 16)] ^ T2[(byte)(b5 >> 8)] ^ T3[(byte)b0] ^ ekey[27];
-                       a4 = T0[b4 >> 24] ^ T1[(byte)(b5 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[28];
-                       a5 = T0[b5 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[29];
-
-                       /* Round 5 */
-                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[30];
-                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a4] ^ ekey[31];
-                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a4 >> 8)] ^ T3[(byte)a5] ^ ekey[32];
-                       b3 = T0[a3 >> 24] ^ T1[(byte)(a4 >> 16)] ^ T2[(byte)(a5 >> 8)] ^ T3[(byte)a0] ^ ekey[33];
-                       b4 = T0[a4 >> 24] ^ T1[(byte)(a5 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[34];
-                       b5 = T0[a5 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[35];
-
-                       /* Round 6 */
-                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[36];
-                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b4] ^ ekey[37];
-                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b4 >> 8)] ^ T3[(byte)b5] ^ ekey[38];
-                       a3 = T0[b3 >> 24] ^ T1[(byte)(b4 >> 16)] ^ T2[(byte)(b5 >> 8)] ^ T3[(byte)b0] ^ ekey[39];
-                       a4 = T0[b4 >> 24] ^ T1[(byte)(b5 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[40];
-                       a5 = T0[b5 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[41];
-
-                       /* Round 7 */
-                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[42];
-                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a4] ^ ekey[43];
-                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a4 >> 8)] ^ T3[(byte)a5] ^ ekey[44];
-                       b3 = T0[a3 >> 24] ^ T1[(byte)(a4 >> 16)] ^ T2[(byte)(a5 >> 8)] ^ T3[(byte)a0] ^ ekey[45];
-                       b4 = T0[a4 >> 24] ^ T1[(byte)(a5 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[46];
-                       b5 = T0[a5 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[47];
-
-                       /* Round 8 */
-                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[48];
-                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b4] ^ ekey[49];
-                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b4 >> 8)] ^ T3[(byte)b5] ^ ekey[50];
-                       a3 = T0[b3 >> 24] ^ T1[(byte)(b4 >> 16)] ^ T2[(byte)(b5 >> 8)] ^ T3[(byte)b0] ^ ekey[51];
-                       a4 = T0[b4 >> 24] ^ T1[(byte)(b5 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[52];
-                       a5 = T0[b5 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[53];
-
-                       /* Round 9 */
-                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[54];
-                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a4] ^ ekey[55];
-                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a4 >> 8)] ^ T3[(byte)a5] ^ ekey[56];
-                       b3 = T0[a3 >> 24] ^ T1[(byte)(a4 >> 16)] ^ T2[(byte)(a5 >> 8)] ^ T3[(byte)a0] ^ ekey[57];
-                       b4 = T0[a4 >> 24] ^ T1[(byte)(a5 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[58];
-                       b5 = T0[a5 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[59];
-
-                       /* Round 10 */
-                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[60];
-                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b4] ^ ekey[61];
-                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b4 >> 8)] ^ T3[(byte)b5] ^ ekey[62];
-                       a3 = T0[b3 >> 24] ^ T1[(byte)(b4 >> 16)] ^ T2[(byte)(b5 >> 8)] ^ T3[(byte)b0] ^ ekey[63];
-                       a4 = T0[b4 >> 24] ^ T1[(byte)(b5 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[64];
-                       a5 = T0[b5 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[65];
-
-                       /* Round 11 */
-                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[66];
-                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a4] ^ ekey[67];
-                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a4 >> 8)] ^ T3[(byte)a5] ^ ekey[68];
-                       b3 = T0[a3 >> 24] ^ T1[(byte)(a4 >> 16)] ^ T2[(byte)(a5 >> 8)] ^ T3[(byte)a0] ^ ekey[69];
-                       b4 = T0[a4 >> 24] ^ T1[(byte)(a5 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[70];
-                       b5 = T0[a5 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[71];
-
-                       if (Nr > 12) {
-
-                               /* Round 12 */
-                               a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[72];
-                               a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b4] ^ ekey[73];
-                               a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b4 >> 8)] ^ T3[(byte)b5] ^ ekey[74];
-                               a3 = T0[b3 >> 24] ^ T1[(byte)(b4 >> 16)] ^ T2[(byte)(b5 >> 8)] ^ T3[(byte)b0] ^ ekey[75];
-                               a4 = T0[b4 >> 24] ^ T1[(byte)(b5 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[76];
-                               a5 = T0[b5 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[77];
-
-                               /* Round 13 */
-                               b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[78];
-                               b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a4] ^ ekey[79];
-                               b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a4 >> 8)] ^ T3[(byte)a5] ^ ekey[80];
-                               b3 = T0[a3 >> 24] ^ T1[(byte)(a4 >> 16)] ^ T2[(byte)(a5 >> 8)] ^ T3[(byte)a0] ^ ekey[81];
-                               b4 = T0[a4 >> 24] ^ T1[(byte)(a5 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[82];
-                               b5 = T0[a5 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[83];
-
-                               ei = 84;
-                       }
-
-                       /* Final Round */
-                       outdata[0] = (byte)(SBox[b0 >> 24] ^ (byte)(ekey[ei] >> 24));
-                       outdata[1] = (byte)(SBox[(byte)(b1 >> 16)] ^ (byte)(ekey[ei] >> 16));
-                       outdata[2] = (byte)(SBox[(byte)(b2 >> 8)] ^ (byte)(ekey[ei] >> 8));
-                       outdata[3] = (byte)(SBox[(byte)b3] ^ (byte)ekey[ei++]);
-
-                       outdata[4] = (byte)(SBox[b1 >> 24] ^ (byte)(ekey[ei] >> 24));
-                       outdata[5] = (byte)(SBox[(byte)(b2 >> 16)] ^ (byte)(ekey[ei] >> 16));
-                       outdata[6] = (byte)(SBox[(byte)(b3 >> 8)] ^ (byte)(ekey[ei] >> 8));
-                       outdata[7] = (byte)(SBox[(byte)b4] ^ (byte)ekey[ei++]);
-
-                       outdata[8] = (byte)(SBox[b2 >> 24] ^ (byte)(ekey[ei] >> 24));
-                       outdata[9] = (byte)(SBox[(byte)(b3 >> 16)] ^ (byte)(ekey[ei] >> 16));
-                       outdata[10] = (byte)(SBox[(byte)(b4 >> 8)] ^ (byte)(ekey[ei] >> 8));
-                       outdata[11] = (byte)(SBox[(byte)b5] ^ (byte)ekey[ei++]);
-
-                       outdata[12] = (byte)(SBox[b3 >> 24] ^ (byte)(ekey[ei] >> 24));
-                       outdata[13] = (byte)(SBox[(byte)(b4 >> 16)] ^ (byte)(ekey[ei] >> 16));
-                       outdata[14] = (byte)(SBox[(byte)(b5 >> 8)] ^ (byte)(ekey[ei] >> 8));
-                       outdata[15] = (byte)(SBox[(byte)b0] ^ (byte)ekey[ei++]);
-
-                       outdata[16] = (byte)(SBox[b4 >> 24] ^ (byte)(ekey[ei] >> 24));
-                       outdata[17] = (byte)(SBox[(byte)(b5 >> 16)] ^ (byte)(ekey[ei] >> 16));
-                       outdata[18] = (byte)(SBox[(byte)(b0 >> 8)] ^ (byte)(ekey[ei] >> 8));
-                       outdata[19] = (byte)(SBox[(byte)b1] ^ (byte)ekey[ei++]);
-
-                       outdata[20] = (byte)(SBox[b5 >> 24] ^ (byte)(ekey[ei] >> 24));
-                       outdata[21] = (byte)(SBox[(byte)(b0 >> 16)] ^ (byte)(ekey[ei] >> 16));
-                       outdata[22] = (byte)(SBox[(byte)(b1 >> 8)] ^ (byte)(ekey[ei] >> 8));
-                       outdata[23] = (byte)(SBox[(byte)b2] ^ (byte)ekey[ei++]);
-               }
-               private void Encrypt256 (byte[] indata, byte[] outdata, uint[] ekey)
-               {
-                       uint a0, a1, a2, a3, a4, a5, a6, a7, b0, b1, b2, b3, b4, b5, b6, b7;
-
-                       /* Round 0 */
-                       a0 = (((uint)indata[0] << 24) | ((uint)indata[1] << 16) | ((uint)indata[2] << 8) | (uint)indata[3]) ^ ekey[0];
-                       a1 = (((uint)indata[4] << 24) | ((uint)indata[5] << 16) | ((uint)indata[6] << 8) | (uint)indata[7]) ^ ekey[1];
-                       a2 = (((uint)indata[8] << 24) | ((uint)indata[9] << 16) | ((uint)indata[10] << 8) | (uint)indata[11]) ^ ekey[2];
-                       a3 = (((uint)indata[12] << 24) | ((uint)indata[13] << 16) | ((uint)indata[14] << 8) | (uint)indata[15]) ^ ekey[3];
-                       a4 = (((uint)indata[16] << 24) | ((uint)indata[17] << 16) | ((uint)indata[18] << 8) | (uint)indata[19]) ^ ekey[4];
-                       a5 = (((uint)indata[20] << 24) | ((uint)indata[21] << 16) | ((uint)indata[22] << 8) | (uint)indata[23]) ^ ekey[5];
-                       a6 = (((uint)indata[24] << 24) | ((uint)indata[25] << 16) | ((uint)indata[26] << 8) | (uint)indata[27]) ^ ekey[6];
-                       a7 = (((uint)indata[28] << 24) | ((uint)indata[29] << 16) | ((uint)indata[30] << 8) | (uint)indata[31]) ^ ekey[7];
-
-                       /* Round 1 */
-                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a4] ^ ekey[8];
-                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a4 >> 8)] ^ T3[(byte)a5] ^ ekey[9];
-                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a5 >> 8)] ^ T3[(byte)a6] ^ ekey[10];
-                       b3 = T0[a3 >> 24] ^ T1[(byte)(a4 >> 16)] ^ T2[(byte)(a6 >> 8)] ^ T3[(byte)a7] ^ ekey[11];
-                       b4 = T0[a4 >> 24] ^ T1[(byte)(a5 >> 16)] ^ T2[(byte)(a7 >> 8)] ^ T3[(byte)a0] ^ ekey[12];
-                       b5 = T0[a5 >> 24] ^ T1[(byte)(a6 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[13];
-                       b6 = T0[a6 >> 24] ^ T1[(byte)(a7 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[14];
-                       b7 = T0[a7 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[15];
-
-                       /* Round 2 */
-                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b4] ^ ekey[16];
-                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b4 >> 8)] ^ T3[(byte)b5] ^ ekey[17];
-                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b5 >> 8)] ^ T3[(byte)b6] ^ ekey[18];
-                       a3 = T0[b3 >> 24] ^ T1[(byte)(b4 >> 16)] ^ T2[(byte)(b6 >> 8)] ^ T3[(byte)b7] ^ ekey[19];
-                       a4 = T0[b4 >> 24] ^ T1[(byte)(b5 >> 16)] ^ T2[(byte)(b7 >> 8)] ^ T3[(byte)b0] ^ ekey[20];
-                       a5 = T0[b5 >> 24] ^ T1[(byte)(b6 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[21];
-                       a6 = T0[b6 >> 24] ^ T1[(byte)(b7 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[22];
-                       a7 = T0[b7 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[23];
-
-                       /* Round 3 */
-                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a4] ^ ekey[24];
-                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a4 >> 8)] ^ T3[(byte)a5] ^ ekey[25];
-                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a5 >> 8)] ^ T3[(byte)a6] ^ ekey[26];
-                       b3 = T0[a3 >> 24] ^ T1[(byte)(a4 >> 16)] ^ T2[(byte)(a6 >> 8)] ^ T3[(byte)a7] ^ ekey[27];
-                       b4 = T0[a4 >> 24] ^ T1[(byte)(a5 >> 16)] ^ T2[(byte)(a7 >> 8)] ^ T3[(byte)a0] ^ ekey[28];
-                       b5 = T0[a5 >> 24] ^ T1[(byte)(a6 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[29];
-                       b6 = T0[a6 >> 24] ^ T1[(byte)(a7 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[30];
-                       b7 = T0[a7 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[31];
-
-                       /* Round 4 */
-                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b4] ^ ekey[32];
-                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b4 >> 8)] ^ T3[(byte)b5] ^ ekey[33];
-                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b5 >> 8)] ^ T3[(byte)b6] ^ ekey[34];
-                       a3 = T0[b3 >> 24] ^ T1[(byte)(b4 >> 16)] ^ T2[(byte)(b6 >> 8)] ^ T3[(byte)b7] ^ ekey[35];
-                       a4 = T0[b4 >> 24] ^ T1[(byte)(b5 >> 16)] ^ T2[(byte)(b7 >> 8)] ^ T3[(byte)b0] ^ ekey[36];
-                       a5 = T0[b5 >> 24] ^ T1[(byte)(b6 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[37];
-                       a6 = T0[b6 >> 24] ^ T1[(byte)(b7 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[38];
-                       a7 = T0[b7 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[39];
-
-                       /* Round 5 */
-                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a4] ^ ekey[40];
-                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a4 >> 8)] ^ T3[(byte)a5] ^ ekey[41];
-                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a5 >> 8)] ^ T3[(byte)a6] ^ ekey[42];
-                       b3 = T0[a3 >> 24] ^ T1[(byte)(a4 >> 16)] ^ T2[(byte)(a6 >> 8)] ^ T3[(byte)a7] ^ ekey[43];
-                       b4 = T0[a4 >> 24] ^ T1[(byte)(a5 >> 16)] ^ T2[(byte)(a7 >> 8)] ^ T3[(byte)a0] ^ ekey[44];
-                       b5 = T0[a5 >> 24] ^ T1[(byte)(a6 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[45];
-                       b6 = T0[a6 >> 24] ^ T1[(byte)(a7 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[46];
-                       b7 = T0[a7 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[47];
-
-                       /* Round 6 */
-                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b4] ^ ekey[48];
-                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b4 >> 8)] ^ T3[(byte)b5] ^ ekey[49];
-                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b5 >> 8)] ^ T3[(byte)b6] ^ ekey[50];
-                       a3 = T0[b3 >> 24] ^ T1[(byte)(b4 >> 16)] ^ T2[(byte)(b6 >> 8)] ^ T3[(byte)b7] ^ ekey[51];
-                       a4 = T0[b4 >> 24] ^ T1[(byte)(b5 >> 16)] ^ T2[(byte)(b7 >> 8)] ^ T3[(byte)b0] ^ ekey[52];
-                       a5 = T0[b5 >> 24] ^ T1[(byte)(b6 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[53];
-                       a6 = T0[b6 >> 24] ^ T1[(byte)(b7 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[54];
-                       a7 = T0[b7 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[55];
-
-                       /* Round 7 */
-                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a4] ^ ekey[56];
-                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a4 >> 8)] ^ T3[(byte)a5] ^ ekey[57];
-                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a5 >> 8)] ^ T3[(byte)a6] ^ ekey[58];
-                       b3 = T0[a3 >> 24] ^ T1[(byte)(a4 >> 16)] ^ T2[(byte)(a6 >> 8)] ^ T3[(byte)a7] ^ ekey[59];
-                       b4 = T0[a4 >> 24] ^ T1[(byte)(a5 >> 16)] ^ T2[(byte)(a7 >> 8)] ^ T3[(byte)a0] ^ ekey[60];
-                       b5 = T0[a5 >> 24] ^ T1[(byte)(a6 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[61];
-                       b6 = T0[a6 >> 24] ^ T1[(byte)(a7 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[62];
-                       b7 = T0[a7 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[63];
-
-                       /* Round 8 */
-                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b4] ^ ekey[64];
-                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b4 >> 8)] ^ T3[(byte)b5] ^ ekey[65];
-                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b5 >> 8)] ^ T3[(byte)b6] ^ ekey[66];
-                       a3 = T0[b3 >> 24] ^ T1[(byte)(b4 >> 16)] ^ T2[(byte)(b6 >> 8)] ^ T3[(byte)b7] ^ ekey[67];
-                       a4 = T0[b4 >> 24] ^ T1[(byte)(b5 >> 16)] ^ T2[(byte)(b7 >> 8)] ^ T3[(byte)b0] ^ ekey[68];
-                       a5 = T0[b5 >> 24] ^ T1[(byte)(b6 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[69];
-                       a6 = T0[b6 >> 24] ^ T1[(byte)(b7 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[70];
-                       a7 = T0[b7 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[71];
-
-                       /* Round 9 */
-                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a4] ^ ekey[72];
-                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a4 >> 8)] ^ T3[(byte)a5] ^ ekey[73];
-                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a5 >> 8)] ^ T3[(byte)a6] ^ ekey[74];
-                       b3 = T0[a3 >> 24] ^ T1[(byte)(a4 >> 16)] ^ T2[(byte)(a6 >> 8)] ^ T3[(byte)a7] ^ ekey[75];
-                       b4 = T0[a4 >> 24] ^ T1[(byte)(a5 >> 16)] ^ T2[(byte)(a7 >> 8)] ^ T3[(byte)a0] ^ ekey[76];
-                       b5 = T0[a5 >> 24] ^ T1[(byte)(a6 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[77];
-                       b6 = T0[a6 >> 24] ^ T1[(byte)(a7 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[78];
-                       b7 = T0[a7 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[79];
-
-                       /* Round 10 */
-                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b4] ^ ekey[80];
-                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b4 >> 8)] ^ T3[(byte)b5] ^ ekey[81];
-                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b5 >> 8)] ^ T3[(byte)b6] ^ ekey[82];
-                       a3 = T0[b3 >> 24] ^ T1[(byte)(b4 >> 16)] ^ T2[(byte)(b6 >> 8)] ^ T3[(byte)b7] ^ ekey[83];
-                       a4 = T0[b4 >> 24] ^ T1[(byte)(b5 >> 16)] ^ T2[(byte)(b7 >> 8)] ^ T3[(byte)b0] ^ ekey[84];
-                       a5 = T0[b5 >> 24] ^ T1[(byte)(b6 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[85];
-                       a6 = T0[b6 >> 24] ^ T1[(byte)(b7 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[86];
-                       a7 = T0[b7 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[87];
-
-                       /* Round 11 */
-                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a4] ^ ekey[88];
-                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a4 >> 8)] ^ T3[(byte)a5] ^ ekey[89];
-                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a5 >> 8)] ^ T3[(byte)a6] ^ ekey[90];
-                       b3 = T0[a3 >> 24] ^ T1[(byte)(a4 >> 16)] ^ T2[(byte)(a6 >> 8)] ^ T3[(byte)a7] ^ ekey[91];
-                       b4 = T0[a4 >> 24] ^ T1[(byte)(a5 >> 16)] ^ T2[(byte)(a7 >> 8)] ^ T3[(byte)a0] ^ ekey[92];
-                       b5 = T0[a5 >> 24] ^ T1[(byte)(a6 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[93];
-                       b6 = T0[a6 >> 24] ^ T1[(byte)(a7 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[94];
-                       b7 = T0[a7 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[95];
-
-                       /* Round 12 */
-                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b4] ^ ekey[96];
-                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b4 >> 8)] ^ T3[(byte)b5] ^ ekey[97];
-                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b5 >> 8)] ^ T3[(byte)b6] ^ ekey[98];
-                       a3 = T0[b3 >> 24] ^ T1[(byte)(b4 >> 16)] ^ T2[(byte)(b6 >> 8)] ^ T3[(byte)b7] ^ ekey[99];
-                       a4 = T0[b4 >> 24] ^ T1[(byte)(b5 >> 16)] ^ T2[(byte)(b7 >> 8)] ^ T3[(byte)b0] ^ ekey[100];
-                       a5 = T0[b5 >> 24] ^ T1[(byte)(b6 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[101];
-                       a6 = T0[b6 >> 24] ^ T1[(byte)(b7 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[102];
-                       a7 = T0[b7 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[103];
-
-                       /* Round 13 */
-                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a4] ^ ekey[104];
-                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a4 >> 8)] ^ T3[(byte)a5] ^ ekey[105];
-                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a5 >> 8)] ^ T3[(byte)a6] ^ ekey[106];
-                       b3 = T0[a3 >> 24] ^ T1[(byte)(a4 >> 16)] ^ T2[(byte)(a6 >> 8)] ^ T3[(byte)a7] ^ ekey[107];
-                       b4 = T0[a4 >> 24] ^ T1[(byte)(a5 >> 16)] ^ T2[(byte)(a7 >> 8)] ^ T3[(byte)a0] ^ ekey[108];
-                       b5 = T0[a5 >> 24] ^ T1[(byte)(a6 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[109];
-                       b6 = T0[a6 >> 24] ^ T1[(byte)(a7 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[110];
-                       b7 = T0[a7 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[111];
-
-                       /* Final Round */
-                       outdata[0] = (byte)(SBox[b0 >> 24] ^ (byte)(ekey[112] >> 24));
-                       outdata[1] = (byte)(SBox[(byte)(b1 >> 16)] ^ (byte)(ekey[112] >> 16));
-                       outdata[2] = (byte)(SBox[(byte)(b3 >> 8)] ^ (byte)(ekey[112] >> 8));
-                       outdata[3] = (byte)(SBox[(byte)b4] ^ (byte)ekey[112]);
-
-                       outdata[4] = (byte)(SBox[b1 >> 24] ^ (byte)(ekey[113] >> 24));
-                       outdata[5] = (byte)(SBox[(byte)(b2 >> 16)] ^ (byte)(ekey[113] >> 16));
-                       outdata[6] = (byte)(SBox[(byte)(b4 >> 8)] ^ (byte)(ekey[113] >> 8));
-                       outdata[7] = (byte)(SBox[(byte)b5] ^ (byte)ekey[113]);
-
-                       outdata[8] = (byte)(SBox[b2 >> 24] ^ (byte)(ekey[114] >> 24));
-                       outdata[9] = (byte)(SBox[(byte)(b3 >> 16)] ^ (byte)(ekey[114] >> 16));
-                       outdata[10] = (byte)(SBox[(byte)(b5 >> 8)] ^ (byte)(ekey[114] >> 8));
-                       outdata[11] = (byte)(SBox[(byte)b6] ^ (byte)ekey[114]);
-
-                       outdata[12] = (byte)(SBox[b3 >> 24] ^ (byte)(ekey[115] >> 24));
-                       outdata[13] = (byte)(SBox[(byte)(b4 >> 16)] ^ (byte)(ekey[115] >> 16));
-                       outdata[14] = (byte)(SBox[(byte)(b6 >> 8)] ^ (byte)(ekey[115] >> 8));
-                       outdata[15] = (byte)(SBox[(byte)b7] ^ (byte)ekey[115]);
-
-                       outdata[16] = (byte)(SBox[b4 >> 24] ^ (byte)(ekey[116] >> 24));
-                       outdata[17] = (byte)(SBox[(byte)(b5 >> 16)] ^ (byte)(ekey[116] >> 16));
-                       outdata[18] = (byte)(SBox[(byte)(b7 >> 8)] ^ (byte)(ekey[116] >> 8));
-                       outdata[19] = (byte)(SBox[(byte)b0] ^ (byte)ekey[116]);
-
-                       outdata[20] = (byte)(SBox[b5 >> 24] ^ (byte)(ekey[117] >> 24));
-                       outdata[21] = (byte)(SBox[(byte)(b6 >> 16)] ^ (byte)(ekey[117] >> 16));
-                       outdata[22] = (byte)(SBox[(byte)(b0 >> 8)] ^ (byte)(ekey[117] >> 8));
-                       outdata[23] = (byte)(SBox[(byte)b1] ^ (byte)ekey[117]);
-
-                       outdata[24] = (byte)(SBox[b6 >> 24] ^ (byte)(ekey[118] >> 24));
-                       outdata[25] = (byte)(SBox[(byte)(b7 >> 16)] ^ (byte)(ekey[118] >> 16));
-                       outdata[26] = (byte)(SBox[(byte)(b1 >> 8)] ^ (byte)(ekey[118] >> 8));
-                       outdata[27] = (byte)(SBox[(byte)b2] ^ (byte)ekey[118]);
-
-                       outdata[28] = (byte)(SBox[b7 >> 24] ^ (byte)(ekey[119] >> 24));
-                       outdata[29] = (byte)(SBox[(byte)(b0 >> 16)] ^ (byte)(ekey[119] >> 16));
-                       outdata[30] = (byte)(SBox[(byte)(b2 >> 8)] ^ (byte)(ekey[119] >> 8));
-                       outdata[31] = (byte)(SBox[(byte)b3] ^ (byte)ekey[119]);
-               }
-               #endregion
-
-               #region Decrypt
-               private void Decrypt128 (byte[] indata, byte[] outdata, uint[] ekey)
-               {
-                       uint a0, a1, a2, a3, b0, b1, b2, b3;
-                       int ei = 40;
-
-                       /* Round 0 */
-                       a0 = (((uint)indata[0] << 24) | ((uint)indata[1] << 16) | ((uint)indata[2] << 8) | (uint)indata[3]) ^ ekey[0];
-                       a1 = (((uint)indata[4] << 24) | ((uint)indata[5] << 16) | ((uint)indata[6] << 8) | (uint)indata[7]) ^ ekey[1];
-                       a2 = (((uint)indata[8] << 24) | ((uint)indata[9] << 16) | ((uint)indata[10] << 8) | (uint)indata[11]) ^ ekey[2];
-                       a3 = (((uint)indata[12] << 24) | ((uint)indata[13] << 16) | ((uint)indata[14] << 8) | (uint)indata[15]) ^ ekey[3];
-
-                       /* Round 1 */
-                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[4];
-                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[5];
-                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a3] ^ ekey[6];
-                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[7];
-
-                       /* Round 2 */
-                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[8];
-                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[9];
-                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b3] ^ ekey[10];
-                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[11];
-
-                       /* Round 3 */
-                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[12];
-                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[13];
-                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a3] ^ ekey[14];
-                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[15];
-
-                       /* Round 4 */
-                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[16];
-                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[17];
-                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b3] ^ ekey[18];
-                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[19];
-
-                       /* Round 5 */
-                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[20];
-                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[21];
-                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a3] ^ ekey[22];
-                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[23];
-
-                       /* Round 6 */
-                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[24];
-                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[25];
-                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b3] ^ ekey[26];
-                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[27];
-
-                       /* Round 7 */
-                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[28];
-                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[29];
-                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a3] ^ ekey[30];
-                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[31];
-
-                       /* Round 8 */
-                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[32];
-                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[33];
-                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b3] ^ ekey[34];
-                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[35];
-
-                       /* Round 9 */
-                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[36];
-                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[37];
-                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a3] ^ ekey[38];
-                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[39];
-
-                       if (Nr > 10) {
-
-                               /* Round 10 */
-                               a0 = iT0[b0 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[40];
-                               a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[41];
-                               a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b3] ^ ekey[42];
-                               a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[43];
-
-                               /* Round 11 */
-                               b0 = iT0[a0 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[44];
-                               b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[45];
-                               b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a3] ^ ekey[46];
-                               b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[47];
-
-                               ei = 48;
-
-                               if (Nr > 12) {
-
-                                       /* Round 12 */
-                                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[48];
-                                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[49];
-                                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b3] ^ ekey[50];
-                                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[51];
-
-                                       /* Round 13 */
-                                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[52];
-                                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[53];
-                                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a3] ^ ekey[54];
-                                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[55];
-                                       
-                                       ei = 56;
-                               }
-                       }
-
-                       /* Final Round */
-                       outdata[0] = (byte)(iSBox[b0 >> 24] ^ (byte)(ekey[ei] >> 24));
-                       outdata[1] = (byte)(iSBox[(byte)(b3 >> 16)] ^ (byte)(ekey[ei] >> 16));
-                       outdata[2] = (byte)(iSBox[(byte)(b2 >> 8)] ^ (byte)(ekey[ei] >> 8));
-                       outdata[3] = (byte)(iSBox[(byte)b1] ^ (byte)ekey[ei++]);
-
-                       outdata[4] = (byte)(iSBox[b1 >> 24] ^ (byte)(ekey[ei] >> 24));
-                       outdata[5] = (byte)(iSBox[(byte)(b0 >> 16)] ^ (byte)(ekey[ei] >> 16));
-                       outdata[6] = (byte)(iSBox[(byte)(b3 >> 8)] ^ (byte)(ekey[ei] >> 8));
-                       outdata[7] = (byte)(iSBox[(byte)b2] ^ (byte)ekey[ei++]);
-
-                       outdata[8] = (byte)(iSBox[b2 >> 24] ^ (byte)(ekey[ei] >> 24));
-                       outdata[9] = (byte)(iSBox[(byte)(b1 >> 16)] ^ (byte)(ekey[ei] >> 16));
-                       outdata[10] = (byte)(iSBox[(byte)(b0 >> 8)] ^ (byte)(ekey[ei] >> 8));
-                       outdata[11] = (byte)(iSBox[(byte)b3] ^ (byte)ekey[ei++]);
-
-                       outdata[12] = (byte)(iSBox[b3 >> 24] ^ (byte)(ekey[ei] >> 24));
-                       outdata[13] = (byte)(iSBox[(byte)(b2 >> 16)] ^ (byte)(ekey[ei] >> 16));
-                       outdata[14] = (byte)(iSBox[(byte)(b1 >> 8)] ^ (byte)(ekey[ei] >> 8));
-                       outdata[15] = (byte)(iSBox[(byte)b0] ^ (byte)ekey[ei++]);
-               }
-               private void Decrypt192 (byte[] indata, byte[] outdata, uint[] ekey)
-               {
-                       uint a0, a1, a2, a3, a4, a5, b0, b1, b2, b3, b4, b5;
-                       int ei = 72;
-
-                       /* Round 0 */
-                       a0 = (((uint)indata[0] << 24) | ((uint)indata[1] << 16) | ((uint)indata[2] << 8) | (uint)indata[3]) ^ ekey[0];
-                       a1 = (((uint)indata[4] << 24) | ((uint)indata[5] << 16) | ((uint)indata[6] << 8) | (uint)indata[7]) ^ ekey[1];
-                       a2 = (((uint)indata[8] << 24) | ((uint)indata[9] << 16) | ((uint)indata[10] << 8) | (uint)indata[11]) ^ ekey[2];
-                       a3 = (((uint)indata[12] << 24) | ((uint)indata[13] << 16) | ((uint)indata[14] << 8) | (uint)indata[15]) ^ ekey[3];
-                       a4 = (((uint)indata[16] << 24) | ((uint)indata[17] << 16) | ((uint)indata[18] << 8) | (uint)indata[19]) ^ ekey[4];
-                       a5 = (((uint)indata[20] << 24) | ((uint)indata[21] << 16) | ((uint)indata[22] << 8) | (uint)indata[23]) ^ ekey[5];
-
-                       /* Round 1 */
-                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a5 >> 16)] ^ iT2[(byte)(a4 >> 8)] ^ iT3[(byte)a3] ^ ekey[6];
-                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a5 >> 8)] ^ iT3[(byte)a4] ^ ekey[7];
-                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a5] ^ ekey[8];
-                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[9];
-                       b4 = iT0[a4 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[10];
-                       b5 = iT0[a5 >> 24] ^ iT1[(byte)(a4 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[11];
-
-                       /* Round 2 */
-                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b5 >> 16)] ^ iT2[(byte)(b4 >> 8)] ^ iT3[(byte)b3] ^ ekey[12];
-                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b5 >> 8)] ^ iT3[(byte)b4] ^ ekey[13];
-                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b5] ^ ekey[14];
-                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[15];
-                       a4 = iT0[b4 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[16];
-                       a5 = iT0[b5 >> 24] ^ iT1[(byte)(b4 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[17];
-
-                       /* Round 3 */
-                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a5 >> 16)] ^ iT2[(byte)(a4 >> 8)] ^ iT3[(byte)a3] ^ ekey[18];
-                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a5 >> 8)] ^ iT3[(byte)a4] ^ ekey[19];
-                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a5] ^ ekey[20];
-                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[21];
-                       b4 = iT0[a4 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[22];
-                       b5 = iT0[a5 >> 24] ^ iT1[(byte)(a4 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[23];
-
-                       /* Round 4 */
-                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b5 >> 16)] ^ iT2[(byte)(b4 >> 8)] ^ iT3[(byte)b3] ^ ekey[24];
-                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b5 >> 8)] ^ iT3[(byte)b4] ^ ekey[25];
-                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b5] ^ ekey[26];
-                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[27];
-                       a4 = iT0[b4 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[28];
-                       a5 = iT0[b5 >> 24] ^ iT1[(byte)(b4 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[29];
-
-                       /* Round 5 */
-                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a5 >> 16)] ^ iT2[(byte)(a4 >> 8)] ^ iT3[(byte)a3] ^ ekey[30];
-                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a5 >> 8)] ^ iT3[(byte)a4] ^ ekey[31];
-                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a5] ^ ekey[32];
-                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[33];
-                       b4 = iT0[a4 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[34];
-                       b5 = iT0[a5 >> 24] ^ iT1[(byte)(a4 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[35];
-
-                       /* Round 6 */
-                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b5 >> 16)] ^ iT2[(byte)(b4 >> 8)] ^ iT3[(byte)b3] ^ ekey[36];
-                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b5 >> 8)] ^ iT3[(byte)b4] ^ ekey[37];
-                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b5] ^ ekey[38];
-                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[39];
-                       a4 = iT0[b4 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[40];
-                       a5 = iT0[b5 >> 24] ^ iT1[(byte)(b4 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[41];
-
-                       /* Round 7 */
-                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a5 >> 16)] ^ iT2[(byte)(a4 >> 8)] ^ iT3[(byte)a3] ^ ekey[42];
-                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a5 >> 8)] ^ iT3[(byte)a4] ^ ekey[43];
-                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a5] ^ ekey[44];
-                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[45];
-                       b4 = iT0[a4 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[46];
-                       b5 = iT0[a5 >> 24] ^ iT1[(byte)(a4 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[47];
-
-                       /* Round 8 */
-                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b5 >> 16)] ^ iT2[(byte)(b4 >> 8)] ^ iT3[(byte)b3] ^ ekey[48];
-                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b5 >> 8)] ^ iT3[(byte)b4] ^ ekey[49];
-                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b5] ^ ekey[50];
-                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[51];
-                       a4 = iT0[b4 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[52];
-                       a5 = iT0[b5 >> 24] ^ iT1[(byte)(b4 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[53];
-
-                       /* Round 9 */
-                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a5 >> 16)] ^ iT2[(byte)(a4 >> 8)] ^ iT3[(byte)a3] ^ ekey[54];
-                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a5 >> 8)] ^ iT3[(byte)a4] ^ ekey[55];
-                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a5] ^ ekey[56];
-                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[57];
-                       b4 = iT0[a4 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[58];
-                       b5 = iT0[a5 >> 24] ^ iT1[(byte)(a4 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[59];
-
-                       /* Round 10 */
-                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b5 >> 16)] ^ iT2[(byte)(b4 >> 8)] ^ iT3[(byte)b3] ^ ekey[60];
-                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b5 >> 8)] ^ iT3[(byte)b4] ^ ekey[61];
-                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b5] ^ ekey[62];
-                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[63];
-                       a4 = iT0[b4 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[64];
-                       a5 = iT0[b5 >> 24] ^ iT1[(byte)(b4 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[65];
-
-                       /* Round 11 */
-                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a5 >> 16)] ^ iT2[(byte)(a4 >> 8)] ^ iT3[(byte)a3] ^ ekey[66];
-                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a5 >> 8)] ^ iT3[(byte)a4] ^ ekey[67];
-                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a5] ^ ekey[68];
-                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[69];
-                       b4 = iT0[a4 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[70];
-                       b5 = iT0[a5 >> 24] ^ iT1[(byte)(a4 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[71];
-
-                       if (Nr > 12) {
-
-                               /* Round 12 */
-                               a0 = iT0[b0 >> 24] ^ iT1[(byte)(b5 >> 16)] ^ iT2[(byte)(b4 >> 8)] ^ iT3[(byte)b3] ^ ekey[72];
-                               a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b5 >> 8)] ^ iT3[(byte)b4] ^ ekey[73];
-                               a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b5] ^ ekey[74];
-                               a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[75];
-                               a4 = iT0[b4 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[76];
-                               a5 = iT0[b5 >> 24] ^ iT1[(byte)(b4 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[77];
-
-                               /* Round 13 */
-                               b0 = iT0[a0 >> 24] ^ iT1[(byte)(a5 >> 16)] ^ iT2[(byte)(a4 >> 8)] ^ iT3[(byte)a3] ^ ekey[78];
-                               b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a5 >> 8)] ^ iT3[(byte)a4] ^ ekey[79];
-                               b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a5] ^ ekey[80];
-                               b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[81];
-                               b4 = iT0[a4 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[82];
-                               b5 = iT0[a5 >> 24] ^ iT1[(byte)(a4 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[83];
-
-                               ei = 84;
-                       }
-
-                       /* Final Round */
-                       outdata[0] = (byte)(iSBox[b0 >> 24] ^ (byte)(ekey[ei] >> 24));
-                       outdata[1] = (byte)(iSBox[(byte)(b5 >> 16)] ^ (byte)(ekey[ei] >> 16));
-                       outdata[2] = (byte)(iSBox[(byte)(b4 >> 8)] ^ (byte)(ekey[ei] >> 8));
-                       outdata[3] = (byte)(iSBox[(byte)b3] ^ (byte)ekey[ei++]);
-
-                       outdata[4] = (byte)(iSBox[b1 >> 24] ^ (byte)(ekey[ei] >> 24));
-                       outdata[5] = (byte)(iSBox[(byte)(b0 >> 16)] ^ (byte)(ekey[ei] >> 16));
-                       outdata[6] = (byte)(iSBox[(byte)(b5 >> 8)] ^ (byte)(ekey[ei] >> 8));
-                       outdata[7] = (byte)(iSBox[(byte)b4] ^ (byte)ekey[ei++]);
-
-                       outdata[8] = (byte)(iSBox[b2 >> 24] ^ (byte)(ekey[ei] >> 24));
-                       outdata[9] = (byte)(iSBox[(byte)(b1 >> 16)] ^ (byte)(ekey[ei] >> 16));
-                       outdata[10] = (byte)(iSBox[(byte)(b0 >> 8)] ^ (byte)(ekey[ei] >> 8));
-                       outdata[11] = (byte)(iSBox[(byte)b5] ^ (byte)ekey[ei++]);
-
-                       outdata[12] = (byte)(iSBox[b3 >> 24] ^ (byte)(ekey[ei] >> 24));
-                       outdata[13] = (byte)(iSBox[(byte)(b2 >> 16)] ^ (byte)(ekey[ei] >> 16));
-                       outdata[14] = (byte)(iSBox[(byte)(b1 >> 8)] ^ (byte)(ekey[ei] >> 8));
-                       outdata[15] = (byte)(iSBox[(byte)b0] ^ (byte)ekey[ei++]);
-
-                       outdata[16] = (byte)(iSBox[b4 >> 24] ^ (byte)(ekey[ei] >> 24));
-                       outdata[17] = (byte)(iSBox[(byte)(b3 >> 16)] ^ (byte)(ekey[ei] >> 16));
-                       outdata[18] = (byte)(iSBox[(byte)(b2 >> 8)] ^ (byte)(ekey[ei] >> 8));
-                       outdata[19] = (byte)(iSBox[(byte)b1] ^ (byte)ekey[ei++]);
-
-                       outdata[20] = (byte)(iSBox[b5 >> 24] ^ (byte)(ekey[ei] >> 24));
-                       outdata[21] = (byte)(iSBox[(byte)(b4 >> 16)] ^ (byte)(ekey[ei] >> 16));
-                       outdata[22] = (byte)(iSBox[(byte)(b3 >> 8)] ^ (byte)(ekey[ei] >> 8));
-                       outdata[23] = (byte)(iSBox[(byte)b2] ^ (byte)ekey[ei++]);
-               }
-               private void Decrypt256 (byte[] indata, byte[] outdata, uint[] ekey)
-               {
-                       uint a0, a1, a2, a3, a4, a5, a6, a7, b0, b1, b2, b3, b4, b5, b6, b7;
-
-                       /* Round 0 */
-                       a0 = (((uint)indata[0] << 24) | ((uint)indata[1] << 16) | ((uint)indata[2] << 8) | (uint)indata[3]) ^ ekey[0];
-                       a1 = (((uint)indata[4] << 24) | ((uint)indata[5] << 16) | ((uint)indata[6] << 8) | (uint)indata[7]) ^ ekey[1];
-                       a2 = (((uint)indata[8] << 24) | ((uint)indata[9] << 16) | ((uint)indata[10] << 8) | (uint)indata[11]) ^ ekey[2];
-                       a3 = (((uint)indata[12] << 24) | ((uint)indata[13] << 16) | ((uint)indata[14] << 8) | (uint)indata[15]) ^ ekey[3];
-                       a4 = (((uint)indata[16] << 24) | ((uint)indata[17] << 16) | ((uint)indata[18] << 8) | (uint)indata[19]) ^ ekey[4];
-                       a5 = (((uint)indata[20] << 24) | ((uint)indata[21] << 16) | ((uint)indata[22] << 8) | (uint)indata[23]) ^ ekey[5];
-                       a6 = (((uint)indata[24] << 24) | ((uint)indata[25] << 16) | ((uint)indata[26] << 8) | (uint)indata[27]) ^ ekey[6];
-                       a7 = (((uint)indata[28] << 24) | ((uint)indata[29] << 16) | ((uint)indata[30] << 8) | (uint)indata[31]) ^ ekey[7];
-
-                       /* Round 1 */
-                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a7 >> 16)] ^ iT2[(byte)(a5 >> 8)] ^ iT3[(byte)a4] ^ ekey[8];
-                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a6 >> 8)] ^ iT3[(byte)a5] ^ ekey[9];
-                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a7 >> 8)] ^ iT3[(byte)a6] ^ ekey[10];
-                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a7] ^ ekey[11];
-                       b4 = iT0[a4 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[12];
-                       b5 = iT0[a5 >> 24] ^ iT1[(byte)(a4 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[13];
-                       b6 = iT0[a6 >> 24] ^ iT1[(byte)(a5 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[14];
-                       b7 = iT0[a7 >> 24] ^ iT1[(byte)(a6 >> 16)] ^ iT2[(byte)(a4 >> 8)] ^ iT3[(byte)a3] ^ ekey[15];
-
-                       /* Round 2 */
-                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b7 >> 16)] ^ iT2[(byte)(b5 >> 8)] ^ iT3[(byte)b4] ^ ekey[16];
-                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b6 >> 8)] ^ iT3[(byte)b5] ^ ekey[17];
-                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b7 >> 8)] ^ iT3[(byte)b6] ^ ekey[18];
-                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b7] ^ ekey[19];
-                       a4 = iT0[b4 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[20];
-                       a5 = iT0[b5 >> 24] ^ iT1[(byte)(b4 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[21];
-                       a6 = iT0[b6 >> 24] ^ iT1[(byte)(b5 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[22];
-                       a7 = iT0[b7 >> 24] ^ iT1[(byte)(b6 >> 16)] ^ iT2[(byte)(b4 >> 8)] ^ iT3[(byte)b3] ^ ekey[23];
-
-                       /* Round 3 */
-                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a7 >> 16)] ^ iT2[(byte)(a5 >> 8)] ^ iT3[(byte)a4] ^ ekey[24];
-                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a6 >> 8)] ^ iT3[(byte)a5] ^ ekey[25];
-                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a7 >> 8)] ^ iT3[(byte)a6] ^ ekey[26];
-                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a7] ^ ekey[27];
-                       b4 = iT0[a4 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[28];
-                       b5 = iT0[a5 >> 24] ^ iT1[(byte)(a4 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[29];
-                       b6 = iT0[a6 >> 24] ^ iT1[(byte)(a5 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[30];
-                       b7 = iT0[a7 >> 24] ^ iT1[(byte)(a6 >> 16)] ^ iT2[(byte)(a4 >> 8)] ^ iT3[(byte)a3] ^ ekey[31];
-
-                       /* Round 4 */
-                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b7 >> 16)] ^ iT2[(byte)(b5 >> 8)] ^ iT3[(byte)b4] ^ ekey[32];
-                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b6 >> 8)] ^ iT3[(byte)b5] ^ ekey[33];
-                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b7 >> 8)] ^ iT3[(byte)b6] ^ ekey[34];
-                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b7] ^ ekey[35];
-                       a4 = iT0[b4 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[36];
-                       a5 = iT0[b5 >> 24] ^ iT1[(byte)(b4 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[37];
-                       a6 = iT0[b6 >> 24] ^ iT1[(byte)(b5 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[38];
-                       a7 = iT0[b7 >> 24] ^ iT1[(byte)(b6 >> 16)] ^ iT2[(byte)(b4 >> 8)] ^ iT3[(byte)b3] ^ ekey[39];
-
-                       /* Round 5 */
-                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a7 >> 16)] ^ iT2[(byte)(a5 >> 8)] ^ iT3[(byte)a4] ^ ekey[40];
-                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a6 >> 8)] ^ iT3[(byte)a5] ^ ekey[41];
-                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a7 >> 8)] ^ iT3[(byte)a6] ^ ekey[42];
-                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a7] ^ ekey[43];
-                       b4 = iT0[a4 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[44];
-                       b5 = iT0[a5 >> 24] ^ iT1[(byte)(a4 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[45];
-                       b6 = iT0[a6 >> 24] ^ iT1[(byte)(a5 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[46];
-                       b7 = iT0[a7 >> 24] ^ iT1[(byte)(a6 >> 16)] ^ iT2[(byte)(a4 >> 8)] ^ iT3[(byte)a3] ^ ekey[47];
-
-                       /* Round 6 */
-                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b7 >> 16)] ^ iT2[(byte)(b5 >> 8)] ^ iT3[(byte)b4] ^ ekey[48];
-                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b6 >> 8)] ^ iT3[(byte)b5] ^ ekey[49];
-                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b7 >> 8)] ^ iT3[(byte)b6] ^ ekey[50];
-                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b7] ^ ekey[51];
-                       a4 = iT0[b4 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[52];
-                       a5 = iT0[b5 >> 24] ^ iT1[(byte)(b4 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[53];
-                       a6 = iT0[b6 >> 24] ^ iT1[(byte)(b5 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[54];
-                       a7 = iT0[b7 >> 24] ^ iT1[(byte)(b6 >> 16)] ^ iT2[(byte)(b4 >> 8)] ^ iT3[(byte)b3] ^ ekey[55];
-
-                       /* Round 7 */
-                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a7 >> 16)] ^ iT2[(byte)(a5 >> 8)] ^ iT3[(byte)a4] ^ ekey[56];
-                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a6 >> 8)] ^ iT3[(byte)a5] ^ ekey[57];
-                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a7 >> 8)] ^ iT3[(byte)a6] ^ ekey[58];
-                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a7] ^ ekey[59];
-                       b4 = iT0[a4 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[60];
-                       b5 = iT0[a5 >> 24] ^ iT1[(byte)(a4 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[61];
-                       b6 = iT0[a6 >> 24] ^ iT1[(byte)(a5 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[62];
-                       b7 = iT0[a7 >> 24] ^ iT1[(byte)(a6 >> 16)] ^ iT2[(byte)(a4 >> 8)] ^ iT3[(byte)a3] ^ ekey[63];
-
-                       /* Round 8 */
-                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b7 >> 16)] ^ iT2[(byte)(b5 >> 8)] ^ iT3[(byte)b4] ^ ekey[64];
-                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b6 >> 8)] ^ iT3[(byte)b5] ^ ekey[65];
-                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b7 >> 8)] ^ iT3[(byte)b6] ^ ekey[66];
-                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b7] ^ ekey[67];
-                       a4 = iT0[b4 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[68];
-                       a5 = iT0[b5 >> 24] ^ iT1[(byte)(b4 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[69];
-                       a6 = iT0[b6 >> 24] ^ iT1[(byte)(b5 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[70];
-                       a7 = iT0[b7 >> 24] ^ iT1[(byte)(b6 >> 16)] ^ iT2[(byte)(b4 >> 8)] ^ iT3[(byte)b3] ^ ekey[71];
-
-                       /* Round 9 */
-                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a7 >> 16)] ^ iT2[(byte)(a5 >> 8)] ^ iT3[(byte)a4] ^ ekey[72];
-                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a6 >> 8)] ^ iT3[(byte)a5] ^ ekey[73];
-                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a7 >> 8)] ^ iT3[(byte)a6] ^ ekey[74];
-                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a7] ^ ekey[75];
-                       b4 = iT0[a4 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[76];
-                       b5 = iT0[a5 >> 24] ^ iT1[(byte)(a4 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[77];
-                       b6 = iT0[a6 >> 24] ^ iT1[(byte)(a5 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[78];
-                       b7 = iT0[a7 >> 24] ^ iT1[(byte)(a6 >> 16)] ^ iT2[(byte)(a4 >> 8)] ^ iT3[(byte)a3] ^ ekey[79];
-
-                       /* Round 10 */
-                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b7 >> 16)] ^ iT2[(byte)(b5 >> 8)] ^ iT3[(byte)b4] ^ ekey[80];
-                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b6 >> 8)] ^ iT3[(byte)b5] ^ ekey[81];
-                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b7 >> 8)] ^ iT3[(byte)b6] ^ ekey[82];
-                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b7] ^ ekey[83];
-                       a4 = iT0[b4 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[84];
-                       a5 = iT0[b5 >> 24] ^ iT1[(byte)(b4 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[85];
-                       a6 = iT0[b6 >> 24] ^ iT1[(byte)(b5 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[86];
-                       a7 = iT0[b7 >> 24] ^ iT1[(byte)(b6 >> 16)] ^ iT2[(byte)(b4 >> 8)] ^ iT3[(byte)b3] ^ ekey[87];
-
-                       /* Round 11 */
-                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a7 >> 16)] ^ iT2[(byte)(a5 >> 8)] ^ iT3[(byte)a4] ^ ekey[88];
-                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a6 >> 8)] ^ iT3[(byte)a5] ^ ekey[89];
-                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a7 >> 8)] ^ iT3[(byte)a6] ^ ekey[90];
-                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a7] ^ ekey[91];
-                       b4 = iT0[a4 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[92];
-                       b5 = iT0[a5 >> 24] ^ iT1[(byte)(a4 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[93];
-                       b6 = iT0[a6 >> 24] ^ iT1[(byte)(a5 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[94];
-                       b7 = iT0[a7 >> 24] ^ iT1[(byte)(a6 >> 16)] ^ iT2[(byte)(a4 >> 8)] ^ iT3[(byte)a3] ^ ekey[95];
-
-                       /* Round 12 */
-                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b7 >> 16)] ^ iT2[(byte)(b5 >> 8)] ^ iT3[(byte)b4] ^ ekey[96];
-                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b6 >> 8)] ^ iT3[(byte)b5] ^ ekey[97];
-                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b7 >> 8)] ^ iT3[(byte)b6] ^ ekey[98];
-                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b7] ^ ekey[99];
-                       a4 = iT0[b4 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[100];
-                       a5 = iT0[b5 >> 24] ^ iT1[(byte)(b4 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[101];
-                       a6 = iT0[b6 >> 24] ^ iT1[(byte)(b5 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[102];
-                       a7 = iT0[b7 >> 24] ^ iT1[(byte)(b6 >> 16)] ^ iT2[(byte)(b4 >> 8)] ^ iT3[(byte)b3] ^ ekey[103];
-
-                       /* Round 13 */
-                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a7 >> 16)] ^ iT2[(byte)(a5 >> 8)] ^ iT3[(byte)a4] ^ ekey[104];
-                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a6 >> 8)] ^ iT3[(byte)a5] ^ ekey[105];
-                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a7 >> 8)] ^ iT3[(byte)a6] ^ ekey[106];
-                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a7] ^ ekey[107];
-                       b4 = iT0[a4 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[108];
-                       b5 = iT0[a5 >> 24] ^ iT1[(byte)(a4 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[109];
-                       b6 = iT0[a6 >> 24] ^ iT1[(byte)(a5 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[110];
-                       b7 = iT0[a7 >> 24] ^ iT1[(byte)(a6 >> 16)] ^ iT2[(byte)(a4 >> 8)] ^ iT3[(byte)a3] ^ ekey[111];
-
-                       /* Final Round */
-                       outdata[0] = (byte)(iSBox[b0 >> 24] ^ (byte)(ekey[112] >> 24));
-                       outdata[1] = (byte)(iSBox[(byte)(b7 >> 16)] ^ (byte)(ekey[112] >> 16));
-                       outdata[2] = (byte)(iSBox[(byte)(b5 >> 8)] ^ (byte)(ekey[112] >> 8));
-                       outdata[3] = (byte)(iSBox[(byte)b4] ^ (byte)ekey[112]);
-
-                       outdata[4] = (byte)(iSBox[b1 >> 24] ^ (byte)(ekey[113] >> 24));
-                       outdata[5] = (byte)(iSBox[(byte)(b0 >> 16)] ^ (byte)(ekey[113] >> 16));
-                       outdata[6] = (byte)(iSBox[(byte)(b6 >> 8)] ^ (byte)(ekey[113] >> 8));
-                       outdata[7] = (byte)(iSBox[(byte)b5] ^ (byte)ekey[113]);
-
-                       outdata[8] = (byte)(iSBox[b2 >> 24] ^ (byte)(ekey[114] >> 24));
-                       outdata[9] = (byte)(iSBox[(byte)(b1 >> 16)] ^ (byte)(ekey[114] >> 16));
-                       outdata[10] = (byte)(iSBox[(byte)(b7 >> 8)] ^ (byte)(ekey[114] >> 8));
-                       outdata[11] = (byte)(iSBox[(byte)b6] ^ (byte)ekey[114]);
-
-                       outdata[12] = (byte)(iSBox[b3 >> 24] ^ (byte)(ekey[115] >> 24));
-                       outdata[13] = (byte)(iSBox[(byte)(b2 >> 16)] ^ (byte)(ekey[115] >> 16));
-                       outdata[14] = (byte)(iSBox[(byte)(b0 >> 8)] ^ (byte)(ekey[115] >> 8));
-                       outdata[15] = (byte)(iSBox[(byte)b7] ^ (byte)ekey[115]);
-
-                       outdata[16] = (byte)(iSBox[b4 >> 24] ^ (byte)(ekey[116] >> 24));
-                       outdata[17] = (byte)(iSBox[(byte)(b3 >> 16)] ^ (byte)(ekey[116] >> 16));
-                       outdata[18] = (byte)(iSBox[(byte)(b1 >> 8)] ^ (byte)(ekey[116] >> 8));
-                       outdata[19] = (byte)(iSBox[(byte)b0] ^ (byte)ekey[116]);
-
-                       outdata[20] = (byte)(iSBox[b5 >> 24] ^ (byte)(ekey[117] >> 24));
-                       outdata[21] = (byte)(iSBox[(byte)(b4 >> 16)] ^ (byte)(ekey[117] >> 16));
-                       outdata[22] = (byte)(iSBox[(byte)(b2 >> 8)] ^ (byte)(ekey[117] >> 8));
-                       outdata[23] = (byte)(iSBox[(byte)b1] ^ (byte)ekey[117]);
-
-                       outdata[24] = (byte)(iSBox[b6 >> 24] ^ (byte)(ekey[118] >> 24));
-                       outdata[25] = (byte)(iSBox[(byte)(b5 >> 16)] ^ (byte)(ekey[118] >> 16));
-                       outdata[26] = (byte)(iSBox[(byte)(b3 >> 8)] ^ (byte)(ekey[118] >> 8));
-                       outdata[27] = (byte)(iSBox[(byte)b2] ^ (byte)ekey[118]);
-
-                       outdata[28] = (byte)(iSBox[b7 >> 24] ^ (byte)(ekey[119] >> 24));
-                       outdata[29] = (byte)(iSBox[(byte)(b6 >> 16)] ^ (byte)(ekey[119] >> 16));
-                       outdata[30] = (byte)(iSBox[(byte)(b4 >> 8)] ^ (byte)(ekey[119] >> 8));
-                       outdata[31] = (byte)(iSBox[(byte)b3] ^ (byte)ekey[119]);
-               }
-               #endregion
-
-               #region Constant Table
-               static readonly uint[] Rcon = new uint[] {
-                       0x00000000, 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000,
-                       0x80000000, 0x1b000000, 0x36000000, 0x6c000000, 0xd8000000, 0xab000000, 0x4d000000, 0x9a000000,
-                       0x2f000000, 0x5e000000, 0xbc000000, 0x63000000, 0xc6000000, 0x97000000, 0x35000000, 0x6a000000,
-                       0xd4000000, 0xb3000000, 0x7d000000, 0xfa000000, 0xef000000, 0xc5000000
-               };
-
-               static readonly byte[] SBox = new byte[] {
-                       0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
-                       0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
-                       0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
-                       0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
-                       0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
-                       0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
-                       0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
-                       0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
-                       0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
-                       0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
-                       0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
-                       0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
-                       0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
-                       0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
-                       0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
-                       0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-               };
-
-               static readonly byte[] iSBox = {
-                       0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
-                       0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
-                       0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
-                       0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
-                       0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
-                       0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
-                       0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
-                       0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
-                       0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
-                       0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
-                       0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
-                       0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
-                       0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
-                       0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
-                       0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
-                       0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d,
-               };
-
-               static readonly uint[] T0 = {
-                       0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
-                       0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d, 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
-                       0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87, 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
-                       0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
-                       0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a, 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
-                       0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108, 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
-                       0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
-                       0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d, 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
-                       0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e, 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
-                       0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
-                       0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c, 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
-                       0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b, 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
-                       0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
-                       0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81, 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
-                       0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a, 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
-                       0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
-                       0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f, 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
-                       0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47, 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
-                       0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
-                       0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c, 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
-                       0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e, 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
-                       0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
-                       0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7, 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
-                       0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25, 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
-                       0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
-                       0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21, 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
-                       0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa, 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
-                       0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
-                       0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133, 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
-                       0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920, 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
-                       0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17, 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
-                       0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11, 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a,
-               };
-
-               static readonly uint[] T1 = {
-                       0xa5c66363, 0x84f87c7c, 0x99ee7777, 0x8df67b7b, 0x0dfff2f2, 0xbdd66b6b, 0xb1de6f6f, 0x5491c5c5,
-                       0x50603030, 0x03020101, 0xa9ce6767, 0x7d562b2b, 0x19e7fefe, 0x62b5d7d7, 0xe64dabab, 0x9aec7676,
-                       0x458fcaca, 0x9d1f8282, 0x4089c9c9, 0x87fa7d7d, 0x15effafa, 0xebb25959, 0xc98e4747, 0x0bfbf0f0,
-                       0xec41adad, 0x67b3d4d4, 0xfd5fa2a2, 0xea45afaf, 0xbf239c9c, 0xf753a4a4, 0x96e47272, 0x5b9bc0c0,
-                       0xc275b7b7, 0x1ce1fdfd, 0xae3d9393, 0x6a4c2626, 0x5a6c3636, 0x417e3f3f, 0x02f5f7f7, 0x4f83cccc,
-                       0x5c683434, 0xf451a5a5, 0x34d1e5e5, 0x08f9f1f1, 0x93e27171, 0x73abd8d8, 0x53623131, 0x3f2a1515,
-                       0x0c080404, 0x5295c7c7, 0x65462323, 0x5e9dc3c3, 0x28301818, 0xa1379696, 0x0f0a0505, 0xb52f9a9a,
-                       0x090e0707, 0x36241212, 0x9b1b8080, 0x3ddfe2e2, 0x26cdebeb, 0x694e2727, 0xcd7fb2b2, 0x9fea7575,
-                       0x1b120909, 0x9e1d8383, 0x74582c2c, 0x2e341a1a, 0x2d361b1b, 0xb2dc6e6e, 0xeeb45a5a, 0xfb5ba0a0,
-                       0xf6a45252, 0x4d763b3b, 0x61b7d6d6, 0xce7db3b3, 0x7b522929, 0x3edde3e3, 0x715e2f2f, 0x97138484,
-                       0xf5a65353, 0x68b9d1d1, 0x00000000, 0x2cc1eded, 0x60402020, 0x1fe3fcfc, 0xc879b1b1, 0xedb65b5b,
-                       0xbed46a6a, 0x468dcbcb, 0xd967bebe, 0x4b723939, 0xde944a4a, 0xd4984c4c, 0xe8b05858, 0x4a85cfcf,
-                       0x6bbbd0d0, 0x2ac5efef, 0xe54faaaa, 0x16edfbfb, 0xc5864343, 0xd79a4d4d, 0x55663333, 0x94118585,
-                       0xcf8a4545, 0x10e9f9f9, 0x06040202, 0x81fe7f7f, 0xf0a05050, 0x44783c3c, 0xba259f9f, 0xe34ba8a8,
-                       0xf3a25151, 0xfe5da3a3, 0xc0804040, 0x8a058f8f, 0xad3f9292, 0xbc219d9d, 0x48703838, 0x04f1f5f5,
-                       0xdf63bcbc, 0xc177b6b6, 0x75afdada, 0x63422121, 0x30201010, 0x1ae5ffff, 0x0efdf3f3, 0x6dbfd2d2,
-                       0x4c81cdcd, 0x14180c0c, 0x35261313, 0x2fc3ecec, 0xe1be5f5f, 0xa2359797, 0xcc884444, 0x392e1717,
-                       0x5793c4c4, 0xf255a7a7, 0x82fc7e7e, 0x477a3d3d, 0xacc86464, 0xe7ba5d5d, 0x2b321919, 0x95e67373,
-                       0xa0c06060, 0x98198181, 0xd19e4f4f, 0x7fa3dcdc, 0x66442222, 0x7e542a2a, 0xab3b9090, 0x830b8888,
-                       0xca8c4646, 0x29c7eeee, 0xd36bb8b8, 0x3c281414, 0x79a7dede, 0xe2bc5e5e, 0x1d160b0b, 0x76addbdb,
-                       0x3bdbe0e0, 0x56643232, 0x4e743a3a, 0x1e140a0a, 0xdb924949, 0x0a0c0606, 0x6c482424, 0xe4b85c5c,
-                       0x5d9fc2c2, 0x6ebdd3d3, 0xef43acac, 0xa6c46262, 0xa8399191, 0xa4319595, 0x37d3e4e4, 0x8bf27979,
-                       0x32d5e7e7, 0x438bc8c8, 0x596e3737, 0xb7da6d6d, 0x8c018d8d, 0x64b1d5d5, 0xd29c4e4e, 0xe049a9a9,
-                       0xb4d86c6c, 0xfaac5656, 0x07f3f4f4, 0x25cfeaea, 0xafca6565, 0x8ef47a7a, 0xe947aeae, 0x18100808,
-                       0xd56fbaba, 0x88f07878, 0x6f4a2525, 0x725c2e2e, 0x24381c1c, 0xf157a6a6, 0xc773b4b4, 0x5197c6c6,
-                       0x23cbe8e8, 0x7ca1dddd, 0x9ce87474, 0x213e1f1f, 0xdd964b4b, 0xdc61bdbd, 0x860d8b8b, 0x850f8a8a,
-                       0x90e07070, 0x427c3e3e, 0xc471b5b5, 0xaacc6666, 0xd8904848, 0x05060303, 0x01f7f6f6, 0x121c0e0e,
-                       0xa3c26161, 0x5f6a3535, 0xf9ae5757, 0xd069b9b9, 0x91178686, 0x5899c1c1, 0x273a1d1d, 0xb9279e9e,
-                       0x38d9e1e1, 0x13ebf8f8, 0xb32b9898, 0x33221111, 0xbbd26969, 0x70a9d9d9, 0x89078e8e, 0xa7339494,
-                       0xb62d9b9b, 0x223c1e1e, 0x92158787, 0x20c9e9e9, 0x4987cece, 0xffaa5555, 0x78502828, 0x7aa5dfdf,
-                       0x8f038c8c, 0xf859a1a1, 0x80098989, 0x171a0d0d, 0xda65bfbf, 0x31d7e6e6, 0xc6844242, 0xb8d06868,
-                       0xc3824141, 0xb0299999, 0x775a2d2d, 0x111e0f0f, 0xcb7bb0b0, 0xfca85454, 0xd66dbbbb, 0x3a2c1616,
-               };
-
-               static readonly uint[] T2 = {
-                       0x63a5c663, 0x7c84f87c, 0x7799ee77, 0x7b8df67b, 0xf20dfff2, 0x6bbdd66b, 0x6fb1de6f, 0xc55491c5,
-                       0x30506030, 0x01030201, 0x67a9ce67, 0x2b7d562b, 0xfe19e7fe, 0xd762b5d7, 0xabe64dab, 0x769aec76,
-                       0xca458fca, 0x829d1f82, 0xc94089c9, 0x7d87fa7d, 0xfa15effa, 0x59ebb259, 0x47c98e47, 0xf00bfbf0,
-                       0xadec41ad, 0xd467b3d4, 0xa2fd5fa2, 0xafea45af, 0x9cbf239c, 0xa4f753a4, 0x7296e472, 0xc05b9bc0,
-                       0xb7c275b7, 0xfd1ce1fd, 0x93ae3d93, 0x266a4c26, 0x365a6c36, 0x3f417e3f, 0xf702f5f7, 0xcc4f83cc,
-                       0x345c6834, 0xa5f451a5, 0xe534d1e5, 0xf108f9f1, 0x7193e271, 0xd873abd8, 0x31536231, 0x153f2a15,
-                       0x040c0804, 0xc75295c7, 0x23654623, 0xc35e9dc3, 0x18283018, 0x96a13796, 0x050f0a05, 0x9ab52f9a,
-                       0x07090e07, 0x12362412, 0x809b1b80, 0xe23ddfe2, 0xeb26cdeb, 0x27694e27, 0xb2cd7fb2, 0x759fea75,
-                       0x091b1209, 0x839e1d83, 0x2c74582c, 0x1a2e341a, 0x1b2d361b, 0x6eb2dc6e, 0x5aeeb45a, 0xa0fb5ba0,
-                       0x52f6a452, 0x3b4d763b, 0xd661b7d6, 0xb3ce7db3, 0x297b5229, 0xe33edde3, 0x2f715e2f, 0x84971384,
-                       0x53f5a653, 0xd168b9d1, 0x00000000, 0xed2cc1ed, 0x20604020, 0xfc1fe3fc, 0xb1c879b1, 0x5bedb65b,
-                       0x6abed46a, 0xcb468dcb, 0xbed967be, 0x394b7239, 0x4ade944a, 0x4cd4984c, 0x58e8b058, 0xcf4a85cf,
-                       0xd06bbbd0, 0xef2ac5ef, 0xaae54faa, 0xfb16edfb, 0x43c58643, 0x4dd79a4d, 0x33556633, 0x85941185,
-                       0x45cf8a45, 0xf910e9f9, 0x02060402, 0x7f81fe7f, 0x50f0a050, 0x3c44783c, 0x9fba259f, 0xa8e34ba8,
-                       0x51f3a251, 0xa3fe5da3, 0x40c08040, 0x8f8a058f, 0x92ad3f92, 0x9dbc219d, 0x38487038, 0xf504f1f5,
-                       0xbcdf63bc, 0xb6c177b6, 0xda75afda, 0x21634221, 0x10302010, 0xff1ae5ff, 0xf30efdf3, 0xd26dbfd2,
-                       0xcd4c81cd, 0x0c14180c, 0x13352613, 0xec2fc3ec, 0x5fe1be5f, 0x97a23597, 0x44cc8844, 0x17392e17,
-                       0xc45793c4, 0xa7f255a7, 0x7e82fc7e, 0x3d477a3d, 0x64acc864, 0x5de7ba5d, 0x192b3219, 0x7395e673,
-                       0x60a0c060, 0x81981981, 0x4fd19e4f, 0xdc7fa3dc, 0x22664422, 0x2a7e542a, 0x90ab3b90, 0x88830b88,
-                       0x46ca8c46, 0xee29c7ee, 0xb8d36bb8, 0x143c2814, 0xde79a7de, 0x5ee2bc5e, 0x0b1d160b, 0xdb76addb,
-                       0xe03bdbe0, 0x32566432, 0x3a4e743a, 0x0a1e140a, 0x49db9249, 0x060a0c06, 0x246c4824, 0x5ce4b85c,
-                       0xc25d9fc2, 0xd36ebdd3, 0xacef43ac, 0x62a6c462, 0x91a83991, 0x95a43195, 0xe437d3e4, 0x798bf279,
-                       0xe732d5e7, 0xc8438bc8, 0x37596e37, 0x6db7da6d, 0x8d8c018d, 0xd564b1d5, 0x4ed29c4e, 0xa9e049a9,
-                       0x6cb4d86c, 0x56faac56, 0xf407f3f4, 0xea25cfea, 0x65afca65, 0x7a8ef47a, 0xaee947ae, 0x08181008,
-                       0xbad56fba, 0x7888f078, 0x256f4a25, 0x2e725c2e, 0x1c24381c, 0xa6f157a6, 0xb4c773b4, 0xc65197c6,
-                       0xe823cbe8, 0xdd7ca1dd, 0x749ce874, 0x1f213e1f, 0x4bdd964b, 0xbddc61bd, 0x8b860d8b, 0x8a850f8a,
-                       0x7090e070, 0x3e427c3e, 0xb5c471b5, 0x66aacc66, 0x48d89048, 0x03050603, 0xf601f7f6, 0x0e121c0e,
-                       0x61a3c261, 0x355f6a35, 0x57f9ae57, 0xb9d069b9, 0x86911786, 0xc15899c1, 0x1d273a1d, 0x9eb9279e,
-                       0xe138d9e1, 0xf813ebf8, 0x98b32b98, 0x11332211, 0x69bbd269, 0xd970a9d9, 0x8e89078e, 0x94a73394,
-                       0x9bb62d9b, 0x1e223c1e, 0x87921587, 0xe920c9e9, 0xce4987ce, 0x55ffaa55, 0x28785028, 0xdf7aa5df,
-                       0x8c8f038c, 0xa1f859a1, 0x89800989, 0x0d171a0d, 0xbfda65bf, 0xe631d7e6, 0x42c68442, 0x68b8d068,
-                       0x41c38241, 0x99b02999, 0x2d775a2d, 0x0f111e0f, 0xb0cb7bb0, 0x54fca854, 0xbbd66dbb, 0x163a2c16,
-               };
-
-               static readonly uint[] T3 = {
-                       0x6363a5c6, 0x7c7c84f8, 0x777799ee, 0x7b7b8df6, 0xf2f20dff, 0x6b6bbdd6, 0x6f6fb1de, 0xc5c55491,
-                       0x30305060, 0x01010302, 0x6767a9ce, 0x2b2b7d56, 0xfefe19e7, 0xd7d762b5, 0xababe64d, 0x76769aec,
-                       0xcaca458f, 0x82829d1f, 0xc9c94089, 0x7d7d87fa, 0xfafa15ef, 0x5959ebb2, 0x4747c98e, 0xf0f00bfb,
-                       0xadadec41, 0xd4d467b3, 0xa2a2fd5f, 0xafafea45, 0x9c9cbf23, 0xa4a4f753, 0x727296e4, 0xc0c05b9b,
-                       0xb7b7c275, 0xfdfd1ce1, 0x9393ae3d, 0x26266a4c, 0x36365a6c, 0x3f3f417e, 0xf7f702f5, 0xcccc4f83,
-                       0x34345c68, 0xa5a5f451, 0xe5e534d1, 0xf1f108f9, 0x717193e2, 0xd8d873ab, 0x31315362, 0x15153f2a,
-                       0x04040c08, 0xc7c75295, 0x23236546, 0xc3c35e9d, 0x18182830, 0x9696a137, 0x05050f0a, 0x9a9ab52f,
-                       0x0707090e, 0x12123624, 0x80809b1b, 0xe2e23ddf, 0xebeb26cd, 0x2727694e, 0xb2b2cd7f, 0x75759fea,
-                       0x09091b12, 0x83839e1d, 0x2c2c7458, 0x1a1a2e34, 0x1b1b2d36, 0x6e6eb2dc, 0x5a5aeeb4, 0xa0a0fb5b,
-                       0x5252f6a4, 0x3b3b4d76, 0xd6d661b7, 0xb3b3ce7d, 0x29297b52, 0xe3e33edd, 0x2f2f715e, 0x84849713,
-                       0x5353f5a6, 0xd1d168b9, 0x00000000, 0xeded2cc1, 0x20206040, 0xfcfc1fe3, 0xb1b1c879, 0x5b5bedb6,
-                       0x6a6abed4, 0xcbcb468d, 0xbebed967, 0x39394b72, 0x4a4ade94, 0x4c4cd498, 0x5858e8b0, 0xcfcf4a85,
-                       0xd0d06bbb, 0xefef2ac5, 0xaaaae54f, 0xfbfb16ed, 0x4343c586, 0x4d4dd79a, 0x33335566, 0x85859411,
-                       0x4545cf8a, 0xf9f910e9, 0x02020604, 0x7f7f81fe, 0x5050f0a0, 0x3c3c4478, 0x9f9fba25, 0xa8a8e34b,
-                       0x5151f3a2, 0xa3a3fe5d, 0x4040c080, 0x8f8f8a05, 0x9292ad3f, 0x9d9dbc21, 0x38384870, 0xf5f504f1,
-                       0xbcbcdf63, 0xb6b6c177, 0xdada75af, 0x21216342, 0x10103020, 0xffff1ae5, 0xf3f30efd, 0xd2d26dbf,
-                       0xcdcd4c81, 0x0c0c1418, 0x13133526, 0xecec2fc3, 0x5f5fe1be, 0x9797a235, 0x4444cc88, 0x1717392e,
-                       0xc4c45793, 0xa7a7f255, 0x7e7e82fc, 0x3d3d477a, 0x6464acc8, 0x5d5de7ba, 0x19192b32, 0x737395e6,
-                       0x6060a0c0, 0x81819819, 0x4f4fd19e, 0xdcdc7fa3, 0x22226644, 0x2a2a7e54, 0x9090ab3b, 0x8888830b,
-                       0x4646ca8c, 0xeeee29c7, 0xb8b8d36b, 0x14143c28, 0xdede79a7, 0x5e5ee2bc, 0x0b0b1d16, 0xdbdb76ad,
-                       0xe0e03bdb, 0x32325664, 0x3a3a4e74, 0x0a0a1e14, 0x4949db92, 0x06060a0c, 0x24246c48, 0x5c5ce4b8,
-                       0xc2c25d9f, 0xd3d36ebd, 0xacacef43, 0x6262a6c4, 0x9191a839, 0x9595a431, 0xe4e437d3, 0x79798bf2,
-                       0xe7e732d5, 0xc8c8438b, 0x3737596e, 0x6d6db7da, 0x8d8d8c01, 0xd5d564b1, 0x4e4ed29c, 0xa9a9e049,
-                       0x6c6cb4d8, 0x5656faac, 0xf4f407f3, 0xeaea25cf, 0x6565afca, 0x7a7a8ef4, 0xaeaee947, 0x08081810,
-                       0xbabad56f, 0x787888f0, 0x25256f4a, 0x2e2e725c, 0x1c1c2438, 0xa6a6f157, 0xb4b4c773, 0xc6c65197,
-                       0xe8e823cb, 0xdddd7ca1, 0x74749ce8, 0x1f1f213e, 0x4b4bdd96, 0xbdbddc61, 0x8b8b860d, 0x8a8a850f,
-                       0x707090e0, 0x3e3e427c, 0xb5b5c471, 0x6666aacc, 0x4848d890, 0x03030506, 0xf6f601f7, 0x0e0e121c,
-                       0x6161a3c2, 0x35355f6a, 0x5757f9ae, 0xb9b9d069, 0x86869117, 0xc1c15899, 0x1d1d273a, 0x9e9eb927,
-                       0xe1e138d9, 0xf8f813eb, 0x9898b32b, 0x11113322, 0x6969bbd2, 0xd9d970a9, 0x8e8e8907, 0x9494a733,
-                       0x9b9bb62d, 0x1e1e223c, 0x87879215, 0xe9e920c9, 0xcece4987, 0x5555ffaa, 0x28287850, 0xdfdf7aa5,
-                       0x8c8c8f03, 0xa1a1f859, 0x89898009, 0x0d0d171a, 0xbfbfda65, 0xe6e631d7, 0x4242c684, 0x6868b8d0,
-                       0x4141c382, 0x9999b029, 0x2d2d775a, 0x0f0f111e, 0xb0b0cb7b, 0x5454fca8, 0xbbbbd66d, 0x16163a2c,
-               };
-
-               static readonly uint[] iT0 = {
-                       0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96, 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
-                       0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25, 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
-                       0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1, 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
-                       0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da, 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
-                       0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd, 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
-                       0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45, 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
-                       0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7, 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
-                       0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5, 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
-                       0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1, 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
-                       0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75, 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
-                       0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46, 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
-                       0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77, 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
-                       0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000, 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
-                       0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927, 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
-                       0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e, 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
-                       0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d, 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
-                       0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd, 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
-                       0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163, 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
-                       0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d, 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
-                       0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422, 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
-                       0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36, 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
-                       0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662, 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
-                       0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3, 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
-                       0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8, 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
-                       0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6, 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
-                       0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815, 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
-                       0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df, 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
-                       0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e, 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
-                       0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89, 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
-                       0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf, 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
-                       0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f, 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
-                       0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190, 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742,
-               };
-
-               static readonly uint[] iT1 = {
-                       0x5051f4a7, 0x537e4165, 0xc31a17a4, 0x963a275e, 0xcb3bab6b, 0xf11f9d45, 0xabacfa58, 0x934be303,
-                       0x552030fa, 0xf6ad766d, 0x9188cc76, 0x25f5024c, 0xfc4fe5d7, 0xd7c52acb, 0x80263544, 0x8fb562a3,
-                       0x49deb15a, 0x6725ba1b, 0x9845ea0e, 0xe15dfec0, 0x02c32f75, 0x12814cf0, 0xa38d4697, 0xc66bd3f9,
-                       0xe7038f5f, 0x9515929c, 0xebbf6d7a, 0xda955259, 0x2dd4be83, 0xd3587421, 0x2949e069, 0x448ec9c8,
-                       0x6a75c289, 0x78f48e79, 0x6b99583e, 0xdd27b971, 0xb6bee14f, 0x17f088ad, 0x66c920ac, 0xb47dce3a,
-                       0x1863df4a, 0x82e51a31, 0x60975133, 0x4562537f, 0xe0b16477, 0x84bb6bae, 0x1cfe81a0, 0x94f9082b,
-                       0x58704868, 0x198f45fd, 0x8794de6c, 0xb7527bf8, 0x23ab73d3, 0xe2724b02, 0x57e31f8f, 0x2a6655ab,
-                       0x07b2eb28, 0x032fb5c2, 0x9a86c57b, 0xa5d33708, 0xf2302887, 0xb223bfa5, 0xba02036a, 0x5ced1682,
-                       0x2b8acf1c, 0x92a779b4, 0xf0f307f2, 0xa14e69e2, 0xcd65daf4, 0xd50605be, 0x1fd13462, 0x8ac4a6fe,
-                       0x9d342e53, 0xa0a2f355, 0x32058ae1, 0x75a4f6eb, 0x390b83ec, 0xaa4060ef, 0x065e719f, 0x51bd6e10,
-                       0xf93e218a, 0x3d96dd06, 0xaedd3e05, 0x464de6bd, 0xb591548d, 0x0571c45d, 0x6f0406d4, 0xff605015,
-                       0x241998fb, 0x97d6bde9, 0xcc894043, 0x7767d99e, 0xbdb0e842, 0x8807898b, 0x38e7195b, 0xdb79c8ee,
-                       0x47a17c0a, 0xe97c420f, 0xc9f8841e, 0x00000000, 0x83098086, 0x48322bed, 0xac1e1170, 0x4e6c5a72,
-                       0xfbfd0eff, 0x560f8538, 0x1e3daed5, 0x27362d39, 0x640a0fd9, 0x21685ca6, 0xd19b5b54, 0x3a24362e,
-                       0xb10c0a67, 0x0f9357e7, 0xd2b4ee96, 0x9e1b9b91, 0x4f80c0c5, 0xa261dc20, 0x695a774b, 0x161c121a,
-                       0x0ae293ba, 0xe5c0a02a, 0x433c22e0, 0x1d121b17, 0x0b0e090d, 0xadf28bc7, 0xb92db6a8, 0xc8141ea9,
-                       0x8557f119, 0x4caf7507, 0xbbee99dd, 0xfda37f60, 0x9ff70126, 0xbc5c72f5, 0xc544663b, 0x345bfb7e,
-                       0x768b4329, 0xdccb23c6, 0x68b6edfc, 0x63b8e4f1, 0xcad731dc, 0x10426385, 0x40139722, 0x2084c611,
-                       0x7d854a24, 0xf8d2bb3d, 0x11aef932, 0x6dc729a1, 0x4b1d9e2f, 0xf3dcb230, 0xec0d8652, 0xd077c1e3,
-                       0x6c2bb316, 0x99a970b9, 0xfa119448, 0x2247e964, 0xc4a8fc8c, 0x1aa0f03f, 0xd8567d2c, 0xef223390,
-                       0xc787494e, 0xc1d938d1, 0xfe8ccaa2, 0x3698d40b, 0xcfa6f581, 0x28a57ade, 0x26dab78e, 0xa43fadbf,
-                       0xe42c3a9d, 0x0d507892, 0x9b6a5fcc, 0x62547e46, 0xc2f68d13, 0xe890d8b8, 0x5e2e39f7, 0xf582c3af,
-                       0xbe9f5d80, 0x7c69d093, 0xa96fd52d, 0xb3cf2512, 0x3bc8ac99, 0xa710187d, 0x6ee89c63, 0x7bdb3bbb,
-                       0x09cd2678, 0xf46e5918, 0x01ec9ab7, 0xa8834f9a, 0x65e6956e, 0x7eaaffe6, 0x0821bccf, 0xe6ef15e8,
-                       0xd9bae79b, 0xce4a6f36, 0xd4ea9f09, 0xd629b07c, 0xaf31a4b2, 0x312a3f23, 0x30c6a594, 0xc035a266,
-                       0x37744ebc, 0xa6fc82ca, 0xb0e090d0, 0x1533a7d8, 0x4af10498, 0xf741ecda, 0x0e7fcd50, 0x2f1791f6,
-                       0x8d764dd6, 0x4d43efb0, 0x54ccaa4d, 0xdfe49604, 0xe39ed1b5, 0x1b4c6a88, 0xb8c12c1f, 0x7f466551,
-                       0x049d5eea, 0x5d018c35, 0x73fa8774, 0x2efb0b41, 0x5ab3671d, 0x5292dbd2, 0x33e91056, 0x136dd647,
-                       0x8c9ad761, 0x7a37a10c, 0x8e59f814, 0x89eb133c, 0xeecea927, 0x35b761c9, 0xede11ce5, 0x3c7a47b1,
-                       0x599cd2df, 0x3f55f273, 0x791814ce, 0xbf73c737, 0xea53f7cd, 0x5b5ffdaa, 0x14df3d6f, 0x867844db,
-                       0x81caaff3, 0x3eb968c4, 0x2c382434, 0x5fc2a340, 0x72161dc3, 0x0cbce225, 0x8b283c49, 0x41ff0d95,
-                       0x7139a801, 0xde080cb3, 0x9cd8b4e4, 0x906456c1, 0x617bcb84, 0x70d532b6, 0x74486c5c, 0x42d0b857,
-               };
-
-               static readonly uint[] iT2 = {
-                       0xa75051f4, 0x65537e41, 0xa4c31a17, 0x5e963a27, 0x6bcb3bab, 0x45f11f9d, 0x58abacfa, 0x03934be3,
-                       0xfa552030, 0x6df6ad76, 0x769188cc, 0x4c25f502, 0xd7fc4fe5, 0xcbd7c52a, 0x44802635, 0xa38fb562,
-                       0x5a49deb1, 0x1b6725ba, 0x0e9845ea, 0xc0e15dfe, 0x7502c32f, 0xf012814c, 0x97a38d46, 0xf9c66bd3,
-                       0x5fe7038f, 0x9c951592, 0x7aebbf6d, 0x59da9552, 0x832dd4be, 0x21d35874, 0x692949e0, 0xc8448ec9,
-                       0x896a75c2, 0x7978f48e, 0x3e6b9958, 0x71dd27b9, 0x4fb6bee1, 0xad17f088, 0xac66c920, 0x3ab47dce,
-                       0x4a1863df, 0x3182e51a, 0x33609751, 0x7f456253, 0x77e0b164, 0xae84bb6b, 0xa01cfe81, 0x2b94f908,
-                       0x68587048, 0xfd198f45, 0x6c8794de, 0xf8b7527b, 0xd323ab73, 0x02e2724b, 0x8f57e31f, 0xab2a6655,
-                       0x2807b2eb, 0xc2032fb5, 0x7b9a86c5, 0x08a5d337, 0x87f23028, 0xa5b223bf, 0x6aba0203, 0x825ced16,
-                       0x1c2b8acf, 0xb492a779, 0xf2f0f307, 0xe2a14e69, 0xf4cd65da, 0xbed50605, 0x621fd134, 0xfe8ac4a6,
-                       0x539d342e, 0x55a0a2f3, 0xe132058a, 0xeb75a4f6, 0xec390b83, 0xefaa4060, 0x9f065e71, 0x1051bd6e,
-                       0x8af93e21, 0x063d96dd, 0x05aedd3e, 0xbd464de6, 0x8db59154, 0x5d0571c4, 0xd46f0406, 0x15ff6050,
-                       0xfb241998, 0xe997d6bd, 0x43cc8940, 0x9e7767d9, 0x42bdb0e8, 0x8b880789, 0x5b38e719, 0xeedb79c8,
-                       0x0a47a17c, 0x0fe97c42, 0x1ec9f884, 0x00000000, 0x86830980, 0xed48322b, 0x70ac1e11, 0x724e6c5a,
-                       0xfffbfd0e, 0x38560f85, 0xd51e3dae, 0x3927362d, 0xd9640a0f, 0xa621685c, 0x54d19b5b, 0x2e3a2436,
-                       0x67b10c0a, 0xe70f9357, 0x96d2b4ee, 0x919e1b9b, 0xc54f80c0, 0x20a261dc, 0x4b695a77, 0x1a161c12,
-                       0xba0ae293, 0x2ae5c0a0, 0xe0433c22, 0x171d121b, 0x0d0b0e09, 0xc7adf28b, 0xa8b92db6, 0xa9c8141e,
-                       0x198557f1, 0x074caf75, 0xddbbee99, 0x60fda37f, 0x269ff701, 0xf5bc5c72, 0x3bc54466, 0x7e345bfb,
-                       0x29768b43, 0xc6dccb23, 0xfc68b6ed, 0xf163b8e4, 0xdccad731, 0x85104263, 0x22401397, 0x112084c6,
-                       0x247d854a, 0x3df8d2bb, 0x3211aef9, 0xa16dc729, 0x2f4b1d9e, 0x30f3dcb2, 0x52ec0d86, 0xe3d077c1,
-                       0x166c2bb3, 0xb999a970, 0x48fa1194, 0x642247e9, 0x8cc4a8fc, 0x3f1aa0f0, 0x2cd8567d, 0x90ef2233,
-                       0x4ec78749, 0xd1c1d938, 0xa2fe8cca, 0x0b3698d4, 0x81cfa6f5, 0xde28a57a, 0x8e26dab7, 0xbfa43fad,
-                       0x9de42c3a, 0x920d5078, 0xcc9b6a5f, 0x4662547e, 0x13c2f68d, 0xb8e890d8, 0xf75e2e39, 0xaff582c3,
-                       0x80be9f5d, 0x937c69d0, 0x2da96fd5, 0x12b3cf25, 0x993bc8ac, 0x7da71018, 0x636ee89c, 0xbb7bdb3b,
-                       0x7809cd26, 0x18f46e59, 0xb701ec9a, 0x9aa8834f, 0x6e65e695, 0xe67eaaff, 0xcf0821bc, 0xe8e6ef15,
-                       0x9bd9bae7, 0x36ce4a6f, 0x09d4ea9f, 0x7cd629b0, 0xb2af31a4, 0x23312a3f, 0x9430c6a5, 0x66c035a2,
-                       0xbc37744e, 0xcaa6fc82, 0xd0b0e090, 0xd81533a7, 0x984af104, 0xdaf741ec, 0x500e7fcd, 0xf62f1791,
-                       0xd68d764d, 0xb04d43ef, 0x4d54ccaa, 0x04dfe496, 0xb5e39ed1, 0x881b4c6a, 0x1fb8c12c, 0x517f4665,
-                       0xea049d5e, 0x355d018c, 0x7473fa87, 0x412efb0b, 0x1d5ab367, 0xd25292db, 0x5633e910, 0x47136dd6,
-                       0x618c9ad7, 0x0c7a37a1, 0x148e59f8, 0x3c89eb13, 0x27eecea9, 0xc935b761, 0xe5ede11c, 0xb13c7a47,
-                       0xdf599cd2, 0x733f55f2, 0xce791814, 0x37bf73c7, 0xcdea53f7, 0xaa5b5ffd, 0x6f14df3d, 0xdb867844,
-                       0xf381caaf, 0xc43eb968, 0x342c3824, 0x405fc2a3, 0xc372161d, 0x250cbce2, 0x498b283c, 0x9541ff0d,
-                       0x017139a8, 0xb3de080c, 0xe49cd8b4, 0xc1906456, 0x84617bcb, 0xb670d532, 0x5c74486c, 0x5742d0b8,
-               };
-
-               static readonly uint[] iT3 = {
-                       0xf4a75051, 0x4165537e, 0x17a4c31a, 0x275e963a, 0xab6bcb3b, 0x9d45f11f, 0xfa58abac, 0xe303934b,
-                       0x30fa5520, 0x766df6ad, 0xcc769188, 0x024c25f5, 0xe5d7fc4f, 0x2acbd7c5, 0x35448026, 0x62a38fb5,
-                       0xb15a49de, 0xba1b6725, 0xea0e9845, 0xfec0e15d, 0x2f7502c3, 0x4cf01281, 0x4697a38d, 0xd3f9c66b,
-                       0x8f5fe703, 0x929c9515, 0x6d7aebbf, 0x5259da95, 0xbe832dd4, 0x7421d358, 0xe0692949, 0xc9c8448e,
-                       0xc2896a75, 0x8e7978f4, 0x583e6b99, 0xb971dd27, 0xe14fb6be, 0x88ad17f0, 0x20ac66c9, 0xce3ab47d,
-                       0xdf4a1863, 0x1a3182e5, 0x51336097, 0x537f4562, 0x6477e0b1, 0x6bae84bb, 0x81a01cfe, 0x082b94f9,
-                       0x48685870, 0x45fd198f, 0xde6c8794, 0x7bf8b752, 0x73d323ab, 0x4b02e272, 0x1f8f57e3, 0x55ab2a66,
-                       0xeb2807b2, 0xb5c2032f, 0xc57b9a86, 0x3708a5d3, 0x2887f230, 0xbfa5b223, 0x036aba02, 0x16825ced,
-                       0xcf1c2b8a, 0x79b492a7, 0x07f2f0f3, 0x69e2a14e, 0xdaf4cd65, 0x05bed506, 0x34621fd1, 0xa6fe8ac4,
-                       0x2e539d34, 0xf355a0a2, 0x8ae13205, 0xf6eb75a4, 0x83ec390b, 0x60efaa40, 0x719f065e, 0x6e1051bd,
-                       0x218af93e, 0xdd063d96, 0x3e05aedd, 0xe6bd464d, 0x548db591, 0xc45d0571, 0x06d46f04, 0x5015ff60,
-                       0x98fb2419, 0xbde997d6, 0x4043cc89, 0xd99e7767, 0xe842bdb0, 0x898b8807, 0x195b38e7, 0xc8eedb79,
-                       0x7c0a47a1, 0x420fe97c, 0x841ec9f8, 0x00000000, 0x80868309, 0x2bed4832, 0x1170ac1e, 0x5a724e6c,
-                       0x0efffbfd, 0x8538560f, 0xaed51e3d, 0x2d392736, 0x0fd9640a, 0x5ca62168, 0x5b54d19b, 0x362e3a24,
-                       0x0a67b10c, 0x57e70f93, 0xee96d2b4, 0x9b919e1b, 0xc0c54f80, 0xdc20a261, 0x774b695a, 0x121a161c,
-                       0x93ba0ae2, 0xa02ae5c0, 0x22e0433c, 0x1b171d12, 0x090d0b0e, 0x8bc7adf2, 0xb6a8b92d, 0x1ea9c814,
-                       0xf1198557, 0x75074caf, 0x99ddbbee, 0x7f60fda3, 0x01269ff7, 0x72f5bc5c, 0x663bc544, 0xfb7e345b,
-                       0x4329768b, 0x23c6dccb, 0xedfc68b6, 0xe4f163b8, 0x31dccad7, 0x63851042, 0x97224013, 0xc6112084,
-                       0x4a247d85, 0xbb3df8d2, 0xf93211ae, 0x29a16dc7, 0x9e2f4b1d, 0xb230f3dc, 0x8652ec0d, 0xc1e3d077,
-                       0xb3166c2b, 0x70b999a9, 0x9448fa11, 0xe9642247, 0xfc8cc4a8, 0xf03f1aa0, 0x7d2cd856, 0x3390ef22,
-                       0x494ec787, 0x38d1c1d9, 0xcaa2fe8c, 0xd40b3698, 0xf581cfa6, 0x7ade28a5, 0xb78e26da, 0xadbfa43f,
-                       0x3a9de42c, 0x78920d50, 0x5fcc9b6a, 0x7e466254, 0x8d13c2f6, 0xd8b8e890, 0x39f75e2e, 0xc3aff582,
-                       0x5d80be9f, 0xd0937c69, 0xd52da96f, 0x2512b3cf, 0xac993bc8, 0x187da710, 0x9c636ee8, 0x3bbb7bdb,
-                       0x267809cd, 0x5918f46e, 0x9ab701ec, 0x4f9aa883, 0x956e65e6, 0xffe67eaa, 0xbccf0821, 0x15e8e6ef,
-                       0xe79bd9ba, 0x6f36ce4a, 0x9f09d4ea, 0xb07cd629, 0xa4b2af31, 0x3f23312a, 0xa59430c6, 0xa266c035,
-                       0x4ebc3774, 0x82caa6fc, 0x90d0b0e0, 0xa7d81533, 0x04984af1, 0xecdaf741, 0xcd500e7f, 0x91f62f17,
-                       0x4dd68d76, 0xefb04d43, 0xaa4d54cc, 0x9604dfe4, 0xd1b5e39e, 0x6a881b4c, 0x2c1fb8c1, 0x65517f46,
-                       0x5eea049d, 0x8c355d01, 0x877473fa, 0x0b412efb, 0x671d5ab3, 0xdbd25292, 0x105633e9, 0xd647136d,
-                       0xd7618c9a, 0xa10c7a37, 0xf8148e59, 0x133c89eb, 0xa927eece, 0x61c935b7, 0x1ce5ede1, 0x47b13c7a,
-                       0xd2df599c, 0xf2733f55, 0x14ce7918, 0xc737bf73, 0xf7cdea53, 0xfdaa5b5f, 0x3d6f14df, 0x44db8678,
-                       0xaff381ca, 0x68c43eb9, 0x24342c38, 0xa3405fc2, 0x1dc37216, 0xe2250cbc, 0x3c498b28, 0x0d9541ff,
-                       0xa8017139, 0x0cb3de08, 0xb4e49cd8, 0x56c19064, 0xcb84617b, 0x32b670d5, 0x6c5c7448, 0xb85742d0,
-               };
-               #endregion
-       }
 }
 
 #endif
index 4191343d523d8d923a2334f35461598fb1499065..396f11f6f44ab0d6d284f893917a81336891f60b 100644 (file)
@@ -28,6 +28,7 @@
 
 #if  !MOONLIGHT
 
+using Mono.Security.Cryptography;
 using System.Runtime.InteropServices;
 
 namespace System.Security.Cryptography {
@@ -98,6 +99,1385 @@ namespace System.Security.Cryptography {
                        return _st.TransformFinalBlock (inputBuffer, inputOffset, inputCount);
                }
        }
+
+       internal class RijndaelTransform : SymmetricTransform
+       {
+               private uint[] expandedKey;
+       
+               private int Nb;
+               private int Nk;
+               private int Nr;
+       
+               public RijndaelTransform (Rijndael algo, bool encryption, byte[] key, byte[] iv) : base (algo, encryption, iv)
+               {
+                       if (key == null)
+                               throw new CryptographicException ("key is null");
+                       if ((iv != null) && (iv.Length != (algo.BlockSize >> 3))) {
+                               string msg = Locale.GetText ("IV length is invalid ({0} bytes), it should be {1} bytes long.",
+                                       iv.Length, (algo.BlockSize >> 3));
+                               throw new CryptographicException (msg);
+                       }
+
+                       int keySize = key.Length;
+                       if (keySize != 16 && keySize != 24 && keySize != 32) {
+                               string msg = Locale.GetText ("Key is too small ({0} bytes), it should be {1}, {2} or {3} bytes long.",
+                                       keySize, 16, 24, 32);
+                               throw new CryptographicException (msg);
+                       }
+                       keySize <<= 3; // bytes -> bits
+                       int blockSize = algo.BlockSize;
+
+                       this.Nb = (blockSize >> 5); // div 32
+                       this.Nk = (keySize >> 5); // div 32
+       
+                       if (Nb == 8 || Nk == 8) {
+                               Nr = 14;
+                       } else if (Nb == 6 || Nk == 6) {
+                               Nr = 12;
+                       } else {
+                               Nr = 10;
+                       }
+       
+                       // Setup Expanded Key
+                       int exKeySize = Nb * (Nr+1);
+                       UInt32[] exKey = new UInt32[exKeySize];
+                       int pos = 0;
+                       for (int i=0; i < Nk; i++) {
+                               UInt32 value = ((UInt32)key [pos++] << 24);
+                               value |= ((UInt32)key[pos++] << 16);
+                               value |= ((UInt32)key[pos++] << 8);
+                               value |= ((UInt32)key[pos++]);
+                               exKey [i] = value;
+                       }
+       
+                       for (int i = Nk; i < exKeySize; i++) {
+                               UInt32 temp = exKey [i-1];
+                               if (i % Nk == 0) {
+                                       UInt32 rot = (UInt32) ((temp << 8) | ((temp >> 24) & 0xff));
+                                       temp = SubByte (rot) ^ Rcon [i / Nk];
+                               } else if (Nk > 6 && (i % Nk) == 4) {
+                                       temp = SubByte (temp);
+                               }
+                               exKey [i] = exKey [i-Nk] ^ temp;
+                       }
+
+                       if (!encryption && (algo.Mode == CipherMode.ECB || algo.Mode == CipherMode.CBC)) {
+                               for (int i = 0, k = exKeySize - Nb; i < k; i += Nb, k -= Nb) {
+                                       for (int j = 0; j < Nb; j ++) {
+                                               uint temp = exKey[i + j];
+                                               exKey[i + j] = exKey[k + j];
+                                               exKey[k + j] = temp;
+                                       }
+                               }
+
+                               for (int i = Nb; i < exKey.Length - Nb; i ++) {
+                                       exKey[i] =
+                                               iT0[SBox[(exKey[i] >> 24)]] ^
+                                               iT1[SBox[(byte)(exKey[i] >> 16)]] ^
+                                               iT2[SBox[(byte)(exKey[i] >> 8)]] ^
+                                               iT3[SBox[(byte)exKey[i]]];
+                               }
+                       }
+                       expandedKey = exKey;
+               }
+
+               public void Clear () 
+               {
+                       Dispose (true);
+               }
+       
+               // note: this method is guaranteed to be called with a valid blocksize
+               // for both input and output
+               protected override void ECB (byte[] input, byte[] output) 
+               {
+                       if (encrypt) {
+                               switch (Nb) {
+                                       case 4:
+                                               Encrypt128 (input, output, expandedKey);
+                                               return;
+                                       case 6:
+                                               Encrypt192 (input, output, expandedKey);
+                                               return;
+                                       case 8:
+                                               Encrypt256 (input, output, expandedKey);
+                                               return;
+                               }
+                       } else {
+                               switch (Nb) {
+                                       case 4:
+                                               Decrypt128 (input, output, expandedKey);
+                                               return;
+                                       case 6:
+                                               Decrypt192 (input, output, expandedKey);
+                                               return;
+                                       case 8:
+                                               Decrypt256 (input, output, expandedKey);
+                                               return;
+                               }
+                       }
+               }
+
+               private UInt32 SubByte (UInt32 a)
+               {
+                       UInt32 value = 0xff & a;
+                       UInt32 result = SBox[value];
+                       value = 0xff & (a >> 8);
+                       result |= (UInt32)SBox[value] << 8;
+                       value = 0xff & (a >> 16);
+                       result |= (UInt32)SBox[value] << 16;
+                       value = 0xff & (a >> 24);
+                       return result | (UInt32)(SBox[value] << 24);
+               }
+
+               #region Encrypt
+               private void Encrypt128 (byte[] indata, byte[] outdata, uint[] ekey)
+               {
+                       uint a0, a1, a2, a3, b0, b1, b2, b3;
+                       int ei = 40;
+
+                       /* Round 0 */
+                       a0 = (((uint)indata[0] << 24) | ((uint)indata[1] << 16) | ((uint)indata[2] << 8) | (uint)indata[3]) ^ ekey[0];
+                       a1 = (((uint)indata[4] << 24) | ((uint)indata[5] << 16) | ((uint)indata[6] << 8) | (uint)indata[7]) ^ ekey[1];
+                       a2 = (((uint)indata[8] << 24) | ((uint)indata[9] << 16) | ((uint)indata[10] << 8) | (uint)indata[11]) ^ ekey[2];
+                       a3 = (((uint)indata[12] << 24) | ((uint)indata[13] << 16) | ((uint)indata[14] << 8) | (uint)indata[15]) ^ ekey[3];
+
+                       /* Round 1 */
+                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[4];
+                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a0] ^ ekey[5];
+                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[6];
+                       b3 = T0[a3 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[7];
+
+                       /* Round 2 */
+                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[8];
+                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b0] ^ ekey[9];
+                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[10];
+                       a3 = T0[b3 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[11];
+
+                       /* Round 3 */
+                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[12];
+                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a0] ^ ekey[13];
+                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[14];
+                       b3 = T0[a3 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[15];
+
+                       /* Round 4 */
+                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[16];
+                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b0] ^ ekey[17];
+                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[18];
+                       a3 = T0[b3 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[19];
+
+                       /* Round 5 */
+                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[20];
+                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a0] ^ ekey[21];
+                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[22];
+                       b3 = T0[a3 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[23];
+
+                       /* Round 6 */
+                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[24];
+                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b0] ^ ekey[25];
+                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[26];
+                       a3 = T0[b3 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[27];
+
+                       /* Round 7 */
+                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[28];
+                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a0] ^ ekey[29];
+                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[30];
+                       b3 = T0[a3 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[31];
+
+                       /* Round 8 */
+                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[32];
+                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b0] ^ ekey[33];
+                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[34];
+                       a3 = T0[b3 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[35];
+
+                       /* Round 9 */
+                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[36];
+                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a0] ^ ekey[37];
+                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[38];
+                       b3 = T0[a3 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[39];
+
+                       if (Nr > 10) {
+
+                               /* Round 10 */
+                               a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[40];
+                               a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b0] ^ ekey[41];
+                               a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[42];
+                               a3 = T0[b3 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[43];
+
+                               /* Round 11 */
+                               b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[44];
+                               b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a0] ^ ekey[45];
+                               b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[46];
+                               b3 = T0[a3 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[47];
+
+                               ei = 48;
+
+                               if (Nr > 12) {
+
+                                       /* Round 12 */
+                                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[48];
+                                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b0] ^ ekey[49];
+                                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[50];
+                                       a3 = T0[b3 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[51];
+
+                                       /* Round 13 */
+                                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[52];
+                                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a0] ^ ekey[53];
+                                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[54];
+                                       b3 = T0[a3 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[55];
+
+                                       ei = 56;
+                               }
+                       }
+
+                       /* Final Round */
+                       outdata[0] = (byte)(SBox[b0 >> 24] ^ (byte)(ekey[ei] >> 24));
+                       outdata[1] = (byte)(SBox[(byte)(b1 >> 16)] ^ (byte)(ekey[ei] >> 16));
+                       outdata[2] = (byte)(SBox[(byte)(b2 >> 8)] ^ (byte)(ekey[ei] >> 8));
+                       outdata[3] = (byte)(SBox[(byte)b3] ^ (byte)ekey[ei++]);
+
+                       outdata[4] = (byte)(SBox[b1 >> 24] ^ (byte)(ekey[ei] >> 24));
+                       outdata[5] = (byte)(SBox[(byte)(b2 >> 16)] ^ (byte)(ekey[ei] >> 16));
+                       outdata[6] = (byte)(SBox[(byte)(b3 >> 8)] ^ (byte)(ekey[ei] >> 8));
+                       outdata[7] = (byte)(SBox[(byte)b0] ^ (byte)ekey[ei++]);
+
+                       outdata[8] = (byte)(SBox[b2 >> 24] ^ (byte)(ekey[ei] >> 24));
+                       outdata[9] = (byte)(SBox[(byte)(b3 >> 16)] ^ (byte)(ekey[ei] >> 16));
+                       outdata[10] = (byte)(SBox[(byte)(b0 >> 8)] ^ (byte)(ekey[ei] >> 8));
+                       outdata[11] = (byte)(SBox[(byte)b1] ^ (byte)ekey[ei++]);
+
+                       outdata[12] = (byte)(SBox[b3 >> 24] ^ (byte)(ekey[ei] >> 24));
+                       outdata[13] = (byte)(SBox[(byte)(b0 >> 16)] ^ (byte)(ekey[ei] >> 16));
+                       outdata[14] = (byte)(SBox[(byte)(b1 >> 8)] ^ (byte)(ekey[ei] >> 8));
+                       outdata[15] = (byte)(SBox[(byte)b2] ^ (byte)ekey[ei++]);
+               }
+               private void Encrypt192 (byte[] indata, byte[] outdata, uint[] ekey)
+               {
+                       uint a0, a1, a2, a3, a4, a5, b0, b1, b2, b3, b4, b5;
+                       int ei = 72;
+
+                       /* Round 0 */
+                       a0 = (((uint)indata[0] << 24) | ((uint)indata[1] << 16) | ((uint)indata[2] << 8) | (uint)indata[3]) ^ ekey[0];
+                       a1 = (((uint)indata[4] << 24) | ((uint)indata[5] << 16) | ((uint)indata[6] << 8) | (uint)indata[7]) ^ ekey[1];
+                       a2 = (((uint)indata[8] << 24) | ((uint)indata[9] << 16) | ((uint)indata[10] << 8) | (uint)indata[11]) ^ ekey[2];
+                       a3 = (((uint)indata[12] << 24) | ((uint)indata[13] << 16) | ((uint)indata[14] << 8) | (uint)indata[15]) ^ ekey[3];
+                       a4 = (((uint)indata[16] << 24) | ((uint)indata[17] << 16) | ((uint)indata[18] << 8) | (uint)indata[19]) ^ ekey[4];
+                       a5 = (((uint)indata[20] << 24) | ((uint)indata[21] << 16) | ((uint)indata[22] << 8) | (uint)indata[23]) ^ ekey[5];
+
+                       /* Round 1 */
+                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[6];
+                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a4] ^ ekey[7];
+                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a4 >> 8)] ^ T3[(byte)a5] ^ ekey[8];
+                       b3 = T0[a3 >> 24] ^ T1[(byte)(a4 >> 16)] ^ T2[(byte)(a5 >> 8)] ^ T3[(byte)a0] ^ ekey[9];
+                       b4 = T0[a4 >> 24] ^ T1[(byte)(a5 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[10];
+                       b5 = T0[a5 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[11];
+
+                       /* Round 2 */
+                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[12];
+                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b4] ^ ekey[13];
+                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b4 >> 8)] ^ T3[(byte)b5] ^ ekey[14];
+                       a3 = T0[b3 >> 24] ^ T1[(byte)(b4 >> 16)] ^ T2[(byte)(b5 >> 8)] ^ T3[(byte)b0] ^ ekey[15];
+                       a4 = T0[b4 >> 24] ^ T1[(byte)(b5 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[16];
+                       a5 = T0[b5 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[17];
+
+                       /* Round 3 */
+                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[18];
+                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a4] ^ ekey[19];
+                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a4 >> 8)] ^ T3[(byte)a5] ^ ekey[20];
+                       b3 = T0[a3 >> 24] ^ T1[(byte)(a4 >> 16)] ^ T2[(byte)(a5 >> 8)] ^ T3[(byte)a0] ^ ekey[21];
+                       b4 = T0[a4 >> 24] ^ T1[(byte)(a5 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[22];
+                       b5 = T0[a5 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[23];
+
+                       /* Round 4 */
+                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[24];
+                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b4] ^ ekey[25];
+                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b4 >> 8)] ^ T3[(byte)b5] ^ ekey[26];
+                       a3 = T0[b3 >> 24] ^ T1[(byte)(b4 >> 16)] ^ T2[(byte)(b5 >> 8)] ^ T3[(byte)b0] ^ ekey[27];
+                       a4 = T0[b4 >> 24] ^ T1[(byte)(b5 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[28];
+                       a5 = T0[b5 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[29];
+
+                       /* Round 5 */
+                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[30];
+                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a4] ^ ekey[31];
+                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a4 >> 8)] ^ T3[(byte)a5] ^ ekey[32];
+                       b3 = T0[a3 >> 24] ^ T1[(byte)(a4 >> 16)] ^ T2[(byte)(a5 >> 8)] ^ T3[(byte)a0] ^ ekey[33];
+                       b4 = T0[a4 >> 24] ^ T1[(byte)(a5 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[34];
+                       b5 = T0[a5 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[35];
+
+                       /* Round 6 */
+                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[36];
+                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b4] ^ ekey[37];
+                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b4 >> 8)] ^ T3[(byte)b5] ^ ekey[38];
+                       a3 = T0[b3 >> 24] ^ T1[(byte)(b4 >> 16)] ^ T2[(byte)(b5 >> 8)] ^ T3[(byte)b0] ^ ekey[39];
+                       a4 = T0[b4 >> 24] ^ T1[(byte)(b5 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[40];
+                       a5 = T0[b5 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[41];
+
+                       /* Round 7 */
+                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[42];
+                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a4] ^ ekey[43];
+                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a4 >> 8)] ^ T3[(byte)a5] ^ ekey[44];
+                       b3 = T0[a3 >> 24] ^ T1[(byte)(a4 >> 16)] ^ T2[(byte)(a5 >> 8)] ^ T3[(byte)a0] ^ ekey[45];
+                       b4 = T0[a4 >> 24] ^ T1[(byte)(a5 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[46];
+                       b5 = T0[a5 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[47];
+
+                       /* Round 8 */
+                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[48];
+                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b4] ^ ekey[49];
+                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b4 >> 8)] ^ T3[(byte)b5] ^ ekey[50];
+                       a3 = T0[b3 >> 24] ^ T1[(byte)(b4 >> 16)] ^ T2[(byte)(b5 >> 8)] ^ T3[(byte)b0] ^ ekey[51];
+                       a4 = T0[b4 >> 24] ^ T1[(byte)(b5 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[52];
+                       a5 = T0[b5 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[53];
+
+                       /* Round 9 */
+                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[54];
+                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a4] ^ ekey[55];
+                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a4 >> 8)] ^ T3[(byte)a5] ^ ekey[56];
+                       b3 = T0[a3 >> 24] ^ T1[(byte)(a4 >> 16)] ^ T2[(byte)(a5 >> 8)] ^ T3[(byte)a0] ^ ekey[57];
+                       b4 = T0[a4 >> 24] ^ T1[(byte)(a5 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[58];
+                       b5 = T0[a5 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[59];
+
+                       /* Round 10 */
+                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[60];
+                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b4] ^ ekey[61];
+                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b4 >> 8)] ^ T3[(byte)b5] ^ ekey[62];
+                       a3 = T0[b3 >> 24] ^ T1[(byte)(b4 >> 16)] ^ T2[(byte)(b5 >> 8)] ^ T3[(byte)b0] ^ ekey[63];
+                       a4 = T0[b4 >> 24] ^ T1[(byte)(b5 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[64];
+                       a5 = T0[b5 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[65];
+
+                       /* Round 11 */
+                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[66];
+                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a4] ^ ekey[67];
+                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a4 >> 8)] ^ T3[(byte)a5] ^ ekey[68];
+                       b3 = T0[a3 >> 24] ^ T1[(byte)(a4 >> 16)] ^ T2[(byte)(a5 >> 8)] ^ T3[(byte)a0] ^ ekey[69];
+                       b4 = T0[a4 >> 24] ^ T1[(byte)(a5 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[70];
+                       b5 = T0[a5 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[71];
+
+                       if (Nr > 12) {
+
+                               /* Round 12 */
+                               a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[72];
+                               a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b4] ^ ekey[73];
+                               a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b4 >> 8)] ^ T3[(byte)b5] ^ ekey[74];
+                               a3 = T0[b3 >> 24] ^ T1[(byte)(b4 >> 16)] ^ T2[(byte)(b5 >> 8)] ^ T3[(byte)b0] ^ ekey[75];
+                               a4 = T0[b4 >> 24] ^ T1[(byte)(b5 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[76];
+                               a5 = T0[b5 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[77];
+
+                               /* Round 13 */
+                               b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[78];
+                               b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a4] ^ ekey[79];
+                               b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a4 >> 8)] ^ T3[(byte)a5] ^ ekey[80];
+                               b3 = T0[a3 >> 24] ^ T1[(byte)(a4 >> 16)] ^ T2[(byte)(a5 >> 8)] ^ T3[(byte)a0] ^ ekey[81];
+                               b4 = T0[a4 >> 24] ^ T1[(byte)(a5 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[82];
+                               b5 = T0[a5 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[83];
+
+                               ei = 84;
+                       }
+
+                       /* Final Round */
+                       outdata[0] = (byte)(SBox[b0 >> 24] ^ (byte)(ekey[ei] >> 24));
+                       outdata[1] = (byte)(SBox[(byte)(b1 >> 16)] ^ (byte)(ekey[ei] >> 16));
+                       outdata[2] = (byte)(SBox[(byte)(b2 >> 8)] ^ (byte)(ekey[ei] >> 8));
+                       outdata[3] = (byte)(SBox[(byte)b3] ^ (byte)ekey[ei++]);
+
+                       outdata[4] = (byte)(SBox[b1 >> 24] ^ (byte)(ekey[ei] >> 24));
+                       outdata[5] = (byte)(SBox[(byte)(b2 >> 16)] ^ (byte)(ekey[ei] >> 16));
+                       outdata[6] = (byte)(SBox[(byte)(b3 >> 8)] ^ (byte)(ekey[ei] >> 8));
+                       outdata[7] = (byte)(SBox[(byte)b4] ^ (byte)ekey[ei++]);
+
+                       outdata[8] = (byte)(SBox[b2 >> 24] ^ (byte)(ekey[ei] >> 24));
+                       outdata[9] = (byte)(SBox[(byte)(b3 >> 16)] ^ (byte)(ekey[ei] >> 16));
+                       outdata[10] = (byte)(SBox[(byte)(b4 >> 8)] ^ (byte)(ekey[ei] >> 8));
+                       outdata[11] = (byte)(SBox[(byte)b5] ^ (byte)ekey[ei++]);
+
+                       outdata[12] = (byte)(SBox[b3 >> 24] ^ (byte)(ekey[ei] >> 24));
+                       outdata[13] = (byte)(SBox[(byte)(b4 >> 16)] ^ (byte)(ekey[ei] >> 16));
+                       outdata[14] = (byte)(SBox[(byte)(b5 >> 8)] ^ (byte)(ekey[ei] >> 8));
+                       outdata[15] = (byte)(SBox[(byte)b0] ^ (byte)ekey[ei++]);
+
+                       outdata[16] = (byte)(SBox[b4 >> 24] ^ (byte)(ekey[ei] >> 24));
+                       outdata[17] = (byte)(SBox[(byte)(b5 >> 16)] ^ (byte)(ekey[ei] >> 16));
+                       outdata[18] = (byte)(SBox[(byte)(b0 >> 8)] ^ (byte)(ekey[ei] >> 8));
+                       outdata[19] = (byte)(SBox[(byte)b1] ^ (byte)ekey[ei++]);
+
+                       outdata[20] = (byte)(SBox[b5 >> 24] ^ (byte)(ekey[ei] >> 24));
+                       outdata[21] = (byte)(SBox[(byte)(b0 >> 16)] ^ (byte)(ekey[ei] >> 16));
+                       outdata[22] = (byte)(SBox[(byte)(b1 >> 8)] ^ (byte)(ekey[ei] >> 8));
+                       outdata[23] = (byte)(SBox[(byte)b2] ^ (byte)ekey[ei++]);
+               }
+               private void Encrypt256 (byte[] indata, byte[] outdata, uint[] ekey)
+               {
+                       uint a0, a1, a2, a3, a4, a5, a6, a7, b0, b1, b2, b3, b4, b5, b6, b7;
+
+                       /* Round 0 */
+                       a0 = (((uint)indata[0] << 24) | ((uint)indata[1] << 16) | ((uint)indata[2] << 8) | (uint)indata[3]) ^ ekey[0];
+                       a1 = (((uint)indata[4] << 24) | ((uint)indata[5] << 16) | ((uint)indata[6] << 8) | (uint)indata[7]) ^ ekey[1];
+                       a2 = (((uint)indata[8] << 24) | ((uint)indata[9] << 16) | ((uint)indata[10] << 8) | (uint)indata[11]) ^ ekey[2];
+                       a3 = (((uint)indata[12] << 24) | ((uint)indata[13] << 16) | ((uint)indata[14] << 8) | (uint)indata[15]) ^ ekey[3];
+                       a4 = (((uint)indata[16] << 24) | ((uint)indata[17] << 16) | ((uint)indata[18] << 8) | (uint)indata[19]) ^ ekey[4];
+                       a5 = (((uint)indata[20] << 24) | ((uint)indata[21] << 16) | ((uint)indata[22] << 8) | (uint)indata[23]) ^ ekey[5];
+                       a6 = (((uint)indata[24] << 24) | ((uint)indata[25] << 16) | ((uint)indata[26] << 8) | (uint)indata[27]) ^ ekey[6];
+                       a7 = (((uint)indata[28] << 24) | ((uint)indata[29] << 16) | ((uint)indata[30] << 8) | (uint)indata[31]) ^ ekey[7];
+
+                       /* Round 1 */
+                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a4] ^ ekey[8];
+                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a4 >> 8)] ^ T3[(byte)a5] ^ ekey[9];
+                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a5 >> 8)] ^ T3[(byte)a6] ^ ekey[10];
+                       b3 = T0[a3 >> 24] ^ T1[(byte)(a4 >> 16)] ^ T2[(byte)(a6 >> 8)] ^ T3[(byte)a7] ^ ekey[11];
+                       b4 = T0[a4 >> 24] ^ T1[(byte)(a5 >> 16)] ^ T2[(byte)(a7 >> 8)] ^ T3[(byte)a0] ^ ekey[12];
+                       b5 = T0[a5 >> 24] ^ T1[(byte)(a6 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[13];
+                       b6 = T0[a6 >> 24] ^ T1[(byte)(a7 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[14];
+                       b7 = T0[a7 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[15];
+
+                       /* Round 2 */
+                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b4] ^ ekey[16];
+                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b4 >> 8)] ^ T3[(byte)b5] ^ ekey[17];
+                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b5 >> 8)] ^ T3[(byte)b6] ^ ekey[18];
+                       a3 = T0[b3 >> 24] ^ T1[(byte)(b4 >> 16)] ^ T2[(byte)(b6 >> 8)] ^ T3[(byte)b7] ^ ekey[19];
+                       a4 = T0[b4 >> 24] ^ T1[(byte)(b5 >> 16)] ^ T2[(byte)(b7 >> 8)] ^ T3[(byte)b0] ^ ekey[20];
+                       a5 = T0[b5 >> 24] ^ T1[(byte)(b6 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[21];
+                       a6 = T0[b6 >> 24] ^ T1[(byte)(b7 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[22];
+                       a7 = T0[b7 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[23];
+
+                       /* Round 3 */
+                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a4] ^ ekey[24];
+                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a4 >> 8)] ^ T3[(byte)a5] ^ ekey[25];
+                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a5 >> 8)] ^ T3[(byte)a6] ^ ekey[26];
+                       b3 = T0[a3 >> 24] ^ T1[(byte)(a4 >> 16)] ^ T2[(byte)(a6 >> 8)] ^ T3[(byte)a7] ^ ekey[27];
+                       b4 = T0[a4 >> 24] ^ T1[(byte)(a5 >> 16)] ^ T2[(byte)(a7 >> 8)] ^ T3[(byte)a0] ^ ekey[28];
+                       b5 = T0[a5 >> 24] ^ T1[(byte)(a6 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[29];
+                       b6 = T0[a6 >> 24] ^ T1[(byte)(a7 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[30];
+                       b7 = T0[a7 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[31];
+
+                       /* Round 4 */
+                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b4] ^ ekey[32];
+                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b4 >> 8)] ^ T3[(byte)b5] ^ ekey[33];
+                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b5 >> 8)] ^ T3[(byte)b6] ^ ekey[34];
+                       a3 = T0[b3 >> 24] ^ T1[(byte)(b4 >> 16)] ^ T2[(byte)(b6 >> 8)] ^ T3[(byte)b7] ^ ekey[35];
+                       a4 = T0[b4 >> 24] ^ T1[(byte)(b5 >> 16)] ^ T2[(byte)(b7 >> 8)] ^ T3[(byte)b0] ^ ekey[36];
+                       a5 = T0[b5 >> 24] ^ T1[(byte)(b6 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[37];
+                       a6 = T0[b6 >> 24] ^ T1[(byte)(b7 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[38];
+                       a7 = T0[b7 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[39];
+
+                       /* Round 5 */
+                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a4] ^ ekey[40];
+                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a4 >> 8)] ^ T3[(byte)a5] ^ ekey[41];
+                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a5 >> 8)] ^ T3[(byte)a6] ^ ekey[42];
+                       b3 = T0[a3 >> 24] ^ T1[(byte)(a4 >> 16)] ^ T2[(byte)(a6 >> 8)] ^ T3[(byte)a7] ^ ekey[43];
+                       b4 = T0[a4 >> 24] ^ T1[(byte)(a5 >> 16)] ^ T2[(byte)(a7 >> 8)] ^ T3[(byte)a0] ^ ekey[44];
+                       b5 = T0[a5 >> 24] ^ T1[(byte)(a6 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[45];
+                       b6 = T0[a6 >> 24] ^ T1[(byte)(a7 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[46];
+                       b7 = T0[a7 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[47];
+
+                       /* Round 6 */
+                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b4] ^ ekey[48];
+                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b4 >> 8)] ^ T3[(byte)b5] ^ ekey[49];
+                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b5 >> 8)] ^ T3[(byte)b6] ^ ekey[50];
+                       a3 = T0[b3 >> 24] ^ T1[(byte)(b4 >> 16)] ^ T2[(byte)(b6 >> 8)] ^ T3[(byte)b7] ^ ekey[51];
+                       a4 = T0[b4 >> 24] ^ T1[(byte)(b5 >> 16)] ^ T2[(byte)(b7 >> 8)] ^ T3[(byte)b0] ^ ekey[52];
+                       a5 = T0[b5 >> 24] ^ T1[(byte)(b6 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[53];
+                       a6 = T0[b6 >> 24] ^ T1[(byte)(b7 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[54];
+                       a7 = T0[b7 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[55];
+
+                       /* Round 7 */
+                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a4] ^ ekey[56];
+                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a4 >> 8)] ^ T3[(byte)a5] ^ ekey[57];
+                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a5 >> 8)] ^ T3[(byte)a6] ^ ekey[58];
+                       b3 = T0[a3 >> 24] ^ T1[(byte)(a4 >> 16)] ^ T2[(byte)(a6 >> 8)] ^ T3[(byte)a7] ^ ekey[59];
+                       b4 = T0[a4 >> 24] ^ T1[(byte)(a5 >> 16)] ^ T2[(byte)(a7 >> 8)] ^ T3[(byte)a0] ^ ekey[60];
+                       b5 = T0[a5 >> 24] ^ T1[(byte)(a6 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[61];
+                       b6 = T0[a6 >> 24] ^ T1[(byte)(a7 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[62];
+                       b7 = T0[a7 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[63];
+
+                       /* Round 8 */
+                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b4] ^ ekey[64];
+                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b4 >> 8)] ^ T3[(byte)b5] ^ ekey[65];
+                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b5 >> 8)] ^ T3[(byte)b6] ^ ekey[66];
+                       a3 = T0[b3 >> 24] ^ T1[(byte)(b4 >> 16)] ^ T2[(byte)(b6 >> 8)] ^ T3[(byte)b7] ^ ekey[67];
+                       a4 = T0[b4 >> 24] ^ T1[(byte)(b5 >> 16)] ^ T2[(byte)(b7 >> 8)] ^ T3[(byte)b0] ^ ekey[68];
+                       a5 = T0[b5 >> 24] ^ T1[(byte)(b6 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[69];
+                       a6 = T0[b6 >> 24] ^ T1[(byte)(b7 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[70];
+                       a7 = T0[b7 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[71];
+
+                       /* Round 9 */
+                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a4] ^ ekey[72];
+                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a4 >> 8)] ^ T3[(byte)a5] ^ ekey[73];
+                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a5 >> 8)] ^ T3[(byte)a6] ^ ekey[74];
+                       b3 = T0[a3 >> 24] ^ T1[(byte)(a4 >> 16)] ^ T2[(byte)(a6 >> 8)] ^ T3[(byte)a7] ^ ekey[75];
+                       b4 = T0[a4 >> 24] ^ T1[(byte)(a5 >> 16)] ^ T2[(byte)(a7 >> 8)] ^ T3[(byte)a0] ^ ekey[76];
+                       b5 = T0[a5 >> 24] ^ T1[(byte)(a6 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[77];
+                       b6 = T0[a6 >> 24] ^ T1[(byte)(a7 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[78];
+                       b7 = T0[a7 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[79];
+
+                       /* Round 10 */
+                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b4] ^ ekey[80];
+                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b4 >> 8)] ^ T3[(byte)b5] ^ ekey[81];
+                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b5 >> 8)] ^ T3[(byte)b6] ^ ekey[82];
+                       a3 = T0[b3 >> 24] ^ T1[(byte)(b4 >> 16)] ^ T2[(byte)(b6 >> 8)] ^ T3[(byte)b7] ^ ekey[83];
+                       a4 = T0[b4 >> 24] ^ T1[(byte)(b5 >> 16)] ^ T2[(byte)(b7 >> 8)] ^ T3[(byte)b0] ^ ekey[84];
+                       a5 = T0[b5 >> 24] ^ T1[(byte)(b6 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[85];
+                       a6 = T0[b6 >> 24] ^ T1[(byte)(b7 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[86];
+                       a7 = T0[b7 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[87];
+
+                       /* Round 11 */
+                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a4] ^ ekey[88];
+                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a4 >> 8)] ^ T3[(byte)a5] ^ ekey[89];
+                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a5 >> 8)] ^ T3[(byte)a6] ^ ekey[90];
+                       b3 = T0[a3 >> 24] ^ T1[(byte)(a4 >> 16)] ^ T2[(byte)(a6 >> 8)] ^ T3[(byte)a7] ^ ekey[91];
+                       b4 = T0[a4 >> 24] ^ T1[(byte)(a5 >> 16)] ^ T2[(byte)(a7 >> 8)] ^ T3[(byte)a0] ^ ekey[92];
+                       b5 = T0[a5 >> 24] ^ T1[(byte)(a6 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[93];
+                       b6 = T0[a6 >> 24] ^ T1[(byte)(a7 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[94];
+                       b7 = T0[a7 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[95];
+
+                       /* Round 12 */
+                       a0 = T0[b0 >> 24] ^ T1[(byte)(b1 >> 16)] ^ T2[(byte)(b3 >> 8)] ^ T3[(byte)b4] ^ ekey[96];
+                       a1 = T0[b1 >> 24] ^ T1[(byte)(b2 >> 16)] ^ T2[(byte)(b4 >> 8)] ^ T3[(byte)b5] ^ ekey[97];
+                       a2 = T0[b2 >> 24] ^ T1[(byte)(b3 >> 16)] ^ T2[(byte)(b5 >> 8)] ^ T3[(byte)b6] ^ ekey[98];
+                       a3 = T0[b3 >> 24] ^ T1[(byte)(b4 >> 16)] ^ T2[(byte)(b6 >> 8)] ^ T3[(byte)b7] ^ ekey[99];
+                       a4 = T0[b4 >> 24] ^ T1[(byte)(b5 >> 16)] ^ T2[(byte)(b7 >> 8)] ^ T3[(byte)b0] ^ ekey[100];
+                       a5 = T0[b5 >> 24] ^ T1[(byte)(b6 >> 16)] ^ T2[(byte)(b0 >> 8)] ^ T3[(byte)b1] ^ ekey[101];
+                       a6 = T0[b6 >> 24] ^ T1[(byte)(b7 >> 16)] ^ T2[(byte)(b1 >> 8)] ^ T3[(byte)b2] ^ ekey[102];
+                       a7 = T0[b7 >> 24] ^ T1[(byte)(b0 >> 16)] ^ T2[(byte)(b2 >> 8)] ^ T3[(byte)b3] ^ ekey[103];
+
+                       /* Round 13 */
+                       b0 = T0[a0 >> 24] ^ T1[(byte)(a1 >> 16)] ^ T2[(byte)(a3 >> 8)] ^ T3[(byte)a4] ^ ekey[104];
+                       b1 = T0[a1 >> 24] ^ T1[(byte)(a2 >> 16)] ^ T2[(byte)(a4 >> 8)] ^ T3[(byte)a5] ^ ekey[105];
+                       b2 = T0[a2 >> 24] ^ T1[(byte)(a3 >> 16)] ^ T2[(byte)(a5 >> 8)] ^ T3[(byte)a6] ^ ekey[106];
+                       b3 = T0[a3 >> 24] ^ T1[(byte)(a4 >> 16)] ^ T2[(byte)(a6 >> 8)] ^ T3[(byte)a7] ^ ekey[107];
+                       b4 = T0[a4 >> 24] ^ T1[(byte)(a5 >> 16)] ^ T2[(byte)(a7 >> 8)] ^ T3[(byte)a0] ^ ekey[108];
+                       b5 = T0[a5 >> 24] ^ T1[(byte)(a6 >> 16)] ^ T2[(byte)(a0 >> 8)] ^ T3[(byte)a1] ^ ekey[109];
+                       b6 = T0[a6 >> 24] ^ T1[(byte)(a7 >> 16)] ^ T2[(byte)(a1 >> 8)] ^ T3[(byte)a2] ^ ekey[110];
+                       b7 = T0[a7 >> 24] ^ T1[(byte)(a0 >> 16)] ^ T2[(byte)(a2 >> 8)] ^ T3[(byte)a3] ^ ekey[111];
+
+                       /* Final Round */
+                       outdata[0] = (byte)(SBox[b0 >> 24] ^ (byte)(ekey[112] >> 24));
+                       outdata[1] = (byte)(SBox[(byte)(b1 >> 16)] ^ (byte)(ekey[112] >> 16));
+                       outdata[2] = (byte)(SBox[(byte)(b3 >> 8)] ^ (byte)(ekey[112] >> 8));
+                       outdata[3] = (byte)(SBox[(byte)b4] ^ (byte)ekey[112]);
+
+                       outdata[4] = (byte)(SBox[b1 >> 24] ^ (byte)(ekey[113] >> 24));
+                       outdata[5] = (byte)(SBox[(byte)(b2 >> 16)] ^ (byte)(ekey[113] >> 16));
+                       outdata[6] = (byte)(SBox[(byte)(b4 >> 8)] ^ (byte)(ekey[113] >> 8));
+                       outdata[7] = (byte)(SBox[(byte)b5] ^ (byte)ekey[113]);
+
+                       outdata[8] = (byte)(SBox[b2 >> 24] ^ (byte)(ekey[114] >> 24));
+                       outdata[9] = (byte)(SBox[(byte)(b3 >> 16)] ^ (byte)(ekey[114] >> 16));
+                       outdata[10] = (byte)(SBox[(byte)(b5 >> 8)] ^ (byte)(ekey[114] >> 8));
+                       outdata[11] = (byte)(SBox[(byte)b6] ^ (byte)ekey[114]);
+
+                       outdata[12] = (byte)(SBox[b3 >> 24] ^ (byte)(ekey[115] >> 24));
+                       outdata[13] = (byte)(SBox[(byte)(b4 >> 16)] ^ (byte)(ekey[115] >> 16));
+                       outdata[14] = (byte)(SBox[(byte)(b6 >> 8)] ^ (byte)(ekey[115] >> 8));
+                       outdata[15] = (byte)(SBox[(byte)b7] ^ (byte)ekey[115]);
+
+                       outdata[16] = (byte)(SBox[b4 >> 24] ^ (byte)(ekey[116] >> 24));
+                       outdata[17] = (byte)(SBox[(byte)(b5 >> 16)] ^ (byte)(ekey[116] >> 16));
+                       outdata[18] = (byte)(SBox[(byte)(b7 >> 8)] ^ (byte)(ekey[116] >> 8));
+                       outdata[19] = (byte)(SBox[(byte)b0] ^ (byte)ekey[116]);
+
+                       outdata[20] = (byte)(SBox[b5 >> 24] ^ (byte)(ekey[117] >> 24));
+                       outdata[21] = (byte)(SBox[(byte)(b6 >> 16)] ^ (byte)(ekey[117] >> 16));
+                       outdata[22] = (byte)(SBox[(byte)(b0 >> 8)] ^ (byte)(ekey[117] >> 8));
+                       outdata[23] = (byte)(SBox[(byte)b1] ^ (byte)ekey[117]);
+
+                       outdata[24] = (byte)(SBox[b6 >> 24] ^ (byte)(ekey[118] >> 24));
+                       outdata[25] = (byte)(SBox[(byte)(b7 >> 16)] ^ (byte)(ekey[118] >> 16));
+                       outdata[26] = (byte)(SBox[(byte)(b1 >> 8)] ^ (byte)(ekey[118] >> 8));
+                       outdata[27] = (byte)(SBox[(byte)b2] ^ (byte)ekey[118]);
+
+                       outdata[28] = (byte)(SBox[b7 >> 24] ^ (byte)(ekey[119] >> 24));
+                       outdata[29] = (byte)(SBox[(byte)(b0 >> 16)] ^ (byte)(ekey[119] >> 16));
+                       outdata[30] = (byte)(SBox[(byte)(b2 >> 8)] ^ (byte)(ekey[119] >> 8));
+                       outdata[31] = (byte)(SBox[(byte)b3] ^ (byte)ekey[119]);
+               }
+               #endregion
+
+               #region Decrypt
+               private void Decrypt128 (byte[] indata, byte[] outdata, uint[] ekey)
+               {
+                       uint a0, a1, a2, a3, b0, b1, b2, b3;
+                       int ei = 40;
+
+                       /* Round 0 */
+                       a0 = (((uint)indata[0] << 24) | ((uint)indata[1] << 16) | ((uint)indata[2] << 8) | (uint)indata[3]) ^ ekey[0];
+                       a1 = (((uint)indata[4] << 24) | ((uint)indata[5] << 16) | ((uint)indata[6] << 8) | (uint)indata[7]) ^ ekey[1];
+                       a2 = (((uint)indata[8] << 24) | ((uint)indata[9] << 16) | ((uint)indata[10] << 8) | (uint)indata[11]) ^ ekey[2];
+                       a3 = (((uint)indata[12] << 24) | ((uint)indata[13] << 16) | ((uint)indata[14] << 8) | (uint)indata[15]) ^ ekey[3];
+
+                       /* Round 1 */
+                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[4];
+                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[5];
+                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a3] ^ ekey[6];
+                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[7];
+
+                       /* Round 2 */
+                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[8];
+                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[9];
+                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b3] ^ ekey[10];
+                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[11];
+
+                       /* Round 3 */
+                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[12];
+                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[13];
+                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a3] ^ ekey[14];
+                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[15];
+
+                       /* Round 4 */
+                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[16];
+                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[17];
+                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b3] ^ ekey[18];
+                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[19];
+
+                       /* Round 5 */
+                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[20];
+                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[21];
+                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a3] ^ ekey[22];
+                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[23];
+
+                       /* Round 6 */
+                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[24];
+                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[25];
+                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b3] ^ ekey[26];
+                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[27];
+
+                       /* Round 7 */
+                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[28];
+                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[29];
+                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a3] ^ ekey[30];
+                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[31];
+
+                       /* Round 8 */
+                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[32];
+                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[33];
+                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b3] ^ ekey[34];
+                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[35];
+
+                       /* Round 9 */
+                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[36];
+                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[37];
+                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a3] ^ ekey[38];
+                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[39];
+
+                       if (Nr > 10) {
+
+                               /* Round 10 */
+                               a0 = iT0[b0 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[40];
+                               a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[41];
+                               a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b3] ^ ekey[42];
+                               a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[43];
+
+                               /* Round 11 */
+                               b0 = iT0[a0 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[44];
+                               b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[45];
+                               b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a3] ^ ekey[46];
+                               b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[47];
+
+                               ei = 48;
+
+                               if (Nr > 12) {
+
+                                       /* Round 12 */
+                                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[48];
+                                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[49];
+                                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b3] ^ ekey[50];
+                                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[51];
+
+                                       /* Round 13 */
+                                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[52];
+                                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[53];
+                                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a3] ^ ekey[54];
+                                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[55];
+                                       
+                                       ei = 56;
+                               }
+                       }
+
+                       /* Final Round */
+                       outdata[0] = (byte)(iSBox[b0 >> 24] ^ (byte)(ekey[ei] >> 24));
+                       outdata[1] = (byte)(iSBox[(byte)(b3 >> 16)] ^ (byte)(ekey[ei] >> 16));
+                       outdata[2] = (byte)(iSBox[(byte)(b2 >> 8)] ^ (byte)(ekey[ei] >> 8));
+                       outdata[3] = (byte)(iSBox[(byte)b1] ^ (byte)ekey[ei++]);
+
+                       outdata[4] = (byte)(iSBox[b1 >> 24] ^ (byte)(ekey[ei] >> 24));
+                       outdata[5] = (byte)(iSBox[(byte)(b0 >> 16)] ^ (byte)(ekey[ei] >> 16));
+                       outdata[6] = (byte)(iSBox[(byte)(b3 >> 8)] ^ (byte)(ekey[ei] >> 8));
+                       outdata[7] = (byte)(iSBox[(byte)b2] ^ (byte)ekey[ei++]);
+
+                       outdata[8] = (byte)(iSBox[b2 >> 24] ^ (byte)(ekey[ei] >> 24));
+                       outdata[9] = (byte)(iSBox[(byte)(b1 >> 16)] ^ (byte)(ekey[ei] >> 16));
+                       outdata[10] = (byte)(iSBox[(byte)(b0 >> 8)] ^ (byte)(ekey[ei] >> 8));
+                       outdata[11] = (byte)(iSBox[(byte)b3] ^ (byte)ekey[ei++]);
+
+                       outdata[12] = (byte)(iSBox[b3 >> 24] ^ (byte)(ekey[ei] >> 24));
+                       outdata[13] = (byte)(iSBox[(byte)(b2 >> 16)] ^ (byte)(ekey[ei] >> 16));
+                       outdata[14] = (byte)(iSBox[(byte)(b1 >> 8)] ^ (byte)(ekey[ei] >> 8));
+                       outdata[15] = (byte)(iSBox[(byte)b0] ^ (byte)ekey[ei++]);
+               }
+               private void Decrypt192 (byte[] indata, byte[] outdata, uint[] ekey)
+               {
+                       uint a0, a1, a2, a3, a4, a5, b0, b1, b2, b3, b4, b5;
+                       int ei = 72;
+
+                       /* Round 0 */
+                       a0 = (((uint)indata[0] << 24) | ((uint)indata[1] << 16) | ((uint)indata[2] << 8) | (uint)indata[3]) ^ ekey[0];
+                       a1 = (((uint)indata[4] << 24) | ((uint)indata[5] << 16) | ((uint)indata[6] << 8) | (uint)indata[7]) ^ ekey[1];
+                       a2 = (((uint)indata[8] << 24) | ((uint)indata[9] << 16) | ((uint)indata[10] << 8) | (uint)indata[11]) ^ ekey[2];
+                       a3 = (((uint)indata[12] << 24) | ((uint)indata[13] << 16) | ((uint)indata[14] << 8) | (uint)indata[15]) ^ ekey[3];
+                       a4 = (((uint)indata[16] << 24) | ((uint)indata[17] << 16) | ((uint)indata[18] << 8) | (uint)indata[19]) ^ ekey[4];
+                       a5 = (((uint)indata[20] << 24) | ((uint)indata[21] << 16) | ((uint)indata[22] << 8) | (uint)indata[23]) ^ ekey[5];
+
+                       /* Round 1 */
+                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a5 >> 16)] ^ iT2[(byte)(a4 >> 8)] ^ iT3[(byte)a3] ^ ekey[6];
+                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a5 >> 8)] ^ iT3[(byte)a4] ^ ekey[7];
+                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a5] ^ ekey[8];
+                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[9];
+                       b4 = iT0[a4 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[10];
+                       b5 = iT0[a5 >> 24] ^ iT1[(byte)(a4 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[11];
+
+                       /* Round 2 */
+                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b5 >> 16)] ^ iT2[(byte)(b4 >> 8)] ^ iT3[(byte)b3] ^ ekey[12];
+                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b5 >> 8)] ^ iT3[(byte)b4] ^ ekey[13];
+                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b5] ^ ekey[14];
+                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[15];
+                       a4 = iT0[b4 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[16];
+                       a5 = iT0[b5 >> 24] ^ iT1[(byte)(b4 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[17];
+
+                       /* Round 3 */
+                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a5 >> 16)] ^ iT2[(byte)(a4 >> 8)] ^ iT3[(byte)a3] ^ ekey[18];
+                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a5 >> 8)] ^ iT3[(byte)a4] ^ ekey[19];
+                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a5] ^ ekey[20];
+                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[21];
+                       b4 = iT0[a4 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[22];
+                       b5 = iT0[a5 >> 24] ^ iT1[(byte)(a4 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[23];
+
+                       /* Round 4 */
+                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b5 >> 16)] ^ iT2[(byte)(b4 >> 8)] ^ iT3[(byte)b3] ^ ekey[24];
+                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b5 >> 8)] ^ iT3[(byte)b4] ^ ekey[25];
+                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b5] ^ ekey[26];
+                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[27];
+                       a4 = iT0[b4 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[28];
+                       a5 = iT0[b5 >> 24] ^ iT1[(byte)(b4 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[29];
+
+                       /* Round 5 */
+                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a5 >> 16)] ^ iT2[(byte)(a4 >> 8)] ^ iT3[(byte)a3] ^ ekey[30];
+                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a5 >> 8)] ^ iT3[(byte)a4] ^ ekey[31];
+                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a5] ^ ekey[32];
+                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[33];
+                       b4 = iT0[a4 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[34];
+                       b5 = iT0[a5 >> 24] ^ iT1[(byte)(a4 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[35];
+
+                       /* Round 6 */
+                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b5 >> 16)] ^ iT2[(byte)(b4 >> 8)] ^ iT3[(byte)b3] ^ ekey[36];
+                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b5 >> 8)] ^ iT3[(byte)b4] ^ ekey[37];
+                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b5] ^ ekey[38];
+                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[39];
+                       a4 = iT0[b4 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[40];
+                       a5 = iT0[b5 >> 24] ^ iT1[(byte)(b4 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[41];
+
+                       /* Round 7 */
+                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a5 >> 16)] ^ iT2[(byte)(a4 >> 8)] ^ iT3[(byte)a3] ^ ekey[42];
+                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a5 >> 8)] ^ iT3[(byte)a4] ^ ekey[43];
+                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a5] ^ ekey[44];
+                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[45];
+                       b4 = iT0[a4 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[46];
+                       b5 = iT0[a5 >> 24] ^ iT1[(byte)(a4 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[47];
+
+                       /* Round 8 */
+                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b5 >> 16)] ^ iT2[(byte)(b4 >> 8)] ^ iT3[(byte)b3] ^ ekey[48];
+                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b5 >> 8)] ^ iT3[(byte)b4] ^ ekey[49];
+                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b5] ^ ekey[50];
+                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[51];
+                       a4 = iT0[b4 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[52];
+                       a5 = iT0[b5 >> 24] ^ iT1[(byte)(b4 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[53];
+
+                       /* Round 9 */
+                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a5 >> 16)] ^ iT2[(byte)(a4 >> 8)] ^ iT3[(byte)a3] ^ ekey[54];
+                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a5 >> 8)] ^ iT3[(byte)a4] ^ ekey[55];
+                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a5] ^ ekey[56];
+                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[57];
+                       b4 = iT0[a4 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[58];
+                       b5 = iT0[a5 >> 24] ^ iT1[(byte)(a4 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[59];
+
+                       /* Round 10 */
+                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b5 >> 16)] ^ iT2[(byte)(b4 >> 8)] ^ iT3[(byte)b3] ^ ekey[60];
+                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b5 >> 8)] ^ iT3[(byte)b4] ^ ekey[61];
+                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b5] ^ ekey[62];
+                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[63];
+                       a4 = iT0[b4 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[64];
+                       a5 = iT0[b5 >> 24] ^ iT1[(byte)(b4 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[65];
+
+                       /* Round 11 */
+                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a5 >> 16)] ^ iT2[(byte)(a4 >> 8)] ^ iT3[(byte)a3] ^ ekey[66];
+                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a5 >> 8)] ^ iT3[(byte)a4] ^ ekey[67];
+                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a5] ^ ekey[68];
+                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[69];
+                       b4 = iT0[a4 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[70];
+                       b5 = iT0[a5 >> 24] ^ iT1[(byte)(a4 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[71];
+
+                       if (Nr > 12) {
+
+                               /* Round 12 */
+                               a0 = iT0[b0 >> 24] ^ iT1[(byte)(b5 >> 16)] ^ iT2[(byte)(b4 >> 8)] ^ iT3[(byte)b3] ^ ekey[72];
+                               a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b5 >> 8)] ^ iT3[(byte)b4] ^ ekey[73];
+                               a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b5] ^ ekey[74];
+                               a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[75];
+                               a4 = iT0[b4 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[76];
+                               a5 = iT0[b5 >> 24] ^ iT1[(byte)(b4 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[77];
+
+                               /* Round 13 */
+                               b0 = iT0[a0 >> 24] ^ iT1[(byte)(a5 >> 16)] ^ iT2[(byte)(a4 >> 8)] ^ iT3[(byte)a3] ^ ekey[78];
+                               b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a5 >> 8)] ^ iT3[(byte)a4] ^ ekey[79];
+                               b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a5] ^ ekey[80];
+                               b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[81];
+                               b4 = iT0[a4 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[82];
+                               b5 = iT0[a5 >> 24] ^ iT1[(byte)(a4 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[83];
+
+                               ei = 84;
+                       }
+
+                       /* Final Round */
+                       outdata[0] = (byte)(iSBox[b0 >> 24] ^ (byte)(ekey[ei] >> 24));
+                       outdata[1] = (byte)(iSBox[(byte)(b5 >> 16)] ^ (byte)(ekey[ei] >> 16));
+                       outdata[2] = (byte)(iSBox[(byte)(b4 >> 8)] ^ (byte)(ekey[ei] >> 8));
+                       outdata[3] = (byte)(iSBox[(byte)b3] ^ (byte)ekey[ei++]);
+
+                       outdata[4] = (byte)(iSBox[b1 >> 24] ^ (byte)(ekey[ei] >> 24));
+                       outdata[5] = (byte)(iSBox[(byte)(b0 >> 16)] ^ (byte)(ekey[ei] >> 16));
+                       outdata[6] = (byte)(iSBox[(byte)(b5 >> 8)] ^ (byte)(ekey[ei] >> 8));
+                       outdata[7] = (byte)(iSBox[(byte)b4] ^ (byte)ekey[ei++]);
+
+                       outdata[8] = (byte)(iSBox[b2 >> 24] ^ (byte)(ekey[ei] >> 24));
+                       outdata[9] = (byte)(iSBox[(byte)(b1 >> 16)] ^ (byte)(ekey[ei] >> 16));
+                       outdata[10] = (byte)(iSBox[(byte)(b0 >> 8)] ^ (byte)(ekey[ei] >> 8));
+                       outdata[11] = (byte)(iSBox[(byte)b5] ^ (byte)ekey[ei++]);
+
+                       outdata[12] = (byte)(iSBox[b3 >> 24] ^ (byte)(ekey[ei] >> 24));
+                       outdata[13] = (byte)(iSBox[(byte)(b2 >> 16)] ^ (byte)(ekey[ei] >> 16));
+                       outdata[14] = (byte)(iSBox[(byte)(b1 >> 8)] ^ (byte)(ekey[ei] >> 8));
+                       outdata[15] = (byte)(iSBox[(byte)b0] ^ (byte)ekey[ei++]);
+
+                       outdata[16] = (byte)(iSBox[b4 >> 24] ^ (byte)(ekey[ei] >> 24));
+                       outdata[17] = (byte)(iSBox[(byte)(b3 >> 16)] ^ (byte)(ekey[ei] >> 16));
+                       outdata[18] = (byte)(iSBox[(byte)(b2 >> 8)] ^ (byte)(ekey[ei] >> 8));
+                       outdata[19] = (byte)(iSBox[(byte)b1] ^ (byte)ekey[ei++]);
+
+                       outdata[20] = (byte)(iSBox[b5 >> 24] ^ (byte)(ekey[ei] >> 24));
+                       outdata[21] = (byte)(iSBox[(byte)(b4 >> 16)] ^ (byte)(ekey[ei] >> 16));
+                       outdata[22] = (byte)(iSBox[(byte)(b3 >> 8)] ^ (byte)(ekey[ei] >> 8));
+                       outdata[23] = (byte)(iSBox[(byte)b2] ^ (byte)ekey[ei++]);
+               }
+               private void Decrypt256 (byte[] indata, byte[] outdata, uint[] ekey)
+               {
+                       uint a0, a1, a2, a3, a4, a5, a6, a7, b0, b1, b2, b3, b4, b5, b6, b7;
+
+                       /* Round 0 */
+                       a0 = (((uint)indata[0] << 24) | ((uint)indata[1] << 16) | ((uint)indata[2] << 8) | (uint)indata[3]) ^ ekey[0];
+                       a1 = (((uint)indata[4] << 24) | ((uint)indata[5] << 16) | ((uint)indata[6] << 8) | (uint)indata[7]) ^ ekey[1];
+                       a2 = (((uint)indata[8] << 24) | ((uint)indata[9] << 16) | ((uint)indata[10] << 8) | (uint)indata[11]) ^ ekey[2];
+                       a3 = (((uint)indata[12] << 24) | ((uint)indata[13] << 16) | ((uint)indata[14] << 8) | (uint)indata[15]) ^ ekey[3];
+                       a4 = (((uint)indata[16] << 24) | ((uint)indata[17] << 16) | ((uint)indata[18] << 8) | (uint)indata[19]) ^ ekey[4];
+                       a5 = (((uint)indata[20] << 24) | ((uint)indata[21] << 16) | ((uint)indata[22] << 8) | (uint)indata[23]) ^ ekey[5];
+                       a6 = (((uint)indata[24] << 24) | ((uint)indata[25] << 16) | ((uint)indata[26] << 8) | (uint)indata[27]) ^ ekey[6];
+                       a7 = (((uint)indata[28] << 24) | ((uint)indata[29] << 16) | ((uint)indata[30] << 8) | (uint)indata[31]) ^ ekey[7];
+
+                       /* Round 1 */
+                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a7 >> 16)] ^ iT2[(byte)(a5 >> 8)] ^ iT3[(byte)a4] ^ ekey[8];
+                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a6 >> 8)] ^ iT3[(byte)a5] ^ ekey[9];
+                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a7 >> 8)] ^ iT3[(byte)a6] ^ ekey[10];
+                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a7] ^ ekey[11];
+                       b4 = iT0[a4 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[12];
+                       b5 = iT0[a5 >> 24] ^ iT1[(byte)(a4 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[13];
+                       b6 = iT0[a6 >> 24] ^ iT1[(byte)(a5 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[14];
+                       b7 = iT0[a7 >> 24] ^ iT1[(byte)(a6 >> 16)] ^ iT2[(byte)(a4 >> 8)] ^ iT3[(byte)a3] ^ ekey[15];
+
+                       /* Round 2 */
+                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b7 >> 16)] ^ iT2[(byte)(b5 >> 8)] ^ iT3[(byte)b4] ^ ekey[16];
+                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b6 >> 8)] ^ iT3[(byte)b5] ^ ekey[17];
+                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b7 >> 8)] ^ iT3[(byte)b6] ^ ekey[18];
+                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b7] ^ ekey[19];
+                       a4 = iT0[b4 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[20];
+                       a5 = iT0[b5 >> 24] ^ iT1[(byte)(b4 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[21];
+                       a6 = iT0[b6 >> 24] ^ iT1[(byte)(b5 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[22];
+                       a7 = iT0[b7 >> 24] ^ iT1[(byte)(b6 >> 16)] ^ iT2[(byte)(b4 >> 8)] ^ iT3[(byte)b3] ^ ekey[23];
+
+                       /* Round 3 */
+                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a7 >> 16)] ^ iT2[(byte)(a5 >> 8)] ^ iT3[(byte)a4] ^ ekey[24];
+                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a6 >> 8)] ^ iT3[(byte)a5] ^ ekey[25];
+                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a7 >> 8)] ^ iT3[(byte)a6] ^ ekey[26];
+                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a7] ^ ekey[27];
+                       b4 = iT0[a4 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[28];
+                       b5 = iT0[a5 >> 24] ^ iT1[(byte)(a4 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[29];
+                       b6 = iT0[a6 >> 24] ^ iT1[(byte)(a5 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[30];
+                       b7 = iT0[a7 >> 24] ^ iT1[(byte)(a6 >> 16)] ^ iT2[(byte)(a4 >> 8)] ^ iT3[(byte)a3] ^ ekey[31];
+
+                       /* Round 4 */
+                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b7 >> 16)] ^ iT2[(byte)(b5 >> 8)] ^ iT3[(byte)b4] ^ ekey[32];
+                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b6 >> 8)] ^ iT3[(byte)b5] ^ ekey[33];
+                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b7 >> 8)] ^ iT3[(byte)b6] ^ ekey[34];
+                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b7] ^ ekey[35];
+                       a4 = iT0[b4 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[36];
+                       a5 = iT0[b5 >> 24] ^ iT1[(byte)(b4 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[37];
+                       a6 = iT0[b6 >> 24] ^ iT1[(byte)(b5 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[38];
+                       a7 = iT0[b7 >> 24] ^ iT1[(byte)(b6 >> 16)] ^ iT2[(byte)(b4 >> 8)] ^ iT3[(byte)b3] ^ ekey[39];
+
+                       /* Round 5 */
+                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a7 >> 16)] ^ iT2[(byte)(a5 >> 8)] ^ iT3[(byte)a4] ^ ekey[40];
+                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a6 >> 8)] ^ iT3[(byte)a5] ^ ekey[41];
+                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a7 >> 8)] ^ iT3[(byte)a6] ^ ekey[42];
+                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a7] ^ ekey[43];
+                       b4 = iT0[a4 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[44];
+                       b5 = iT0[a5 >> 24] ^ iT1[(byte)(a4 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[45];
+                       b6 = iT0[a6 >> 24] ^ iT1[(byte)(a5 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[46];
+                       b7 = iT0[a7 >> 24] ^ iT1[(byte)(a6 >> 16)] ^ iT2[(byte)(a4 >> 8)] ^ iT3[(byte)a3] ^ ekey[47];
+
+                       /* Round 6 */
+                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b7 >> 16)] ^ iT2[(byte)(b5 >> 8)] ^ iT3[(byte)b4] ^ ekey[48];
+                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b6 >> 8)] ^ iT3[(byte)b5] ^ ekey[49];
+                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b7 >> 8)] ^ iT3[(byte)b6] ^ ekey[50];
+                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b7] ^ ekey[51];
+                       a4 = iT0[b4 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[52];
+                       a5 = iT0[b5 >> 24] ^ iT1[(byte)(b4 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[53];
+                       a6 = iT0[b6 >> 24] ^ iT1[(byte)(b5 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[54];
+                       a7 = iT0[b7 >> 24] ^ iT1[(byte)(b6 >> 16)] ^ iT2[(byte)(b4 >> 8)] ^ iT3[(byte)b3] ^ ekey[55];
+
+                       /* Round 7 */
+                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a7 >> 16)] ^ iT2[(byte)(a5 >> 8)] ^ iT3[(byte)a4] ^ ekey[56];
+                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a6 >> 8)] ^ iT3[(byte)a5] ^ ekey[57];
+                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a7 >> 8)] ^ iT3[(byte)a6] ^ ekey[58];
+                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a7] ^ ekey[59];
+                       b4 = iT0[a4 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[60];
+                       b5 = iT0[a5 >> 24] ^ iT1[(byte)(a4 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[61];
+                       b6 = iT0[a6 >> 24] ^ iT1[(byte)(a5 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[62];
+                       b7 = iT0[a7 >> 24] ^ iT1[(byte)(a6 >> 16)] ^ iT2[(byte)(a4 >> 8)] ^ iT3[(byte)a3] ^ ekey[63];
+
+                       /* Round 8 */
+                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b7 >> 16)] ^ iT2[(byte)(b5 >> 8)] ^ iT3[(byte)b4] ^ ekey[64];
+                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b6 >> 8)] ^ iT3[(byte)b5] ^ ekey[65];
+                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b7 >> 8)] ^ iT3[(byte)b6] ^ ekey[66];
+                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b7] ^ ekey[67];
+                       a4 = iT0[b4 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[68];
+                       a5 = iT0[b5 >> 24] ^ iT1[(byte)(b4 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[69];
+                       a6 = iT0[b6 >> 24] ^ iT1[(byte)(b5 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[70];
+                       a7 = iT0[b7 >> 24] ^ iT1[(byte)(b6 >> 16)] ^ iT2[(byte)(b4 >> 8)] ^ iT3[(byte)b3] ^ ekey[71];
+
+                       /* Round 9 */
+                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a7 >> 16)] ^ iT2[(byte)(a5 >> 8)] ^ iT3[(byte)a4] ^ ekey[72];
+                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a6 >> 8)] ^ iT3[(byte)a5] ^ ekey[73];
+                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a7 >> 8)] ^ iT3[(byte)a6] ^ ekey[74];
+                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a7] ^ ekey[75];
+                       b4 = iT0[a4 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[76];
+                       b5 = iT0[a5 >> 24] ^ iT1[(byte)(a4 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[77];
+                       b6 = iT0[a6 >> 24] ^ iT1[(byte)(a5 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[78];
+                       b7 = iT0[a7 >> 24] ^ iT1[(byte)(a6 >> 16)] ^ iT2[(byte)(a4 >> 8)] ^ iT3[(byte)a3] ^ ekey[79];
+
+                       /* Round 10 */
+                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b7 >> 16)] ^ iT2[(byte)(b5 >> 8)] ^ iT3[(byte)b4] ^ ekey[80];
+                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b6 >> 8)] ^ iT3[(byte)b5] ^ ekey[81];
+                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b7 >> 8)] ^ iT3[(byte)b6] ^ ekey[82];
+                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b7] ^ ekey[83];
+                       a4 = iT0[b4 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[84];
+                       a5 = iT0[b5 >> 24] ^ iT1[(byte)(b4 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[85];
+                       a6 = iT0[b6 >> 24] ^ iT1[(byte)(b5 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[86];
+                       a7 = iT0[b7 >> 24] ^ iT1[(byte)(b6 >> 16)] ^ iT2[(byte)(b4 >> 8)] ^ iT3[(byte)b3] ^ ekey[87];
+
+                       /* Round 11 */
+                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a7 >> 16)] ^ iT2[(byte)(a5 >> 8)] ^ iT3[(byte)a4] ^ ekey[88];
+                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a6 >> 8)] ^ iT3[(byte)a5] ^ ekey[89];
+                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a7 >> 8)] ^ iT3[(byte)a6] ^ ekey[90];
+                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a7] ^ ekey[91];
+                       b4 = iT0[a4 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[92];
+                       b5 = iT0[a5 >> 24] ^ iT1[(byte)(a4 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[93];
+                       b6 = iT0[a6 >> 24] ^ iT1[(byte)(a5 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[94];
+                       b7 = iT0[a7 >> 24] ^ iT1[(byte)(a6 >> 16)] ^ iT2[(byte)(a4 >> 8)] ^ iT3[(byte)a3] ^ ekey[95];
+
+                       /* Round 12 */
+                       a0 = iT0[b0 >> 24] ^ iT1[(byte)(b7 >> 16)] ^ iT2[(byte)(b5 >> 8)] ^ iT3[(byte)b4] ^ ekey[96];
+                       a1 = iT0[b1 >> 24] ^ iT1[(byte)(b0 >> 16)] ^ iT2[(byte)(b6 >> 8)] ^ iT3[(byte)b5] ^ ekey[97];
+                       a2 = iT0[b2 >> 24] ^ iT1[(byte)(b1 >> 16)] ^ iT2[(byte)(b7 >> 8)] ^ iT3[(byte)b6] ^ ekey[98];
+                       a3 = iT0[b3 >> 24] ^ iT1[(byte)(b2 >> 16)] ^ iT2[(byte)(b0 >> 8)] ^ iT3[(byte)b7] ^ ekey[99];
+                       a4 = iT0[b4 >> 24] ^ iT1[(byte)(b3 >> 16)] ^ iT2[(byte)(b1 >> 8)] ^ iT3[(byte)b0] ^ ekey[100];
+                       a5 = iT0[b5 >> 24] ^ iT1[(byte)(b4 >> 16)] ^ iT2[(byte)(b2 >> 8)] ^ iT3[(byte)b1] ^ ekey[101];
+                       a6 = iT0[b6 >> 24] ^ iT1[(byte)(b5 >> 16)] ^ iT2[(byte)(b3 >> 8)] ^ iT3[(byte)b2] ^ ekey[102];
+                       a7 = iT0[b7 >> 24] ^ iT1[(byte)(b6 >> 16)] ^ iT2[(byte)(b4 >> 8)] ^ iT3[(byte)b3] ^ ekey[103];
+
+                       /* Round 13 */
+                       b0 = iT0[a0 >> 24] ^ iT1[(byte)(a7 >> 16)] ^ iT2[(byte)(a5 >> 8)] ^ iT3[(byte)a4] ^ ekey[104];
+                       b1 = iT0[a1 >> 24] ^ iT1[(byte)(a0 >> 16)] ^ iT2[(byte)(a6 >> 8)] ^ iT3[(byte)a5] ^ ekey[105];
+                       b2 = iT0[a2 >> 24] ^ iT1[(byte)(a1 >> 16)] ^ iT2[(byte)(a7 >> 8)] ^ iT3[(byte)a6] ^ ekey[106];
+                       b3 = iT0[a3 >> 24] ^ iT1[(byte)(a2 >> 16)] ^ iT2[(byte)(a0 >> 8)] ^ iT3[(byte)a7] ^ ekey[107];
+                       b4 = iT0[a4 >> 24] ^ iT1[(byte)(a3 >> 16)] ^ iT2[(byte)(a1 >> 8)] ^ iT3[(byte)a0] ^ ekey[108];
+                       b5 = iT0[a5 >> 24] ^ iT1[(byte)(a4 >> 16)] ^ iT2[(byte)(a2 >> 8)] ^ iT3[(byte)a1] ^ ekey[109];
+                       b6 = iT0[a6 >> 24] ^ iT1[(byte)(a5 >> 16)] ^ iT2[(byte)(a3 >> 8)] ^ iT3[(byte)a2] ^ ekey[110];
+                       b7 = iT0[a7 >> 24] ^ iT1[(byte)(a6 >> 16)] ^ iT2[(byte)(a4 >> 8)] ^ iT3[(byte)a3] ^ ekey[111];
+
+                       /* Final Round */
+                       outdata[0] = (byte)(iSBox[b0 >> 24] ^ (byte)(ekey[112] >> 24));
+                       outdata[1] = (byte)(iSBox[(byte)(b7 >> 16)] ^ (byte)(ekey[112] >> 16));
+                       outdata[2] = (byte)(iSBox[(byte)(b5 >> 8)] ^ (byte)(ekey[112] >> 8));
+                       outdata[3] = (byte)(iSBox[(byte)b4] ^ (byte)ekey[112]);
+
+                       outdata[4] = (byte)(iSBox[b1 >> 24] ^ (byte)(ekey[113] >> 24));
+                       outdata[5] = (byte)(iSBox[(byte)(b0 >> 16)] ^ (byte)(ekey[113] >> 16));
+                       outdata[6] = (byte)(iSBox[(byte)(b6 >> 8)] ^ (byte)(ekey[113] >> 8));
+                       outdata[7] = (byte)(iSBox[(byte)b5] ^ (byte)ekey[113]);
+
+                       outdata[8] = (byte)(iSBox[b2 >> 24] ^ (byte)(ekey[114] >> 24));
+                       outdata[9] = (byte)(iSBox[(byte)(b1 >> 16)] ^ (byte)(ekey[114] >> 16));
+                       outdata[10] = (byte)(iSBox[(byte)(b7 >> 8)] ^ (byte)(ekey[114] >> 8));
+                       outdata[11] = (byte)(iSBox[(byte)b6] ^ (byte)ekey[114]);
+
+                       outdata[12] = (byte)(iSBox[b3 >> 24] ^ (byte)(ekey[115] >> 24));
+                       outdata[13] = (byte)(iSBox[(byte)(b2 >> 16)] ^ (byte)(ekey[115] >> 16));
+                       outdata[14] = (byte)(iSBox[(byte)(b0 >> 8)] ^ (byte)(ekey[115] >> 8));
+                       outdata[15] = (byte)(iSBox[(byte)b7] ^ (byte)ekey[115]);
+
+                       outdata[16] = (byte)(iSBox[b4 >> 24] ^ (byte)(ekey[116] >> 24));
+                       outdata[17] = (byte)(iSBox[(byte)(b3 >> 16)] ^ (byte)(ekey[116] >> 16));
+                       outdata[18] = (byte)(iSBox[(byte)(b1 >> 8)] ^ (byte)(ekey[116] >> 8));
+                       outdata[19] = (byte)(iSBox[(byte)b0] ^ (byte)ekey[116]);
+
+                       outdata[20] = (byte)(iSBox[b5 >> 24] ^ (byte)(ekey[117] >> 24));
+                       outdata[21] = (byte)(iSBox[(byte)(b4 >> 16)] ^ (byte)(ekey[117] >> 16));
+                       outdata[22] = (byte)(iSBox[(byte)(b2 >> 8)] ^ (byte)(ekey[117] >> 8));
+                       outdata[23] = (byte)(iSBox[(byte)b1] ^ (byte)ekey[117]);
+
+                       outdata[24] = (byte)(iSBox[b6 >> 24] ^ (byte)(ekey[118] >> 24));
+                       outdata[25] = (byte)(iSBox[(byte)(b5 >> 16)] ^ (byte)(ekey[118] >> 16));
+                       outdata[26] = (byte)(iSBox[(byte)(b3 >> 8)] ^ (byte)(ekey[118] >> 8));
+                       outdata[27] = (byte)(iSBox[(byte)b2] ^ (byte)ekey[118]);
+
+                       outdata[28] = (byte)(iSBox[b7 >> 24] ^ (byte)(ekey[119] >> 24));
+                       outdata[29] = (byte)(iSBox[(byte)(b6 >> 16)] ^ (byte)(ekey[119] >> 16));
+                       outdata[30] = (byte)(iSBox[(byte)(b4 >> 8)] ^ (byte)(ekey[119] >> 8));
+                       outdata[31] = (byte)(iSBox[(byte)b3] ^ (byte)ekey[119]);
+               }
+               #endregion
+
+               #region Constant Table
+               static readonly uint[] Rcon = new uint[] {
+                       0x00000000, 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000,
+                       0x80000000, 0x1b000000, 0x36000000, 0x6c000000, 0xd8000000, 0xab000000, 0x4d000000, 0x9a000000,
+                       0x2f000000, 0x5e000000, 0xbc000000, 0x63000000, 0xc6000000, 0x97000000, 0x35000000, 0x6a000000,
+                       0xd4000000, 0xb3000000, 0x7d000000, 0xfa000000, 0xef000000, 0xc5000000
+               };
+
+               static readonly byte[] SBox = new byte[] {
+                       0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+                       0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+                       0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+                       0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+                       0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+                       0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+                       0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+                       0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+                       0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+                       0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+                       0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+                       0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+                       0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+                       0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+                       0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+                       0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+               };
+
+               static readonly byte[] iSBox = {
+                       0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
+                       0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
+                       0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
+                       0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
+                       0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
+                       0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
+                       0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
+                       0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
+                       0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
+                       0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
+                       0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
+                       0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
+                       0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
+                       0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
+                       0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
+                       0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d,
+               };
+
+               static readonly uint[] T0 = {
+                       0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
+                       0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d, 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
+                       0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87, 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
+                       0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
+                       0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a, 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
+                       0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108, 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
+                       0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
+                       0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d, 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
+                       0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e, 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
+                       0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
+                       0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c, 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
+                       0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b, 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
+                       0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
+                       0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81, 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
+                       0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a, 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
+                       0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
+                       0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f, 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
+                       0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47, 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
+                       0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
+                       0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c, 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
+                       0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e, 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
+                       0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
+                       0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7, 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
+                       0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25, 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
+                       0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
+                       0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21, 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
+                       0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa, 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
+                       0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
+                       0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133, 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
+                       0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920, 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
+                       0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17, 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
+                       0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11, 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a,
+               };
+
+               static readonly uint[] T1 = {
+                       0xa5c66363, 0x84f87c7c, 0x99ee7777, 0x8df67b7b, 0x0dfff2f2, 0xbdd66b6b, 0xb1de6f6f, 0x5491c5c5,
+                       0x50603030, 0x03020101, 0xa9ce6767, 0x7d562b2b, 0x19e7fefe, 0x62b5d7d7, 0xe64dabab, 0x9aec7676,
+                       0x458fcaca, 0x9d1f8282, 0x4089c9c9, 0x87fa7d7d, 0x15effafa, 0xebb25959, 0xc98e4747, 0x0bfbf0f0,
+                       0xec41adad, 0x67b3d4d4, 0xfd5fa2a2, 0xea45afaf, 0xbf239c9c, 0xf753a4a4, 0x96e47272, 0x5b9bc0c0,
+                       0xc275b7b7, 0x1ce1fdfd, 0xae3d9393, 0x6a4c2626, 0x5a6c3636, 0x417e3f3f, 0x02f5f7f7, 0x4f83cccc,
+                       0x5c683434, 0xf451a5a5, 0x34d1e5e5, 0x08f9f1f1, 0x93e27171, 0x73abd8d8, 0x53623131, 0x3f2a1515,
+                       0x0c080404, 0x5295c7c7, 0x65462323, 0x5e9dc3c3, 0x28301818, 0xa1379696, 0x0f0a0505, 0xb52f9a9a,
+                       0x090e0707, 0x36241212, 0x9b1b8080, 0x3ddfe2e2, 0x26cdebeb, 0x694e2727, 0xcd7fb2b2, 0x9fea7575,
+                       0x1b120909, 0x9e1d8383, 0x74582c2c, 0x2e341a1a, 0x2d361b1b, 0xb2dc6e6e, 0xeeb45a5a, 0xfb5ba0a0,
+                       0xf6a45252, 0x4d763b3b, 0x61b7d6d6, 0xce7db3b3, 0x7b522929, 0x3edde3e3, 0x715e2f2f, 0x97138484,
+                       0xf5a65353, 0x68b9d1d1, 0x00000000, 0x2cc1eded, 0x60402020, 0x1fe3fcfc, 0xc879b1b1, 0xedb65b5b,
+                       0xbed46a6a, 0x468dcbcb, 0xd967bebe, 0x4b723939, 0xde944a4a, 0xd4984c4c, 0xe8b05858, 0x4a85cfcf,
+                       0x6bbbd0d0, 0x2ac5efef, 0xe54faaaa, 0x16edfbfb, 0xc5864343, 0xd79a4d4d, 0x55663333, 0x94118585,
+                       0xcf8a4545, 0x10e9f9f9, 0x06040202, 0x81fe7f7f, 0xf0a05050, 0x44783c3c, 0xba259f9f, 0xe34ba8a8,
+                       0xf3a25151, 0xfe5da3a3, 0xc0804040, 0x8a058f8f, 0xad3f9292, 0xbc219d9d, 0x48703838, 0x04f1f5f5,
+                       0xdf63bcbc, 0xc177b6b6, 0x75afdada, 0x63422121, 0x30201010, 0x1ae5ffff, 0x0efdf3f3, 0x6dbfd2d2,
+                       0x4c81cdcd, 0x14180c0c, 0x35261313, 0x2fc3ecec, 0xe1be5f5f, 0xa2359797, 0xcc884444, 0x392e1717,
+                       0x5793c4c4, 0xf255a7a7, 0x82fc7e7e, 0x477a3d3d, 0xacc86464, 0xe7ba5d5d, 0x2b321919, 0x95e67373,
+                       0xa0c06060, 0x98198181, 0xd19e4f4f, 0x7fa3dcdc, 0x66442222, 0x7e542a2a, 0xab3b9090, 0x830b8888,
+                       0xca8c4646, 0x29c7eeee, 0xd36bb8b8, 0x3c281414, 0x79a7dede, 0xe2bc5e5e, 0x1d160b0b, 0x76addbdb,
+                       0x3bdbe0e0, 0x56643232, 0x4e743a3a, 0x1e140a0a, 0xdb924949, 0x0a0c0606, 0x6c482424, 0xe4b85c5c,
+                       0x5d9fc2c2, 0x6ebdd3d3, 0xef43acac, 0xa6c46262, 0xa8399191, 0xa4319595, 0x37d3e4e4, 0x8bf27979,
+                       0x32d5e7e7, 0x438bc8c8, 0x596e3737, 0xb7da6d6d, 0x8c018d8d, 0x64b1d5d5, 0xd29c4e4e, 0xe049a9a9,
+                       0xb4d86c6c, 0xfaac5656, 0x07f3f4f4, 0x25cfeaea, 0xafca6565, 0x8ef47a7a, 0xe947aeae, 0x18100808,
+                       0xd56fbaba, 0x88f07878, 0x6f4a2525, 0x725c2e2e, 0x24381c1c, 0xf157a6a6, 0xc773b4b4, 0x5197c6c6,
+                       0x23cbe8e8, 0x7ca1dddd, 0x9ce87474, 0x213e1f1f, 0xdd964b4b, 0xdc61bdbd, 0x860d8b8b, 0x850f8a8a,
+                       0x90e07070, 0x427c3e3e, 0xc471b5b5, 0xaacc6666, 0xd8904848, 0x05060303, 0x01f7f6f6, 0x121c0e0e,
+                       0xa3c26161, 0x5f6a3535, 0xf9ae5757, 0xd069b9b9, 0x91178686, 0x5899c1c1, 0x273a1d1d, 0xb9279e9e,
+                       0x38d9e1e1, 0x13ebf8f8, 0xb32b9898, 0x33221111, 0xbbd26969, 0x70a9d9d9, 0x89078e8e, 0xa7339494,
+                       0xb62d9b9b, 0x223c1e1e, 0x92158787, 0x20c9e9e9, 0x4987cece, 0xffaa5555, 0x78502828, 0x7aa5dfdf,
+                       0x8f038c8c, 0xf859a1a1, 0x80098989, 0x171a0d0d, 0xda65bfbf, 0x31d7e6e6, 0xc6844242, 0xb8d06868,
+                       0xc3824141, 0xb0299999, 0x775a2d2d, 0x111e0f0f, 0xcb7bb0b0, 0xfca85454, 0xd66dbbbb, 0x3a2c1616,
+               };
+
+               static readonly uint[] T2 = {
+                       0x63a5c663, 0x7c84f87c, 0x7799ee77, 0x7b8df67b, 0xf20dfff2, 0x6bbdd66b, 0x6fb1de6f, 0xc55491c5,
+                       0x30506030, 0x01030201, 0x67a9ce67, 0x2b7d562b, 0xfe19e7fe, 0xd762b5d7, 0xabe64dab, 0x769aec76,
+                       0xca458fca, 0x829d1f82, 0xc94089c9, 0x7d87fa7d, 0xfa15effa, 0x59ebb259, 0x47c98e47, 0xf00bfbf0,
+                       0xadec41ad, 0xd467b3d4, 0xa2fd5fa2, 0xafea45af, 0x9cbf239c, 0xa4f753a4, 0x7296e472, 0xc05b9bc0,
+                       0xb7c275b7, 0xfd1ce1fd, 0x93ae3d93, 0x266a4c26, 0x365a6c36, 0x3f417e3f, 0xf702f5f7, 0xcc4f83cc,
+                       0x345c6834, 0xa5f451a5, 0xe534d1e5, 0xf108f9f1, 0x7193e271, 0xd873abd8, 0x31536231, 0x153f2a15,
+                       0x040c0804, 0xc75295c7, 0x23654623, 0xc35e9dc3, 0x18283018, 0x96a13796, 0x050f0a05, 0x9ab52f9a,
+                       0x07090e07, 0x12362412, 0x809b1b80, 0xe23ddfe2, 0xeb26cdeb, 0x27694e27, 0xb2cd7fb2, 0x759fea75,
+                       0x091b1209, 0x839e1d83, 0x2c74582c, 0x1a2e341a, 0x1b2d361b, 0x6eb2dc6e, 0x5aeeb45a, 0xa0fb5ba0,
+                       0x52f6a452, 0x3b4d763b, 0xd661b7d6, 0xb3ce7db3, 0x297b5229, 0xe33edde3, 0x2f715e2f, 0x84971384,
+                       0x53f5a653, 0xd168b9d1, 0x00000000, 0xed2cc1ed, 0x20604020, 0xfc1fe3fc, 0xb1c879b1, 0x5bedb65b,
+                       0x6abed46a, 0xcb468dcb, 0xbed967be, 0x394b7239, 0x4ade944a, 0x4cd4984c, 0x58e8b058, 0xcf4a85cf,
+                       0xd06bbbd0, 0xef2ac5ef, 0xaae54faa, 0xfb16edfb, 0x43c58643, 0x4dd79a4d, 0x33556633, 0x85941185,
+                       0x45cf8a45, 0xf910e9f9, 0x02060402, 0x7f81fe7f, 0x50f0a050, 0x3c44783c, 0x9fba259f, 0xa8e34ba8,
+                       0x51f3a251, 0xa3fe5da3, 0x40c08040, 0x8f8a058f, 0x92ad3f92, 0x9dbc219d, 0x38487038, 0xf504f1f5,
+                       0xbcdf63bc, 0xb6c177b6, 0xda75afda, 0x21634221, 0x10302010, 0xff1ae5ff, 0xf30efdf3, 0xd26dbfd2,
+                       0xcd4c81cd, 0x0c14180c, 0x13352613, 0xec2fc3ec, 0x5fe1be5f, 0x97a23597, 0x44cc8844, 0x17392e17,
+                       0xc45793c4, 0xa7f255a7, 0x7e82fc7e, 0x3d477a3d, 0x64acc864, 0x5de7ba5d, 0x192b3219, 0x7395e673,
+                       0x60a0c060, 0x81981981, 0x4fd19e4f, 0xdc7fa3dc, 0x22664422, 0x2a7e542a, 0x90ab3b90, 0x88830b88,
+                       0x46ca8c46, 0xee29c7ee, 0xb8d36bb8, 0x143c2814, 0xde79a7de, 0x5ee2bc5e, 0x0b1d160b, 0xdb76addb,
+                       0xe03bdbe0, 0x32566432, 0x3a4e743a, 0x0a1e140a, 0x49db9249, 0x060a0c06, 0x246c4824, 0x5ce4b85c,
+                       0xc25d9fc2, 0xd36ebdd3, 0xacef43ac, 0x62a6c462, 0x91a83991, 0x95a43195, 0xe437d3e4, 0x798bf279,
+                       0xe732d5e7, 0xc8438bc8, 0x37596e37, 0x6db7da6d, 0x8d8c018d, 0xd564b1d5, 0x4ed29c4e, 0xa9e049a9,
+                       0x6cb4d86c, 0x56faac56, 0xf407f3f4, 0xea25cfea, 0x65afca65, 0x7a8ef47a, 0xaee947ae, 0x08181008,
+                       0xbad56fba, 0x7888f078, 0x256f4a25, 0x2e725c2e, 0x1c24381c, 0xa6f157a6, 0xb4c773b4, 0xc65197c6,
+                       0xe823cbe8, 0xdd7ca1dd, 0x749ce874, 0x1f213e1f, 0x4bdd964b, 0xbddc61bd, 0x8b860d8b, 0x8a850f8a,
+                       0x7090e070, 0x3e427c3e, 0xb5c471b5, 0x66aacc66, 0x48d89048, 0x03050603, 0xf601f7f6, 0x0e121c0e,
+                       0x61a3c261, 0x355f6a35, 0x57f9ae57, 0xb9d069b9, 0x86911786, 0xc15899c1, 0x1d273a1d, 0x9eb9279e,
+                       0xe138d9e1, 0xf813ebf8, 0x98b32b98, 0x11332211, 0x69bbd269, 0xd970a9d9, 0x8e89078e, 0x94a73394,
+                       0x9bb62d9b, 0x1e223c1e, 0x87921587, 0xe920c9e9, 0xce4987ce, 0x55ffaa55, 0x28785028, 0xdf7aa5df,
+                       0x8c8f038c, 0xa1f859a1, 0x89800989, 0x0d171a0d, 0xbfda65bf, 0xe631d7e6, 0x42c68442, 0x68b8d068,
+                       0x41c38241, 0x99b02999, 0x2d775a2d, 0x0f111e0f, 0xb0cb7bb0, 0x54fca854, 0xbbd66dbb, 0x163a2c16,
+               };
+
+               static readonly uint[] T3 = {
+                       0x6363a5c6, 0x7c7c84f8, 0x777799ee, 0x7b7b8df6, 0xf2f20dff, 0x6b6bbdd6, 0x6f6fb1de, 0xc5c55491,
+                       0x30305060, 0x01010302, 0x6767a9ce, 0x2b2b7d56, 0xfefe19e7, 0xd7d762b5, 0xababe64d, 0x76769aec,
+                       0xcaca458f, 0x82829d1f, 0xc9c94089, 0x7d7d87fa, 0xfafa15ef, 0x5959ebb2, 0x4747c98e, 0xf0f00bfb,
+                       0xadadec41, 0xd4d467b3, 0xa2a2fd5f, 0xafafea45, 0x9c9cbf23, 0xa4a4f753, 0x727296e4, 0xc0c05b9b,
+                       0xb7b7c275, 0xfdfd1ce1, 0x9393ae3d, 0x26266a4c, 0x36365a6c, 0x3f3f417e, 0xf7f702f5, 0xcccc4f83,
+                       0x34345c68, 0xa5a5f451, 0xe5e534d1, 0xf1f108f9, 0x717193e2, 0xd8d873ab, 0x31315362, 0x15153f2a,
+                       0x04040c08, 0xc7c75295, 0x23236546, 0xc3c35e9d, 0x18182830, 0x9696a137, 0x05050f0a, 0x9a9ab52f,
+                       0x0707090e, 0x12123624, 0x80809b1b, 0xe2e23ddf, 0xebeb26cd, 0x2727694e, 0xb2b2cd7f, 0x75759fea,
+                       0x09091b12, 0x83839e1d, 0x2c2c7458, 0x1a1a2e34, 0x1b1b2d36, 0x6e6eb2dc, 0x5a5aeeb4, 0xa0a0fb5b,
+                       0x5252f6a4, 0x3b3b4d76, 0xd6d661b7, 0xb3b3ce7d, 0x29297b52, 0xe3e33edd, 0x2f2f715e, 0x84849713,
+                       0x5353f5a6, 0xd1d168b9, 0x00000000, 0xeded2cc1, 0x20206040, 0xfcfc1fe3, 0xb1b1c879, 0x5b5bedb6,
+                       0x6a6abed4, 0xcbcb468d, 0xbebed967, 0x39394b72, 0x4a4ade94, 0x4c4cd498, 0x5858e8b0, 0xcfcf4a85,
+                       0xd0d06bbb, 0xefef2ac5, 0xaaaae54f, 0xfbfb16ed, 0x4343c586, 0x4d4dd79a, 0x33335566, 0x85859411,
+                       0x4545cf8a, 0xf9f910e9, 0x02020604, 0x7f7f81fe, 0x5050f0a0, 0x3c3c4478, 0x9f9fba25, 0xa8a8e34b,
+                       0x5151f3a2, 0xa3a3fe5d, 0x4040c080, 0x8f8f8a05, 0x9292ad3f, 0x9d9dbc21, 0x38384870, 0xf5f504f1,
+                       0xbcbcdf63, 0xb6b6c177, 0xdada75af, 0x21216342, 0x10103020, 0xffff1ae5, 0xf3f30efd, 0xd2d26dbf,
+                       0xcdcd4c81, 0x0c0c1418, 0x13133526, 0xecec2fc3, 0x5f5fe1be, 0x9797a235, 0x4444cc88, 0x1717392e,
+                       0xc4c45793, 0xa7a7f255, 0x7e7e82fc, 0x3d3d477a, 0x6464acc8, 0x5d5de7ba, 0x19192b32, 0x737395e6,
+                       0x6060a0c0, 0x81819819, 0x4f4fd19e, 0xdcdc7fa3, 0x22226644, 0x2a2a7e54, 0x9090ab3b, 0x8888830b,
+                       0x4646ca8c, 0xeeee29c7, 0xb8b8d36b, 0x14143c28, 0xdede79a7, 0x5e5ee2bc, 0x0b0b1d16, 0xdbdb76ad,
+                       0xe0e03bdb, 0x32325664, 0x3a3a4e74, 0x0a0a1e14, 0x4949db92, 0x06060a0c, 0x24246c48, 0x5c5ce4b8,
+                       0xc2c25d9f, 0xd3d36ebd, 0xacacef43, 0x6262a6c4, 0x9191a839, 0x9595a431, 0xe4e437d3, 0x79798bf2,
+                       0xe7e732d5, 0xc8c8438b, 0x3737596e, 0x6d6db7da, 0x8d8d8c01, 0xd5d564b1, 0x4e4ed29c, 0xa9a9e049,
+                       0x6c6cb4d8, 0x5656faac, 0xf4f407f3, 0xeaea25cf, 0x6565afca, 0x7a7a8ef4, 0xaeaee947, 0x08081810,
+                       0xbabad56f, 0x787888f0, 0x25256f4a, 0x2e2e725c, 0x1c1c2438, 0xa6a6f157, 0xb4b4c773, 0xc6c65197,
+                       0xe8e823cb, 0xdddd7ca1, 0x74749ce8, 0x1f1f213e, 0x4b4bdd96, 0xbdbddc61, 0x8b8b860d, 0x8a8a850f,
+                       0x707090e0, 0x3e3e427c, 0xb5b5c471, 0x6666aacc, 0x4848d890, 0x03030506, 0xf6f601f7, 0x0e0e121c,
+                       0x6161a3c2, 0x35355f6a, 0x5757f9ae, 0xb9b9d069, 0x86869117, 0xc1c15899, 0x1d1d273a, 0x9e9eb927,
+                       0xe1e138d9, 0xf8f813eb, 0x9898b32b, 0x11113322, 0x6969bbd2, 0xd9d970a9, 0x8e8e8907, 0x9494a733,
+                       0x9b9bb62d, 0x1e1e223c, 0x87879215, 0xe9e920c9, 0xcece4987, 0x5555ffaa, 0x28287850, 0xdfdf7aa5,
+                       0x8c8c8f03, 0xa1a1f859, 0x89898009, 0x0d0d171a, 0xbfbfda65, 0xe6e631d7, 0x4242c684, 0x6868b8d0,
+                       0x4141c382, 0x9999b029, 0x2d2d775a, 0x0f0f111e, 0xb0b0cb7b, 0x5454fca8, 0xbbbbd66d, 0x16163a2c,
+               };
+
+               static readonly uint[] iT0 = {
+                       0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96, 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
+                       0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25, 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
+                       0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1, 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
+                       0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da, 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
+                       0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd, 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
+                       0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45, 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
+                       0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7, 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
+                       0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5, 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
+                       0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1, 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
+                       0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75, 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
+                       0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46, 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
+                       0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77, 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
+                       0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000, 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
+                       0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927, 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
+                       0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e, 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
+                       0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d, 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
+                       0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd, 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
+                       0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163, 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
+                       0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d, 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
+                       0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422, 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
+                       0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36, 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
+                       0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662, 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
+                       0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3, 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
+                       0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8, 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
+                       0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6, 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
+                       0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815, 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
+                       0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df, 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
+                       0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e, 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
+                       0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89, 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
+                       0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf, 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
+                       0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f, 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
+                       0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190, 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742,
+               };
+
+               static readonly uint[] iT1 = {
+                       0x5051f4a7, 0x537e4165, 0xc31a17a4, 0x963a275e, 0xcb3bab6b, 0xf11f9d45, 0xabacfa58, 0x934be303,
+                       0x552030fa, 0xf6ad766d, 0x9188cc76, 0x25f5024c, 0xfc4fe5d7, 0xd7c52acb, 0x80263544, 0x8fb562a3,
+                       0x49deb15a, 0x6725ba1b, 0x9845ea0e, 0xe15dfec0, 0x02c32f75, 0x12814cf0, 0xa38d4697, 0xc66bd3f9,
+                       0xe7038f5f, 0x9515929c, 0xebbf6d7a, 0xda955259, 0x2dd4be83, 0xd3587421, 0x2949e069, 0x448ec9c8,
+                       0x6a75c289, 0x78f48e79, 0x6b99583e, 0xdd27b971, 0xb6bee14f, 0x17f088ad, 0x66c920ac, 0xb47dce3a,
+                       0x1863df4a, 0x82e51a31, 0x60975133, 0x4562537f, 0xe0b16477, 0x84bb6bae, 0x1cfe81a0, 0x94f9082b,
+                       0x58704868, 0x198f45fd, 0x8794de6c, 0xb7527bf8, 0x23ab73d3, 0xe2724b02, 0x57e31f8f, 0x2a6655ab,
+                       0x07b2eb28, 0x032fb5c2, 0x9a86c57b, 0xa5d33708, 0xf2302887, 0xb223bfa5, 0xba02036a, 0x5ced1682,
+                       0x2b8acf1c, 0x92a779b4, 0xf0f307f2, 0xa14e69e2, 0xcd65daf4, 0xd50605be, 0x1fd13462, 0x8ac4a6fe,
+                       0x9d342e53, 0xa0a2f355, 0x32058ae1, 0x75a4f6eb, 0x390b83ec, 0xaa4060ef, 0x065e719f, 0x51bd6e10,
+                       0xf93e218a, 0x3d96dd06, 0xaedd3e05, 0x464de6bd, 0xb591548d, 0x0571c45d, 0x6f0406d4, 0xff605015,
+                       0x241998fb, 0x97d6bde9, 0xcc894043, 0x7767d99e, 0xbdb0e842, 0x8807898b, 0x38e7195b, 0xdb79c8ee,
+                       0x47a17c0a, 0xe97c420f, 0xc9f8841e, 0x00000000, 0x83098086, 0x48322bed, 0xac1e1170, 0x4e6c5a72,
+                       0xfbfd0eff, 0x560f8538, 0x1e3daed5, 0x27362d39, 0x640a0fd9, 0x21685ca6, 0xd19b5b54, 0x3a24362e,
+                       0xb10c0a67, 0x0f9357e7, 0xd2b4ee96, 0x9e1b9b91, 0x4f80c0c5, 0xa261dc20, 0x695a774b, 0x161c121a,
+                       0x0ae293ba, 0xe5c0a02a, 0x433c22e0, 0x1d121b17, 0x0b0e090d, 0xadf28bc7, 0xb92db6a8, 0xc8141ea9,
+                       0x8557f119, 0x4caf7507, 0xbbee99dd, 0xfda37f60, 0x9ff70126, 0xbc5c72f5, 0xc544663b, 0x345bfb7e,
+                       0x768b4329, 0xdccb23c6, 0x68b6edfc, 0x63b8e4f1, 0xcad731dc, 0x10426385, 0x40139722, 0x2084c611,
+                       0x7d854a24, 0xf8d2bb3d, 0x11aef932, 0x6dc729a1, 0x4b1d9e2f, 0xf3dcb230, 0xec0d8652, 0xd077c1e3,
+                       0x6c2bb316, 0x99a970b9, 0xfa119448, 0x2247e964, 0xc4a8fc8c, 0x1aa0f03f, 0xd8567d2c, 0xef223390,
+                       0xc787494e, 0xc1d938d1, 0xfe8ccaa2, 0x3698d40b, 0xcfa6f581, 0x28a57ade, 0x26dab78e, 0xa43fadbf,
+                       0xe42c3a9d, 0x0d507892, 0x9b6a5fcc, 0x62547e46, 0xc2f68d13, 0xe890d8b8, 0x5e2e39f7, 0xf582c3af,
+                       0xbe9f5d80, 0x7c69d093, 0xa96fd52d, 0xb3cf2512, 0x3bc8ac99, 0xa710187d, 0x6ee89c63, 0x7bdb3bbb,
+                       0x09cd2678, 0xf46e5918, 0x01ec9ab7, 0xa8834f9a, 0x65e6956e, 0x7eaaffe6, 0x0821bccf, 0xe6ef15e8,
+                       0xd9bae79b, 0xce4a6f36, 0xd4ea9f09, 0xd629b07c, 0xaf31a4b2, 0x312a3f23, 0x30c6a594, 0xc035a266,
+                       0x37744ebc, 0xa6fc82ca, 0xb0e090d0, 0x1533a7d8, 0x4af10498, 0xf741ecda, 0x0e7fcd50, 0x2f1791f6,
+                       0x8d764dd6, 0x4d43efb0, 0x54ccaa4d, 0xdfe49604, 0xe39ed1b5, 0x1b4c6a88, 0xb8c12c1f, 0x7f466551,
+                       0x049d5eea, 0x5d018c35, 0x73fa8774, 0x2efb0b41, 0x5ab3671d, 0x5292dbd2, 0x33e91056, 0x136dd647,
+                       0x8c9ad761, 0x7a37a10c, 0x8e59f814, 0x89eb133c, 0xeecea927, 0x35b761c9, 0xede11ce5, 0x3c7a47b1,
+                       0x599cd2df, 0x3f55f273, 0x791814ce, 0xbf73c737, 0xea53f7cd, 0x5b5ffdaa, 0x14df3d6f, 0x867844db,
+                       0x81caaff3, 0x3eb968c4, 0x2c382434, 0x5fc2a340, 0x72161dc3, 0x0cbce225, 0x8b283c49, 0x41ff0d95,
+                       0x7139a801, 0xde080cb3, 0x9cd8b4e4, 0x906456c1, 0x617bcb84, 0x70d532b6, 0x74486c5c, 0x42d0b857,
+               };
+
+               static readonly uint[] iT2 = {
+                       0xa75051f4, 0x65537e41, 0xa4c31a17, 0x5e963a27, 0x6bcb3bab, 0x45f11f9d, 0x58abacfa, 0x03934be3,
+                       0xfa552030, 0x6df6ad76, 0x769188cc, 0x4c25f502, 0xd7fc4fe5, 0xcbd7c52a, 0x44802635, 0xa38fb562,
+                       0x5a49deb1, 0x1b6725ba, 0x0e9845ea, 0xc0e15dfe, 0x7502c32f, 0xf012814c, 0x97a38d46, 0xf9c66bd3,
+                       0x5fe7038f, 0x9c951592, 0x7aebbf6d, 0x59da9552, 0x832dd4be, 0x21d35874, 0x692949e0, 0xc8448ec9,
+                       0x896a75c2, 0x7978f48e, 0x3e6b9958, 0x71dd27b9, 0x4fb6bee1, 0xad17f088, 0xac66c920, 0x3ab47dce,
+                       0x4a1863df, 0x3182e51a, 0x33609751, 0x7f456253, 0x77e0b164, 0xae84bb6b, 0xa01cfe81, 0x2b94f908,
+                       0x68587048, 0xfd198f45, 0x6c8794de, 0xf8b7527b, 0xd323ab73, 0x02e2724b, 0x8f57e31f, 0xab2a6655,
+                       0x2807b2eb, 0xc2032fb5, 0x7b9a86c5, 0x08a5d337, 0x87f23028, 0xa5b223bf, 0x6aba0203, 0x825ced16,
+                       0x1c2b8acf, 0xb492a779, 0xf2f0f307, 0xe2a14e69, 0xf4cd65da, 0xbed50605, 0x621fd134, 0xfe8ac4a6,
+                       0x539d342e, 0x55a0a2f3, 0xe132058a, 0xeb75a4f6, 0xec390b83, 0xefaa4060, 0x9f065e71, 0x1051bd6e,
+                       0x8af93e21, 0x063d96dd, 0x05aedd3e, 0xbd464de6, 0x8db59154, 0x5d0571c4, 0xd46f0406, 0x15ff6050,
+                       0xfb241998, 0xe997d6bd, 0x43cc8940, 0x9e7767d9, 0x42bdb0e8, 0x8b880789, 0x5b38e719, 0xeedb79c8,
+                       0x0a47a17c, 0x0fe97c42, 0x1ec9f884, 0x00000000, 0x86830980, 0xed48322b, 0x70ac1e11, 0x724e6c5a,
+                       0xfffbfd0e, 0x38560f85, 0xd51e3dae, 0x3927362d, 0xd9640a0f, 0xa621685c, 0x54d19b5b, 0x2e3a2436,
+                       0x67b10c0a, 0xe70f9357, 0x96d2b4ee, 0x919e1b9b, 0xc54f80c0, 0x20a261dc, 0x4b695a77, 0x1a161c12,
+                       0xba0ae293, 0x2ae5c0a0, 0xe0433c22, 0x171d121b, 0x0d0b0e09, 0xc7adf28b, 0xa8b92db6, 0xa9c8141e,
+                       0x198557f1, 0x074caf75, 0xddbbee99, 0x60fda37f, 0x269ff701, 0xf5bc5c72, 0x3bc54466, 0x7e345bfb,
+                       0x29768b43, 0xc6dccb23, 0xfc68b6ed, 0xf163b8e4, 0xdccad731, 0x85104263, 0x22401397, 0x112084c6,
+                       0x247d854a, 0x3df8d2bb, 0x3211aef9, 0xa16dc729, 0x2f4b1d9e, 0x30f3dcb2, 0x52ec0d86, 0xe3d077c1,
+                       0x166c2bb3, 0xb999a970, 0x48fa1194, 0x642247e9, 0x8cc4a8fc, 0x3f1aa0f0, 0x2cd8567d, 0x90ef2233,
+                       0x4ec78749, 0xd1c1d938, 0xa2fe8cca, 0x0b3698d4, 0x81cfa6f5, 0xde28a57a, 0x8e26dab7, 0xbfa43fad,
+                       0x9de42c3a, 0x920d5078, 0xcc9b6a5f, 0x4662547e, 0x13c2f68d, 0xb8e890d8, 0xf75e2e39, 0xaff582c3,
+                       0x80be9f5d, 0x937c69d0, 0x2da96fd5, 0x12b3cf25, 0x993bc8ac, 0x7da71018, 0x636ee89c, 0xbb7bdb3b,
+                       0x7809cd26, 0x18f46e59, 0xb701ec9a, 0x9aa8834f, 0x6e65e695, 0xe67eaaff, 0xcf0821bc, 0xe8e6ef15,
+                       0x9bd9bae7, 0x36ce4a6f, 0x09d4ea9f, 0x7cd629b0, 0xb2af31a4, 0x23312a3f, 0x9430c6a5, 0x66c035a2,
+                       0xbc37744e, 0xcaa6fc82, 0xd0b0e090, 0xd81533a7, 0x984af104, 0xdaf741ec, 0x500e7fcd, 0xf62f1791,
+                       0xd68d764d, 0xb04d43ef, 0x4d54ccaa, 0x04dfe496, 0xb5e39ed1, 0x881b4c6a, 0x1fb8c12c, 0x517f4665,
+                       0xea049d5e, 0x355d018c, 0x7473fa87, 0x412efb0b, 0x1d5ab367, 0xd25292db, 0x5633e910, 0x47136dd6,
+                       0x618c9ad7, 0x0c7a37a1, 0x148e59f8, 0x3c89eb13, 0x27eecea9, 0xc935b761, 0xe5ede11c, 0xb13c7a47,
+                       0xdf599cd2, 0x733f55f2, 0xce791814, 0x37bf73c7, 0xcdea53f7, 0xaa5b5ffd, 0x6f14df3d, 0xdb867844,
+                       0xf381caaf, 0xc43eb968, 0x342c3824, 0x405fc2a3, 0xc372161d, 0x250cbce2, 0x498b283c, 0x9541ff0d,
+                       0x017139a8, 0xb3de080c, 0xe49cd8b4, 0xc1906456, 0x84617bcb, 0xb670d532, 0x5c74486c, 0x5742d0b8,
+               };
+
+               static readonly uint[] iT3 = {
+                       0xf4a75051, 0x4165537e, 0x17a4c31a, 0x275e963a, 0xab6bcb3b, 0x9d45f11f, 0xfa58abac, 0xe303934b,
+                       0x30fa5520, 0x766df6ad, 0xcc769188, 0x024c25f5, 0xe5d7fc4f, 0x2acbd7c5, 0x35448026, 0x62a38fb5,
+                       0xb15a49de, 0xba1b6725, 0xea0e9845, 0xfec0e15d, 0x2f7502c3, 0x4cf01281, 0x4697a38d, 0xd3f9c66b,
+                       0x8f5fe703, 0x929c9515, 0x6d7aebbf, 0x5259da95, 0xbe832dd4, 0x7421d358, 0xe0692949, 0xc9c8448e,
+                       0xc2896a75, 0x8e7978f4, 0x583e6b99, 0xb971dd27, 0xe14fb6be, 0x88ad17f0, 0x20ac66c9, 0xce3ab47d,
+                       0xdf4a1863, 0x1a3182e5, 0x51336097, 0x537f4562, 0x6477e0b1, 0x6bae84bb, 0x81a01cfe, 0x082b94f9,
+                       0x48685870, 0x45fd198f, 0xde6c8794, 0x7bf8b752, 0x73d323ab, 0x4b02e272, 0x1f8f57e3, 0x55ab2a66,
+                       0xeb2807b2, 0xb5c2032f, 0xc57b9a86, 0x3708a5d3, 0x2887f230, 0xbfa5b223, 0x036aba02, 0x16825ced,
+                       0xcf1c2b8a, 0x79b492a7, 0x07f2f0f3, 0x69e2a14e, 0xdaf4cd65, 0x05bed506, 0x34621fd1, 0xa6fe8ac4,
+                       0x2e539d34, 0xf355a0a2, 0x8ae13205, 0xf6eb75a4, 0x83ec390b, 0x60efaa40, 0x719f065e, 0x6e1051bd,
+                       0x218af93e, 0xdd063d96, 0x3e05aedd, 0xe6bd464d, 0x548db591, 0xc45d0571, 0x06d46f04, 0x5015ff60,
+                       0x98fb2419, 0xbde997d6, 0x4043cc89, 0xd99e7767, 0xe842bdb0, 0x898b8807, 0x195b38e7, 0xc8eedb79,
+                       0x7c0a47a1, 0x420fe97c, 0x841ec9f8, 0x00000000, 0x80868309, 0x2bed4832, 0x1170ac1e, 0x5a724e6c,
+                       0x0efffbfd, 0x8538560f, 0xaed51e3d, 0x2d392736, 0x0fd9640a, 0x5ca62168, 0x5b54d19b, 0x362e3a24,
+                       0x0a67b10c, 0x57e70f93, 0xee96d2b4, 0x9b919e1b, 0xc0c54f80, 0xdc20a261, 0x774b695a, 0x121a161c,
+                       0x93ba0ae2, 0xa02ae5c0, 0x22e0433c, 0x1b171d12, 0x090d0b0e, 0x8bc7adf2, 0xb6a8b92d, 0x1ea9c814,
+                       0xf1198557, 0x75074caf, 0x99ddbbee, 0x7f60fda3, 0x01269ff7, 0x72f5bc5c, 0x663bc544, 0xfb7e345b,
+                       0x4329768b, 0x23c6dccb, 0xedfc68b6, 0xe4f163b8, 0x31dccad7, 0x63851042, 0x97224013, 0xc6112084,
+                       0x4a247d85, 0xbb3df8d2, 0xf93211ae, 0x29a16dc7, 0x9e2f4b1d, 0xb230f3dc, 0x8652ec0d, 0xc1e3d077,
+                       0xb3166c2b, 0x70b999a9, 0x9448fa11, 0xe9642247, 0xfc8cc4a8, 0xf03f1aa0, 0x7d2cd856, 0x3390ef22,
+                       0x494ec787, 0x38d1c1d9, 0xcaa2fe8c, 0xd40b3698, 0xf581cfa6, 0x7ade28a5, 0xb78e26da, 0xadbfa43f,
+                       0x3a9de42c, 0x78920d50, 0x5fcc9b6a, 0x7e466254, 0x8d13c2f6, 0xd8b8e890, 0x39f75e2e, 0xc3aff582,
+                       0x5d80be9f, 0xd0937c69, 0xd52da96f, 0x2512b3cf, 0xac993bc8, 0x187da710, 0x9c636ee8, 0x3bbb7bdb,
+                       0x267809cd, 0x5918f46e, 0x9ab701ec, 0x4f9aa883, 0x956e65e6, 0xffe67eaa, 0xbccf0821, 0x15e8e6ef,
+                       0xe79bd9ba, 0x6f36ce4a, 0x9f09d4ea, 0xb07cd629, 0xa4b2af31, 0x3f23312a, 0xa59430c6, 0xa266c035,
+                       0x4ebc3774, 0x82caa6fc, 0x90d0b0e0, 0xa7d81533, 0x04984af1, 0xecdaf741, 0xcd500e7f, 0x91f62f17,
+                       0x4dd68d76, 0xefb04d43, 0xaa4d54cc, 0x9604dfe4, 0xd1b5e39e, 0x6a881b4c, 0x2c1fb8c1, 0x65517f46,
+                       0x5eea049d, 0x8c355d01, 0x877473fa, 0x0b412efb, 0x671d5ab3, 0xdbd25292, 0x105633e9, 0xd647136d,
+                       0xd7618c9a, 0xa10c7a37, 0xf8148e59, 0x133c89eb, 0xa927eece, 0x61c935b7, 0x1ce5ede1, 0x47b13c7a,
+                       0xd2df599c, 0xf2733f55, 0x14ce7918, 0xc737bf73, 0xf7cdea53, 0xfdaa5b5f, 0x3d6f14df, 0x44db8678,
+                       0xaff381ca, 0x68c43eb9, 0x24342c38, 0xa3405fc2, 0x1dc37216, 0xe2250cbc, 0x3c498b28, 0x0d9541ff,
+                       0xa8017139, 0x0cb3de08, 0xb4e49cd8, 0x56c19064, 0xcb84617b, 0x32b670d5, 0x6c5c7448, 0xb85742d0,
+               };
+               #endregion
+       }
 }
 
 #endif
index 28abc25961c929d86d22823d3714baea859d8751..e58afc0b8cd1809ce597aea01592257f2f089f11 100644 (file)
@@ -39,6 +39,7 @@ namespace MonoTests.System.Collections.Generic
        [TestFixture]
        public class ComparerTest
        {
+#if NET_4_5
                [Test]
                public void Create ()
                {
@@ -55,6 +56,7 @@ namespace MonoTests.System.Collections.Generic
                        } catch (ArgumentNullException) {
                        }
                }
+#endif
 
 #if !NET_4_0 && !NET_2_1 // FIXME: the blob contains the 2.0 mscorlib version
 
index ce3c9a13c55424b47bdd153c5cb4e51b98f18c06..224e3058d40f278367ac8af0c60c6719508d4132 100644 (file)
@@ -1087,6 +1087,37 @@ namespace MonoTests.System.IO.IsolatedStorageTest {
                        isf.Close ();
                        isf.Dispose ();
                }
+
+               [Test]
+               public void MultiLevel ()
+               {
+                       // see bug #4101
+                       IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForAssembly ();
+                       try {
+                               isf.CreateDirectory ("dir1");
+                               string [] dirs = isf.GetDirectoryNames ("*");
+                               Assert.AreEqual (dirs.Length, 1, "1a");
+                               Assert.AreEqual (dirs [0], "dir1", "1b");
+       
+                               isf.CreateDirectory ("dir1/test");
+                               dirs = isf.GetDirectoryNames ("dir1/*");
+                               Assert.AreEqual (dirs.Length, 1, "2a");
+                               Assert.AreEqual (dirs [0], "test", "2b");
+       
+                               isf.CreateDirectory ("dir1/test/test2a");
+                               isf.CreateDirectory ("dir1/test/test2b");
+                               dirs = isf.GetDirectoryNames ("dir1/test/*");
+                               Assert.AreEqual (dirs.Length, 2, "3a");
+                               Assert.AreEqual (dirs [0], "test2a", "3b");
+                               Assert.AreEqual (dirs [1], "test2b", "3c");
+                       }
+                       finally {
+                               isf.DeleteDirectory ("dir1/test/test2a");
+                               isf.DeleteDirectory ("dir1/test/test2b");
+                               isf.DeleteDirectory ("dir1/test");
+                               isf.DeleteDirectory ("dir1");
+                       }
+               }
 #endif
        }
 }
index 580fac8e10750c2f4695a3949877b601f1337861..10328b8e60fa59ba34c76298cae2bbb000b0e58c 100644 (file)
@@ -331,7 +331,8 @@ namespace MonoTests.System.Security.Cryptography {
                                Assert.AreEqual (0, cs.Read (buffer, 0, 8), "Read from disposed");
                        }
                }
-
+               
+#if !NET_2_1
                [Test]
                // MS BUG [ExpectedException (typeof (ObjectDisposedException))]
 #if NET_2_0
@@ -353,6 +354,7 @@ namespace MonoTests.System.Security.Cryptography {
                                len = cs.Read (buffer, 3, 4);
                        }
                }
+#endif
 
                [Test]
                [ExpectedException (typeof (NotSupportedException))]
@@ -433,7 +435,8 @@ namespace MonoTests.System.Security.Cryptography {
                        cs = new CryptoStream (readStream, encryptor, CryptoStreamMode.Read);
                        cs.Read (buffer, Int32.MaxValue, 4);
                }
-
+               
+#if !NET_2_1
                [Test]
                // MS BUG [ExpectedException (typeof (ObjectDisposedException))]
 #if NET_2_0
@@ -453,7 +456,8 @@ namespace MonoTests.System.Security.Cryptography {
                                cs.Write (buffer, 0, 8);
                        }
                }
-
+#endif
+               
                [Test]
                [ExpectedException (typeof (NotSupportedException))]
                public void Write_ReadStream () 
index a15a9b83952d0c379aaa36d7b3c563cf1181d434..727b13cdaa00cd184e3574beee86c0eadd18bebf 100644 (file)
@@ -48,8 +48,7 @@ public class DSACryptoServiceProviderTest {
 
        private bool machineKeyStore;
 
-       [TestFixtureSetUp]
-       public void FixtureSetUp () 
+       public DSACryptoServiceProviderTest () 
        {
                disposed = new DSACryptoServiceProvider (minKeySize);
                // FX 2.0 beta 1 bug - we must use the key before clearing it
@@ -328,7 +327,8 @@ public class DSACryptoServiceProviderTest {
                // verify a signature based on a new just generated keypair
                Assert.IsFalse (emptyDSA.VerifySignature (hash, sign));
        }
-
+               
+#if !NET_2_1
        [Test]
        [Category ("NotWorking")]
        public void ImportDisposed ()
@@ -338,6 +338,7 @@ public class DSACryptoServiceProviderTest {
                import.ImportParameters (AllTests.GetKey (false));
                // no exception from Fx 2.0 +
        }
+#endif
 
        [Test]
        [ExpectedException (typeof (ObjectDisposedException))]
@@ -864,7 +865,8 @@ public class DSACryptoServiceProviderTest {
                catch (UnauthorizedAccessException) {
                }
        }
-
+               
+#if !NET_2_1
        [Test]
        [Category ("NotWorking")]
        public void CspKeyContainerInfo_NewKeypair ()
@@ -932,6 +934,7 @@ public class DSACryptoServiceProviderTest {
                Assert.IsFalse (info.Removable, "Removable");
                // info.UniqueKeyContainerName throws a CryptographicException at this stage
        }
+#endif
 
        [Test]
        public void ExportCspBlob_Full ()
index 069e348370a9b872461e49500ce97ef380b36910..d34d72b131f1a913704dd55b1ddb6fdf71aecc2a 100644 (file)
@@ -44,8 +44,7 @@ public class DSASignatureDeformatterTest {
        static byte[] sign = { 0x50, 0xd2, 0xb0, 0x8b, 0xcd, 0x5e, 0xb2, 0xc2, 0x35, 0x82, 0xd3, 0x76, 0x07, 0x79, 0xbb, 0x55, 0x98, 0x72, 0x43, 0xe8,
                               0x74, 0xc9, 0x35, 0xf8, 0xc9, 0xbd, 0x69, 0x2f, 0x08, 0x34, 0xfa, 0x5a, 0x59, 0x23, 0x2a, 0x85, 0x7b, 0xa3, 0xb3, 0x82 };
 
-       [TestFixtureSetUp]
-       public void FixtureSetUp () 
+       public DSASignatureDeformatterTest () 
        {
                // key generation is VERY long so one time is enough
                dsa = DSA.Create ();
index 14e060bc9e99e451b7ad6e5b37b0c246340a73ec..ef90ffeb9d646890e809ef695ccbcb47513e7557 100644 (file)
@@ -40,8 +40,7 @@ public class DSASignatureFormatterTest {
        protected static DSA dsa;
        protected static RSA rsa;
 
-       [TestFixtureSetUp]
-       public void FixtureSetUp () 
+       public DSASignatureFormatterTest () 
        {
                // key generation is VERY long so one time is enough
                dsa = DSA.Create ();
index 43a83db4f1b608552128eb3346f8e2ee48ee81b7..eb248213bb0dde3bb2aa32d626578be6f9d20fdd 100644 (file)
@@ -36,7 +36,7 @@ namespace MonoTests.System.Security.Cryptography {
                protected HMACMD5 algo;
 
                [SetUp]
-               protected override void SetUp () 
+               public override void SetUp () 
                {
                        algo = new HMACMD5 ();
                        algo.Key = new byte [8];
index 29bcf75bb3d7ae00f853448cdf33f48639412542..7a99bfdc3207120972131fdbac73e080d56d86e5 100644 (file)
@@ -52,7 +52,7 @@ namespace MonoTests.System.Security.Cryptography {
                protected HMACRIPEMD160 hmac;
 
                [SetUp]
-               protected override void SetUp () 
+               public override void SetUp () 
                {
                        hmac = new HMACRIPEMD160 ();
                        hmac.Key = new byte [8];
index 85b049ebf642a4d70ec496f5b55fb9054d0d2a79..0f769b2a6bf77c13068465cf70e118af2b62769d 100644 (file)
@@ -56,7 +56,7 @@ public class HMACSHA1Test : KeyedHashAlgorithmTest {
        protected HMACSHA1 algo;
 
        [SetUp]
-       protected override void SetUp () 
+       public override void SetUp () 
        {
                hash = HMACSHA1.Create ();
                (hash as KeyedHashAlgorithm).Key = new byte [8];
index 2ca198c702674e162a3209320c2cdf45f1c680dc..99216b043406263cbff1375c26c9f00c7e28e632 100644 (file)
@@ -36,7 +36,7 @@ namespace MonoTests.System.Security.Cryptography {
                protected HMACSHA256 algo;
 
                [SetUp]
-               protected override void SetUp () 
+               public override void SetUp () 
                {
                        algo = new HMACSHA256 ();
                        algo.Key = new byte [8];
index dac396f6f6dd90ea61d9d59234ce498c91c1e06b..115bdf30cc40f2f400002f373e0ed99bb91a980d 100644 (file)
@@ -48,7 +48,7 @@ namespace MonoTests.System.Security.Cryptography {
                private bool legacy;
 
                [SetUp]
-               protected override void SetUp () 
+               public override void SetUp () 
                {
                        algo = new HMACSHA384 ();
                        algo.Key = new byte [8];
index fffd25944be1fd22fd3e8d699ac8a4f60647d282..dab2b8841b1a65b3ff1b87a528a3f919a87ba88b 100644 (file)
@@ -48,7 +48,7 @@ namespace MonoTests.System.Security.Cryptography {
                private bool legacy;
 
                [SetUp]
-               protected override void SetUp () 
+               public override void SetUp () 
                {
                        algo = new HMACSHA512 ();
                        algo.Key = new byte [8];
index ced7d28f4426421660164a56d28b69aec1cf4983..9feea2b3385acd7eb8e93b514d86293ed0adf85e 100644 (file)
@@ -44,7 +44,7 @@ public class HashAlgorithmTest {
        protected HashAlgorithm hash;
 
        [SetUp]
-       protected virtual void SetUp () 
+       public virtual void SetUp () 
        {
                hash = HashAlgorithm.Create ();
        }
@@ -356,7 +356,7 @@ public class HashAlgorithmTest {
        public virtual bool ManagedHashImplementation {
                get { return false; }
        }
-
+#if !NET_2_1
        [Test]
        [Category ("NotWorking")] // Mono nevers throws an exception (and we're all managed ;-)
        public void TransformFinalBlock_Twice ()
@@ -394,7 +394,7 @@ public class HashAlgorithmTest {
                if (!ManagedHashImplementation && !exception)
                        Assert.Fail ("Expected CryptographicException from non *Managed classes");
        }
-
+#endif
        [Test]
        public void TransformFinalBlock_Twice_Initialize ()
        {
@@ -435,7 +435,7 @@ public class HashAlgorithmTest {
        {
                Assert.AreEqual (HashBuffer (false), HashBuffer (true), "Intersect");
        }
-
+#if !NET_2_1
        [Test]
        [ExpectedException (typeof (NullReferenceException))]
        [Category ("NotWorking")] // initialization problem ? fx2.0 only ?
@@ -445,7 +445,7 @@ public class HashAlgorithmTest {
                // getting the property throws
                Assert.IsNull (hash.Hash);
        }
-
+#endif
        [Test]
        [ExpectedException (typeof (CryptographicUnexpectedOperationException))]
        public void Hash_AfterInitialize_SecondTime ()
index 5b972d197a769c562fc09e84d9efec09ae08dcc0..7bd79f62e9b2cf114473fb5d35b13d68b02f8d2a 100644 (file)
@@ -22,7 +22,7 @@ namespace MonoTests.System.Security.Cryptography {
 public class KeyedHashAlgorithmTest : HashAlgorithmTest {
 
        [SetUp]
-       protected override void SetUp () 
+       public override void SetUp () 
        {
                hash = KeyedHashAlgorithm.Create ();
                (hash as KeyedHashAlgorithm).Key = new byte [8];
index 37ac3528bf8708f15cd25b8ad87c05a1f4095d1e..222ed82a1e4c9f8f761f8cc50100e1a2869fdad5 100644 (file)
@@ -91,6 +91,16 @@ namespace MonoTests.System.Security.Cryptography {
                        byte[] random = { 0x01 };
                        byte[] mask = pkcs1.GenerateMask (random, -1);
                }
+               
+               [Test]
+               public void Bug3777 ()
+               {
+                       int maskLen = 0x3F;
+                       int seedLen = 0x40;
+                       byte [] seed = new byte [seedLen];
+                       byte [] mask = pkcs1.GenerateMask (seed, maskLen);
+                       Assert.AreEqual (maskLen, mask.Length, "Length");
+               }
 
                // This test will FAIL with MS framework 1.0 and 1.1 as their MGF1 implementation is buggy
                // see ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip for RSA tests vector
index 9002665f2b3e2d2b9ab92122700e024111288d29..39ab03b052e712c575f98bcfbfbc751610d65e64 100644 (file)
@@ -85,6 +85,7 @@ public class PasswordDeriveBytesTest {
                PasswordDeriveBytes pdb = new PasswordDeriveBytes (pwd, salt, new CspParameters ());
        }
 
+#if !NET_2_1
        [Test]
        [Category ("NotWorking")] // CspParameters aren't supported by Mono (requires CryptoAPI)
        public void Ctor_PasswordSaltNullCspParameters ()
@@ -94,6 +95,7 @@ public class PasswordDeriveBytesTest {
                Assert.AreEqual (100, pdb.IterationCount, "IterationCount");
                Assert.IsNull (pdb.Salt, "Salt");
        }
+#endif
 
        [Test]
        public void Ctor_PasswordSaltCspParametersNull ()
@@ -104,6 +106,7 @@ public class PasswordDeriveBytesTest {
                Assert.AreEqual (ssalt, BitConverter.ToString (pdb.Salt), "Salt");
        }
 
+#if !NET_2_1
        [Test]
        [Category ("NotWorking")] // CspParameters aren't supported by Mono (requires CryptoAPI)
        public void Ctor_PasswordSaltCspParameters ()
@@ -113,6 +116,7 @@ public class PasswordDeriveBytesTest {
                Assert.AreEqual (100, pdb.IterationCount, "IterationCount");
                Assert.AreEqual (ssalt, BitConverter.ToString (pdb.Salt), "Salt");
        }
+#endif
 
        [Test]
 #if NET_2_0
@@ -184,6 +188,7 @@ public class PasswordDeriveBytesTest {
                PasswordDeriveBytes pdb = new PasswordDeriveBytes (pwd, salt, "SHA1", 1, new CspParameters ());
        }
 
+#if !NET_2_1
        [Test]
        [Category ("NotWorking")] // CspParameters aren't supported by Mono (requires CryptoAPI)
        public void Ctor_PasswordSaltNullHashIterationCspParameters ()
@@ -193,6 +198,7 @@ public class PasswordDeriveBytesTest {
                Assert.AreEqual (1, pdb.IterationCount, "IterationCount");
                Assert.IsNull (pdb.Salt, "Salt");
        }
+#endif
 
        [Test]
        [ExpectedException (typeof (ArgumentNullException))]
@@ -214,7 +220,8 @@ public class PasswordDeriveBytesTest {
        {
                PasswordDeriveBytes pdb = new PasswordDeriveBytes ("s3kr3t", salt, "SHA1", 0, new CspParameters ());
        }
-
+               
+#if !NET_2_1
        [Test]
        [Category ("NotWorking")] // CspParameters aren't supported by Mono (requires CryptoAPI)
        public void Ctor_PasswordSaltHashIterationMaxValueCspParameters ()
@@ -224,6 +231,7 @@ public class PasswordDeriveBytesTest {
                Assert.AreEqual (Int32.MaxValue, pdb.IterationCount, "IterationCount");
                Assert.AreEqual (ssalt, BitConverter.ToString (pdb.Salt), "Salt");
        }
+#endif
 
        [Test]
        public void Ctor_PasswordSaltHashIterationCspParametersNull ()
@@ -234,6 +242,7 @@ public class PasswordDeriveBytesTest {
                Assert.AreEqual (ssalt, BitConverter.ToString (pdb.Salt), "Salt");
        }
 
+#if !NET_2_1
        [Test]
        [Category ("NotWorking")] // CspParameters aren't supported by Mono (requires CryptoAPI)
        public void Ctor_PasswordSaltHashIterationCspParameters ()
@@ -243,7 +252,8 @@ public class PasswordDeriveBytesTest {
                Assert.AreEqual (1, pdb.IterationCount, "IterationCount");
                Assert.AreEqual (ssalt, BitConverter.ToString (pdb.Salt), "Salt");
        }
-
+#endif
+               
        // Properties
 
        [Test]
@@ -724,7 +734,8 @@ public class PasswordDeriveBytesTest {
                PasswordDeriveBytes pd = new PasswordDeriveBytes ("password", null, "MD5", 1000);
                pd.CryptDeriveKey ("AlgName", "MD5", 256, new byte [8]);
        }
-
+               
+#if !NET_2_1
        [Test]
        [Category ("NotWorking")] // bug #79499
        public void LongMultipleGetBytes ()
@@ -739,6 +750,7 @@ public class PasswordDeriveBytesTest {
                // bytes from 32-40 are different from calling GetBytes separately
                Assert.AreEqual (key + "-F6-55-6C-3E-54-8B-F3-73-4D-3F-9B-F8-EE-AA-95-ED", BitConverter.ToString (pd.GetBytes (48)), "same");
        }
+#endif
 }
 
 }
index acef2f72b495ab67aff1ab25f85ae83f05ddf904..6f351c4edd0c804aaa675032c5e949a3ff8e04d8 100644 (file)
@@ -25,7 +25,7 @@ namespace MonoTests.System.Security.Cryptography {
                {
                        _algo = new RNGCryptoServiceProvider ();
                }
-
+#if !NET_2_1
                [Test]
                public void ConstructorByteArray () 
                {
@@ -62,7 +62,7 @@ namespace MonoTests.System.Security.Cryptography {
                        string s = null;
                        RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider (s);
                }
-
+#endif
                [Test]
                public void GetBytes () 
                {
index e7027510527e52454b6f53fa81413f7459826cb6..3742d1dba9d458cae3c1dec375bf3f9ecc3de20e 100644 (file)
@@ -45,8 +45,7 @@ public class RSACryptoServiceProviderTest : Assertion {
 
        private bool machineKeyStore;
 
-       [TestFixtureSetUp]
-       public void FixtureSetUp () 
+       public RSACryptoServiceProviderTest () 
        {
                sha1OID = CryptoConfig.MapNameToOID ("SHA1");
                disposed = new RSACryptoServiceProvider (minKeySize);
@@ -415,7 +414,7 @@ public class RSACryptoServiceProviderTest : Assertion {
                rsa.VerifyHash (hash, "1.3.14.3.2.26", null);
        }
 
-#if NET_2_0
+#if NET_2_0 && !NET_2_1
        [Test]
        [Category ("NotWorking")]
        public void ImportDisposed ()
@@ -1151,6 +1150,7 @@ public class RSACryptoServiceProviderTest : Assertion {
        }
 
 #if NET_2_0
+#if !NET_2_1
        [Test]
        [Category ("NotWorking")]
        public void CspKeyContainerInfo_NewKeypair ()
@@ -1212,7 +1212,7 @@ public class RSACryptoServiceProviderTest : Assertion {
                Assert ("Removable", !info.Removable);
                // info.UniqueKeyContainerName throws a CryptographicException at this stage
        }
-
+#endif
        [Test]
        public void ExportCspBlob_Full () 
        {
index 6ffe942c6353f64de96f5ad4bcf55e726992afbc..7d923a5b0aad2dc9e3aa30253a1581b2c95dfaaa 100644 (file)
@@ -303,6 +303,7 @@ namespace MonoTests.System.Security.Cryptography {
                        CreateEncryptor_IV (size);
                }
 
+#if !NET_2_1
                [Test]
                [ExpectedException (typeof (CryptographicException))]
                // Rijndael is the only implementation that has
@@ -313,6 +314,7 @@ namespace MonoTests.System.Security.Cryptography {
                        int size = aes.BlockSize; // 8 times too big
                        CreateEncryptor_IV (size);
                }
+#endif
 
                private ICryptoTransform CreateDecryptor_IV (int size)
                {
@@ -349,7 +351,7 @@ namespace MonoTests.System.Security.Cryptography {
                        int size = (aes.BlockSize >> 3);
                        CreateDecryptor_IV (size);
                }
-
+#if !NET_2_1
                [Test]
                [ExpectedException (typeof (CryptographicException))]
                // Rijndael is the only implementation that has
@@ -360,5 +362,6 @@ namespace MonoTests.System.Security.Cryptography {
                        int size = aes.BlockSize; // 8 times too big
                        CreateDecryptor_IV (size);
                }
+#endif
        }
 }
index e316e858c0c92a26324a2469a1881aabba4b8193..882117029b098693941020f4510c5cfda4bebc0d 100644 (file)
@@ -26,7 +26,7 @@ namespace MonoTests.System.Security.Cryptography {
 public class SHA1CryptoServiceProviderTest : SHA1Test {
 
        [SetUp]
-       protected override void SetUp () 
+       public override void SetUp () 
        {
                hash = new SHA1CryptoServiceProvider ();
        }
index d69675c29f2db292779b683386c376c6a9c0466d..c32ae11ba27c48dfd5a1d9bd36e9a8177704e06b 100644 (file)
@@ -28,7 +28,7 @@ namespace MonoTests.System.Security.Cryptography
 public class SHA1Test : HashAlgorithmTest {
 
        [SetUp]
-       protected override void SetUp () 
+       public override void SetUp () 
        {
                hash = SHA1.Create ();
        }
index e89593972f67223d573b8dad0db9ad2cf90b75e7..4247d7a9f946186fdb8aee273e082e9e100b3b18 100644 (file)
@@ -26,7 +26,7 @@ namespace MonoTests.System.Security.Cryptography {
 public class SHA256ManagedTest : SHA256Test {
 
        [SetUp]
-       protected override void SetUp () 
+       public override void SetUp () 
        {
                hash = new SHA256Managed ();
        }
index a6f574e51e758611ba82e16971e59c2e100084a3..88a3dee98367b71720ab812d2bc302940a27e154 100644 (file)
@@ -27,7 +27,7 @@ namespace MonoTests.System.Security.Cryptography {
 public class SHA256Test : HashAlgorithmTest {
 
        [SetUp]
-       protected override void SetUp () 
+       public override void SetUp () 
        {
                hash = SHA256.Create ();
        }
index dc302ecc30e95efcc4ec62eb5de65fdbf688a5b8..a0beba883839d47f7535ec145127ea7a25d30ba1 100644 (file)
@@ -26,7 +26,7 @@ namespace MonoTests.System.Security.Cryptography {
 public class SHA384ManagedTest : SHA384Test {
 
        [SetUp]
-       protected override void SetUp () 
+       public override void SetUp () 
        {
                hash = new SHA384Managed ();
        }
index fa5dc6160c590c60c29c9aae887c886ece4f368f..2c98fdfe25828e26c28a441ae55f7065d402c7df 100644 (file)
@@ -27,7 +27,7 @@ namespace MonoTests.System.Security.Cryptography {
 public class SHA384Test : HashAlgorithmTest {
 
        [SetUp]
-       protected override void SetUp () 
+       public override void SetUp () 
        {
                hash = SHA384.Create ();
        }
index a204691bdf1ad77c365dc2f0dda22c1b571a9194..b372affad2940be0fac04290d4f9142a7567b884 100644 (file)
@@ -26,7 +26,7 @@ namespace MonoTests.System.Security.Cryptography {
 public class SHA512ManagedTest : SHA512Test {
 
        [SetUp]
-       protected override void SetUp () 
+       public override void SetUp () 
        {
                hash = new SHA512Managed ();
        }
index 4ea92dd70634dd179b872aa02d373e95232ed41d..a8096271ad5f298d8484e9262642bf015c4a52fb 100644 (file)
@@ -27,7 +27,7 @@ namespace MonoTests.System.Security.Cryptography {
 public class SHA512Test : HashAlgorithmTest {
 
        [SetUp]
-       protected override void SetUp () 
+       public override void SetUp () 
        {
                hash = SHA512.Create ();
        }
diff --git a/mcs/errors/cs0023-18.cs b/mcs/errors/cs0023-18.cs
new file mode 100644 (file)
index 0000000..be5a73d
--- /dev/null
@@ -0,0 +1,10 @@
+// CS0023: The `-' operator cannot be applied to operand of type `ulong'
+// Line: 8
+
+class X
+{
+       public static void Main ()
+       {
+               object o = -(9223372036854775808);
+       }
+}
diff --git a/mcs/errors/cs0219-6.cs b/mcs/errors/cs0219-6.cs
new file mode 100644 (file)
index 0000000..a5246cd
--- /dev/null
@@ -0,0 +1,17 @@
+// CS0219: The variable `i' is assigned but its value is never used
+// Line: 14
+// Compiler options: -warn:3 -warnaserror
+
+using System.Collections.Generic;
+
+class C
+{
+       IEnumerable<int> Test ()
+       {
+               try {
+                       yield return 1;
+               } finally {
+                       int i = 100;
+               }
+       }
+}
\ No newline at end of file
diff --git a/mcs/errors/cs2021-2.cs b/mcs/errors/cs2021-2.cs
new file mode 100644 (file)
index 0000000..3ecec8e
--- /dev/null
@@ -0,0 +1,3 @@
+// CS2021: Output file name is not valid
+// Line: 0
+// Compiler options: -out:/
diff --git a/mcs/errors/cs2021.cs b/mcs/errors/cs2021.cs
new file mode 100644 (file)
index 0000000..b9547af
--- /dev/null
@@ -0,0 +1,3 @@
+// CS2021: Output file name is not valid
+// Line: 0
+// Compiler options: -out:.dll
diff --git a/mcs/errors/cs4005-2.cs b/mcs/errors/cs4005-2.cs
new file mode 100644 (file)
index 0000000..920f1b0
--- /dev/null
@@ -0,0 +1,13 @@
+// CS4005: Async methods cannot have unsafe parameters
+// Line: 11
+// Compiler options: -unsafe
+
+class C
+{
+       unsafe delegate void D (int* i);
+       
+       public static void Main ()
+       {
+               D d = async delegate { };
+       }
+}
index 91781cf97b254c4dc5c04de30715c4908ca45404..0c05744fb9ff976d35d62978bbe6218a1927455e 100644 (file)
@@ -199,7 +199,7 @@ namespace Mono.CSharp {
 
                        protected override void DoEmit (EmitContext ec)
                        {
-                               hoisted_this.EmitHoistingAssignment (ec);
+                               hoisted_this.EmitAssign (ec, new CompilerGeneratedThis (ec.CurrentType, loc), false, false);
                        }
 
                        protected override void CloneTo (CloneContext clonectx, Statement target)
@@ -211,7 +211,7 @@ namespace Mono.CSharp {
                // Unique storey ID
                public readonly int ID;
 
-               public readonly Block OriginalSourceBlock;
+               public readonly ExplicitBlock OriginalSourceBlock;
 
                // A list of StoreyFieldPair with local field keeping parent storey instance
                List<StoreyFieldPair> used_parent_storeys;
@@ -219,6 +219,7 @@ namespace Mono.CSharp {
 
                // A list of hoisted parameters
                protected List<HoistedParameter> hoisted_params;
+               List<HoistedParameter> hoisted_local_params;
                protected List<HoistedVariable> hoisted_locals;
 
                // Hoisted this
@@ -227,7 +228,9 @@ namespace Mono.CSharp {
                // Local variable which holds this storey instance
                public Expression Instance;
 
-               public AnonymousMethodStorey (Block block, TypeDefinition parent, MemberBase host, TypeParameters tparams, string name, MemberKind kind)
+               bool initialize_hoisted_this;
+
+               public AnonymousMethodStorey (ExplicitBlock block, TypeDefinition parent, MemberBase host, TypeParameters tparams, string name, MemberKind kind)
                        : base (parent, MakeMemberName (host, name, parent.Module.CounterAnonymousContainers, tparams, block.StartLocation),
                                tparams, 0, kind)
                {
@@ -238,18 +241,10 @@ namespace Mono.CSharp {
                public void AddCapturedThisField (EmitContext ec)
                {
                        TypeExpr type_expr = new TypeExpression (ec.CurrentType, Location);
-                       Field f = AddCompilerGeneratedField ("<>f__this", type_expr);
-                       f.Define ();
+                       Field f = AddCompilerGeneratedField ("$this", type_expr);
                        hoisted_this = new HoistedThis (this, f);
 
-                       // Inflated type instance has to be updated manually
-                       if (Instance.Type is InflatedTypeSpec) {
-                               var inflator = new TypeParameterInflator (this, Instance.Type, TypeParameterSpec.EmptyTypes, TypeSpec.EmptyTypes);
-                               Instance.Type.MemberCache.AddMember (f.Spec.InflateMember (inflator));
-
-                               inflator = new TypeParameterInflator (this, f.Parent.CurrentType, TypeParameterSpec.EmptyTypes, TypeSpec.EmptyTypes);
-                               f.Parent.CurrentType.MemberCache.AddMember (f.Spec.InflateMember (inflator));
-                       }
+                       initialize_hoisted_this = true;
                }
 
                public Field AddCapturedVariable (string name, TypeSpec type)
@@ -309,38 +304,93 @@ namespace Mono.CSharp {
                        used_parent_storeys.Add (new StoreyFieldPair (storey, f));
                }
 
-               public void CaptureLocalVariable (ResolveContext ec, LocalVariable local_info)
+               public void CaptureLocalVariable (ResolveContext ec, LocalVariable localVariable)
                {
-                       ec.CurrentBlock.Explicit.HasCapturedVariable = true;
-                       if (ec.CurrentBlock.Explicit != local_info.Block.Explicit)
-                               AddReferenceFromChildrenBlock (ec.CurrentBlock.Explicit);
+                       if (this is StateMachine) {
+                               if (ec.CurrentBlock.ParametersBlock != localVariable.Block.ParametersBlock)
+                                       ec.CurrentBlock.Explicit.HasCapturedVariable = true;
+                       } else {
+                               ec.CurrentBlock.Explicit.HasCapturedVariable = true;
+                       }
 
-                       if (local_info.HoistedVariant != null)
-                               return;
+                       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;
+                       }
 
-                       HoistedVariable var = new HoistedLocalVariable (this, local_info, GetVariableMangledName (local_info));
-                       local_info.HoistedVariant = var;
+                       if (hoisted == null) {
+                               hoisted = new HoistedLocalVariable (this, localVariable, GetVariableMangledName (localVariable));
+                               localVariable.HoistedVariant = hoisted;
 
-                       if (hoisted_locals == null)
-                               hoisted_locals = new List<HoistedVariable> ();
+                               if (hoisted_locals == null)
+                                       hoisted_locals = new List<HoistedVariable> ();
 
-                       hoisted_locals.Add (var);
+                               hoisted_locals.Add (hoisted);
+                       }
+
+                       if (ec.CurrentBlock.Explicit != localVariable.Block.Explicit)
+                               hoisted.Storey.AddReferenceFromChildrenBlock (ec.CurrentBlock.Explicit);
                }
 
-               public void CaptureParameter (ResolveContext ec, ParameterReference param_ref)
+               public void CaptureParameter (ResolveContext ec, ParametersBlock.ParameterInfo parameterInfo, ParameterReference parameterReference)
                {
-                       ec.CurrentBlock.Explicit.HasCapturedVariable = true;
-                       AddReferenceFromChildrenBlock (ec.CurrentBlock.Explicit);
+                       if (!(this is StateMachine)) {
+                               ec.CurrentBlock.Explicit.HasCapturedVariable = true;
+                       }
 
-                       if (param_ref.GetHoistedVariable (ec) != null)
-                               return;
+                       var hoisted = parameterInfo.Parameter.HoistedVariant;
+
+                       if (parameterInfo.Block.StateMachine is AsyncTaskStorey) {
+                               //
+                               // Another storey in same block exists but state machine does not
+                               // have parameter captured. We need to add it there as well to
+                               // proxy parameter value correctly.
+                               //
+                               if (hoisted == null && parameterInfo.Block.StateMachine != this) {
+                                       var storey = parameterInfo.Block.StateMachine;
 
-                       if (hoisted_params == null)
-                               hoisted_params = new List<HoistedParameter> (2);
+                                       hoisted = new HoistedParameter (storey, parameterReference);
+                                       parameterInfo.Parameter.HoistedVariant = hoisted;
+
+                                       if (storey.hoisted_params == null)
+                                               storey.hoisted_params = new List<HoistedParameter> ();
+
+                                       storey.hoisted_params.Add (hoisted);
+                               }
+
+                               //
+                               // Lift captured parameter from value type storey to reference type one. Otherwise
+                               // any side effects would be done on a copy
+                               //
+                               if (hoisted != null && hoisted.Storey != this && hoisted.Storey.Kind == MemberKind.Struct) {
+                                       if (hoisted_local_params == null)
+                                               hoisted_local_params = new List<HoistedParameter> ();
+
+                                       hoisted_local_params.Add (hoisted);
+                                       hoisted = null;
+                               }
+                       }
+
+                       if (hoisted == null) {
+                               hoisted = new HoistedParameter (this, parameterReference);
+                               parameterInfo.Parameter.HoistedVariant = hoisted;
+
+                               if (hoisted_params == null)
+                                       hoisted_params = new List<HoistedParameter> ();
+
+                               hoisted_params.Add (hoisted);
+                       }
 
-                       var expr = new HoistedParameter (this, param_ref);
-                       param_ref.Parameter.HoistedVariant = expr;
-                       hoisted_params.Add (expr);
+                       //
+                       // Register link between current block and parameter storey. It will
+                       // be used when setting up storey definition to deploy storey reference
+                       // when parameters are used from multiple blocks
+                       //
+                       if (ec.CurrentBlock.Explicit != parameterInfo.Block) {
+                               hoisted.Storey.AddReferenceFromChildrenBlock (ec.CurrentBlock.Explicit);
+                       }
                }
 
                TypeExpr CreateStoreyTypeExpression (EmitContext ec)
@@ -496,10 +546,10 @@ namespace Mono.CSharp {
                        }
 
                        //
-                       // Define hoisted `this' in top-level storey only 
+                       // Initialize hoisted `this' only once, everywhere else will be
+                       // referenced indirectly
                        //
-                       if (OriginalSourceBlock.Explicit.HasCapturedThis && !(Parent is AnonymousMethodStorey)) {
-                               AddCapturedThisField (ec);
+                       if (initialize_hoisted_this) {
                                rc.CurrentBlock.AddScopeStatement (new ThisInitializer (hoisted_this));
                        }
 
@@ -516,9 +566,20 @@ namespace Mono.CSharp {
                        ec.CurrentAnonymousMethod = ae;
                }
 
-               protected virtual void EmitHoistedParameters (EmitContext ec, IList<HoistedParameter> hoisted)
+               protected virtual void EmitHoistedParameters (EmitContext ec, List<HoistedParameter> hoisted)
                {
                        foreach (HoistedParameter hp in hoisted) {
+                               //
+                               // Parameters could be proxied via local fields for value type storey
+                               //
+                               if (hoisted_local_params != null) {
+                                       var local_param = hoisted_local_params.Find (l => l.Parameter.Parameter == hp.Parameter.Parameter);
+                                       var source = new FieldExpr (local_param.Field, Location);
+                                       source.InstanceExpression = new CompilerGeneratedThis (CurrentType, Location);
+                                       hp.EmitAssign (ec, source, false, false);
+                                       continue;
+                               }
+
                                hp.EmitHoistingAssignment (ec);
                        }
                }
@@ -591,7 +652,12 @@ namespace Mono.CSharp {
                }
 
                public HoistedThis HoistedThis {
-                       get { return hoisted_this; }
+                       get {
+                               return hoisted_this;
+                       }
+                       set {
+                               hoisted_this = value;
+                       }
                }
 
                public IList<ExplicitBlock> ReferencesFromChildrenBlock {
@@ -659,6 +725,12 @@ namespace Mono.CSharp {
                        this.field = field;
                }
 
+               public AnonymousMethodStorey Storey {
+                       get {
+                               return storey;
+                       }
+               }
+
                public void AddressOf (EmitContext ec, AddressOp mode)
                {
                        GetFieldExpression (ec).AddressOf (ec, mode);
@@ -740,7 +812,7 @@ namespace Mono.CSharp {
 
        public class HoistedParameter : HoistedVariable
        {
-               sealed class HoistedFieldAssign : Assign
+               sealed class HoistedFieldAssign : CompilerAssign
                {
                        public HoistedFieldAssign (Expression target, Expression source)
                                : base (target, source, source.Location)
@@ -771,23 +843,32 @@ namespace Mono.CSharp {
                        this.parameter = hp.parameter;
                }
 
+               #region Properties
+
                public Field Field {
                        get {
                                return field;
                        }
                }
 
+               public ParameterReference Parameter {
+                       get {
+                               return parameter;
+                       }
+               }
+
+               #endregion
+
                public void EmitHoistingAssignment (EmitContext ec)
                {
                        //
                        // Remove hoisted redirection to emit assignment from original parameter
                        //
-                       HoistedVariable temp = parameter.Parameter.HoistedVariant;
+                       var temp = parameter.Parameter.HoistedVariant;
                        parameter.Parameter.HoistedVariant = null;
 
-                       Assign a = new HoistedFieldAssign (GetFieldExpression (ec), parameter);
-                       if (a.Resolve (new ResolveContext (ec.MemberContext)) != null)
-                               a.EmitStatement (ec);
+                       var a = new HoistedFieldAssign (GetFieldExpression (ec), parameter);
+                       a.EmitStatement (ec);
 
                        parameter.Parameter.HoistedVariant = temp;
                }
@@ -813,13 +894,6 @@ namespace Mono.CSharp {
                                return field;
                        }
                }
-
-               public void EmitHoistingAssignment (EmitContext ec)
-               {
-                       SimpleAssign a = new SimpleAssign (GetFieldExpression (ec), new CompilerGeneratedThis (ec.CurrentType, field.Location));
-                       if (a.Resolve (new ResolveContext (ec.MemberContext)) != null)
-                               a.EmitStatement (ec);
-               }
        }
 
        //
@@ -1030,12 +1104,8 @@ namespace Mono.CSharp {
                        }
 
                        using (ec.Set (ResolveContext.Options.ProbingMode | ResolveContext.Options.InferReturnType)) {
-                               var body = CompatibleMethodBody (ec, tic, InternalType.Arglist, delegate_type);
+                               var body = CompatibleMethodBody (ec, tic, null, delegate_type);
                                if (body != null) {
-                                       if (Block.IsAsync) {
-                                               AsyncInitializer.Create (ec, body.Block, body.Parameters, ec.CurrentMemberDefinition.Parent.PartialContainer, null, loc);
-                                       }
-
                                        am = body.Compatible (ec, body);
                                } else {
                                        am = null;
@@ -1122,18 +1192,6 @@ namespace Mono.CSharp {
                                                        am = CreateExpressionTree (ec, delegate_type);
                                        }
                                } else {
-                                       if (Block.IsAsync) {
-                                               var rt = body.ReturnType;
-                                               if (rt.Kind != MemberKind.Void &&
-                                                       rt != ec.Module.PredefinedTypes.Task.TypeSpec &&
-                                                       !rt.IsGenericTask) {
-                                                       ec.Report.Error (4010, loc, "Cannot convert async {0} to delegate type `{1}'",
-                                                               GetSignatureForError (), type.GetSignatureForError ());
-                                               }
-
-                                               AsyncInitializer.Create (ec, body.Block, body.Parameters, ec.CurrentMemberDefinition.Parent.PartialContainer, rt, loc);
-                                       }
-
                                        am = body.Compatible (ec);
                                }
                        } catch (CompletionResult) {
@@ -1261,7 +1319,19 @@ namespace Mono.CSharp {
 
                        ParametersBlock b = ec.IsInProbingMode ? (ParametersBlock) Block.PerformClone () : Block;
 
-                       return CompatibleMethodFactory (return_type, delegate_type, p, b);
+                       if (b.IsAsync) {
+                               var rt = return_type;
+                               if (rt != null && rt.Kind != MemberKind.Void && rt != ec.Module.PredefinedTypes.Task.TypeSpec && !rt.IsGenericTask) {
+                                       ec.Report.Error (4010, loc, "Cannot convert async {0} to delegate type `{1}'",
+                                               GetSignatureForError (), delegate_type.GetSignatureForError ());
+
+                                       return null;
+                               }
+
+                               b = b.ConvertToAsyncTask (ec, ec.CurrentMemberDefinition.Parent.PartialContainer, p, return_type, loc);
+                       }
+
+                       return CompatibleMethodFactory (return_type ?? InternalType.Arglist, delegate_type, p, b);
                }
 
                protected virtual AnonymousMethodBody CompatibleMethodFactory (TypeSpec return_type, TypeSpec delegate_type, ParametersCompiled p, ParametersBlock b)
@@ -1361,6 +1431,15 @@ namespace Mono.CSharp {
                public abstract bool IsIterator { get; }
                public abstract AnonymousMethodStorey Storey { get; }
 
+               //
+               // The block that makes up the body for the anonymous method
+               //
+               public ParametersBlock Block {
+                       get {
+                               return block;
+                       }
+               }
+
                public AnonymousExpression Compatible (ResolveContext ec)
                {
                        return Compatible (ec, this);
@@ -1434,16 +1513,6 @@ namespace Mono.CSharp {
                                b = b.Parent == null ? null : b.Parent.Explicit;
                        } while (b != null);
                }
-
-               //
-               // The block that makes up the body for the anonymous method
-               //
-               public ParametersBlock Block {
-                       get {
-                               return block;
-                       }
-               }
-
        }
 
        public class AnonymousMethodBody : AnonymousExpression
@@ -1531,17 +1600,47 @@ namespace Mono.CSharp {
                        //
 
                        Modifiers modifiers;
-                       if (Block.HasCapturedVariable || Block.HasCapturedThis) {
-                               storey = FindBestMethodStorey ();
+                       TypeDefinition parent = null;
+
+                       var src_block = Block.Original.Explicit;
+                       if (src_block.HasCapturedVariable || src_block.HasCapturedThis) {
+                               parent = storey = FindBestMethodStorey ();
+
+                               if (storey == null) {
+                                       var sm = src_block.ParametersBlock.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++);
@@ -1646,6 +1745,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;
@@ -1656,9 +1766,7 @@ namespace Mono.CSharp {
                                // Mutate anonymous method instance type if we are in nested
                                // hoisted generic anonymous method storey
                                //
-                               if (ec.CurrentAnonymousMethod != null &&
-                                       ec.CurrentAnonymousMethod.Storey != null &&
-                                       ec.CurrentAnonymousMethod.Storey.Mutator != null) {
+                               if (ec.IsAnonymousStoreyMutateRequired) {
                                        t = storey.Mutator.Mutate (t);
                                }
 
@@ -1772,7 +1880,7 @@ namespace Mono.CSharp {
                        c.Block = new ToplevelBlock (parent.Module.Compiler, c.ParameterInfo, loc);
 
                        // 
-                       // Create fields and contructor body with field initialization
+                       // Create fields and constructor body with field initialization
                        //
                        bool error = false;
                        for (int i = 0; i < parameters.Count; ++i) {
index f72d48195cee10d2787928d661b6e81a28c9a48c..1822ac65eeaa239b90d8de0cb3fa6151b3313b41 100644 (file)
@@ -343,7 +343,7 @@ namespace Mono.CSharp {
                        type = target_type;
 
                        if (!(target is IAssignMethod)) {
-                               Error_ValueAssignment (ec, source);
+                               target.Error_ValueAssignment (ec, source);
                                return null;
                        }
 
@@ -567,10 +567,10 @@ namespace Mono.CSharp {
 
                        //
                        // Emit sequence symbol info even if we are in compiler generated
-                       // block to allow debugging filed initializers when constructor is
+                       // block to allow debugging field initializers when constructor is
                        // compiler generated
                        //
-                       if (ec.HasSet (BuilderContext.Options.OmitDebugInfo)) {
+                       if (ec.HasSet (BuilderContext.Options.OmitDebugInfo) && ec.HasMethodSymbolBuilder) {
                                using (ec.With (BuilderContext.Options.OmitDebugInfo, false)) {
                                        ec.Mark (loc);
                                }
@@ -815,7 +815,7 @@ namespace Mono.CSharp {
                                return new SimpleAssign (target, new DynamicConversion (target_type, CSharpBinderFlags.ConvertExplicit, arg, loc), loc).Resolve (ec);
                        }
 
-                       right.Error_ValueCannotBeConverted (ec, loc, target_type, false);
+                       right.Error_ValueCannotBeConverted (ec, target_type, false);
                        return null;
                }
 
index 3fa90a545d553cff12a92f4f2adaa7bc48e57976..c2885de8e0b1350a76c2a137ffa70c73b0831d1a 100644 (file)
@@ -405,12 +405,6 @@ namespace Mono.CSharp
                        }
                }
 
-               public Block OriginalBlock {
-                       get {
-                               return block.Parent;
-                       }
-               }
-
                public TypeInferenceContext ReturnTypeInference {
                        get {
                                return return_inference;
@@ -419,38 +413,6 @@ namespace Mono.CSharp
 
                #endregion
 
-               public static void Create (IMemberContext context, ParametersBlock block, ParametersCompiled parameters, TypeDefinition host, TypeSpec returnType, Location loc)
-               {
-                       for (int i = 0; i < parameters.Count; i++) {
-                               Parameter p = parameters[i];
-                               Parameter.Modifier mod = p.ModFlags;
-                               if ((mod & Parameter.Modifier.RefOutMask) != 0) {
-                                       host.Compiler.Report.Error (1988, p.Location,
-                                               "Async methods cannot have ref or out parameters");
-                                       return;
-                               }
-
-                               if (p is ArglistParameter) {
-                                       host.Compiler.Report.Error (4006, p.Location,
-                                               "__arglist is not allowed in parameter list of async methods");
-                                       return;
-                               }
-
-                               if (parameters.Types[i].IsPointer) {
-                                       host.Compiler.Report.Error (4005, p.Location,
-                                               "Async methods cannot have unsafe parameters");
-                                       return;
-                               }
-                       }
-
-                       if (!block.HasAwait) {
-                               host.Compiler.Report.Warning (1998, 1, loc,
-                                       "Async block lacks `await' operator and will run synchronously");
-                       }
-
-                       block.WrapIntoAsyncTask (context, host, returnType);
-               }
-
                protected override BlockContext CreateBlockContext (ResolveContext rc)
                {
                        var ctx = base.CreateBlockContext (rc);
@@ -501,8 +463,8 @@ namespace Mono.CSharp
                Dictionary<TypeSpec, List<Field>> stack_fields;
                Dictionary<TypeSpec, List<Field>> awaiter_fields;
 
-               public AsyncTaskStorey (IMemberContext context, AsyncInitializer initializer, TypeSpec type)
-                       : base (initializer.OriginalBlock, initializer.Host, context.CurrentMemberDefinition as MemberBase, context.CurrentTypeParameters, "async", MemberKind.Class)
+               public AsyncTaskStorey (ParametersBlock block, IMemberContext context, AsyncInitializer initializer, TypeSpec type)
+                       : base (block, initializer.Host, context.CurrentMemberDefinition as MemberBase, context.CurrentTypeParameters, "async", MemberKind.Struct)
                {
                        return_type = type;
                        awaiter_fields = new Dictionary<TypeSpec, List<Field>> ();
@@ -787,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)
@@ -826,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);
@@ -899,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 7580124ceead35f46cd9af384fdc17b2fe99dcb8..9e2cfc8b96c8704aadcd828986d007581c55b2db 100644 (file)
@@ -149,7 +149,7 @@ namespace Mono.CSharp {
                                        case Binary.Operator.ExclusiveOr:
                                                result = BinaryFold (ec, oper, ((EnumConstant)left).Child, ((EnumConstant)right).Child, loc);
                                                if (result != null)
-                                                       result = result.TryReduce (ec, lt, loc);
+                                                       result = result.TryReduce (ec, lt);
                                                return result;
 
                                        ///
@@ -158,7 +158,7 @@ namespace Mono.CSharp {
                                        case Binary.Operator.Subtraction:
                                                result = BinaryFold (ec, oper, ((EnumConstant)left).Child, ((EnumConstant)right).Child, loc);
                                                if (result != null)
-                                                       result = result.TryReduce (ec, EnumSpec.GetUnderlyingType (lt), loc);
+                                                       result = result.TryReduce (ec, EnumSpec.GetUnderlyingType (lt));
                                                return result;
 
                                        ///
@@ -340,7 +340,7 @@ namespace Mono.CSharp {
                                        if (result == null)
                                                return null;
 
-                                       result = result.TryReduce (ec, lt, loc);
+                                       result = result.TryReduce (ec, lt);
                                        if (result == null)
                                                return null;
 
@@ -459,7 +459,7 @@ namespace Mono.CSharp {
                                        if (result == null)
                                                return null;
 
-                                       result = result.TryReduce (ec, lt, loc);
+                                       result = result.TryReduce (ec, lt);
                                        if (result == null)
                                                return null;
 
index fc8c82e31f6e0de14beb690c8428ab68a299ad9c..465da5a3af1a66a080f9f07ecfa1e18564907c8e 100644 (file)
@@ -139,6 +139,12 @@ namespace Mono.CSharp
                        }
                }
 
+               public bool HasMethodSymbolBuilder {
+                       get {
+                               return methodSymbols != null;
+                       }
+               }
+
                public bool HasReturnLabel {
                        get {
                                return return_label.HasValue;
index 7d42bde35498a4dddfa0acce6618db024777636a..883b0d2c23fe1efd45e1a5b61e4fe73317a3b251 100644 (file)
@@ -200,7 +200,7 @@ namespace Mono.CSharp {
                                        else if (!(expr is Constant))
                                                Error_ExpressionMustBeConstant (rc, expr.Location, GetSignatureForError ());
                                        else
-                                               expr.Error_ValueCannotBeConverted (rc, expr.Location, field.MemberType, false);
+                                               expr.Error_ValueCannotBeConverted (rc, field.MemberType, false);
                                }
 
                                expr = c;
index 86250a222af1e33e389e8ae965ccd93b1eee5707..3cf689ddd81fc60b9fbafbda936eb4733fb4fc43 100644 (file)
@@ -58,7 +58,7 @@ namespace Mono.CSharp {
                }
 #endif
 
-               public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl)
+               public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl)
                {
                        if (!expl && IsLiteral && 
                                BuiltinTypeSpec.IsPrimitiveTypeOrDecimal (target) &&
@@ -66,7 +66,7 @@ namespace Mono.CSharp {
                                ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'",
                                        GetValueAsLiteral (), TypeManager.CSharpName (target));
                        } else {
-                               base.Error_ValueCannotBeConverted (ec, loc, target, expl);
+                               base.Error_ValueCannotBeConverted (ec, target, expl);
                        }
                }
 
@@ -74,7 +74,7 @@ namespace Mono.CSharp {
                {
                        Constant c = ConvertImplicitly (type);
                        if (c == null)
-                               Error_ValueCannotBeConverted (ec, loc, type, false);
+                               Error_ValueCannotBeConverted (ec, type, false);
 
                        return c;
                }
@@ -160,8 +160,11 @@ namespace Mono.CSharp {
                                        return new NullConstant (t, loc);
                        }
 
-                       throw new InternalErrorException ("Constant value `{0}' has unexpected underlying type `{1}'",
-                               v, TypeManager.CSharpName (t));
+#if STATIC
+                       throw new InternalErrorException ("Constant value `{0}' has unexpected underlying type `{1}'", v, t.GetSignatureForError ());
+#else
+                       return null;
+#endif
                }
 
                public override Expression CreateExpressionTree (ResolveContext ec)
@@ -251,32 +254,38 @@ namespace Mono.CSharp {
                /// <summary>
                ///   Attempts to do a compile-time folding of a constant cast.
                /// </summary>
-               public Constant TryReduce (ResolveContext ec, TypeSpec target_type, Location loc)
+               public Constant TryReduce (ResolveContext ec, TypeSpec target_type)
                {
                        try {
-                               return TryReduce (ec, target_type);
-                       }
-                       catch (OverflowException) {
+                               return TryReduceConstant (ec, target_type);
+                       } catch (OverflowException) {
                                if (ec.ConstantCheckState && Type.BuiltinType != BuiltinTypeSpec.Type.Decimal) {
                                        ec.Report.Error (221, loc,
                                                "Constant value `{0}' cannot be converted to a `{1}' (use `unchecked' syntax to override)",
                                                GetValueAsLiteral (), target_type.GetSignatureForError ());
                                } else {
-                                       Error_ValueCannotBeConverted (ec, loc, target_type, false);
+                                       Error_ValueCannotBeConverted (ec, target_type, false);
                                }
 
                                return New.Constantify (target_type, loc);
                        }
                }
 
-               Constant TryReduce (ResolveContext ec, TypeSpec target_type)
+               Constant TryReduceConstant (ResolveContext ec, TypeSpec target_type)
                {
-                       if (Type == target_type)
+                       if (Type == target_type) {
+                               //
+                               // Reducing literal value produces a new constant. Syntactically 10 is not same as (int)10 
+                               //
+                               if (IsLiteral)
+                                       return CreateConstantFromValue (target_type, GetValue (), loc);
+
                                return this;
+                       }
 
                        Constant c;
                        if (target_type.IsEnum) {
-                               c = TryReduce (ec, EnumSpec.GetUnderlyingType (target_type));
+                               c = TryReduceConstant (ec, EnumSpec.GetUnderlyingType (target_type));
                                if (c == null)
                                        return null;
 
@@ -372,11 +381,11 @@ namespace Mono.CSharp {
                        eclass = ExprClass.Value;
                }
 
-               public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl)
+               public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl)
                {
                        try {
                                ConvertExplicitly (true, target);
-                               base.Error_ValueCannotBeConverted (ec, loc, target, expl);
+                               base.Error_ValueCannotBeConverted (ec, target, expl);
                        }
                        catch
                        {
index d28cc0dd06a2bed0ff0a4bab11e5b9e2ce611285..a9a304dfc915fc30af7a568a267596a093f66d35 100644 (file)
@@ -1195,7 +1195,7 @@ namespace Mono.CSharp {
                        if (s_x != source_type) {
                                var c = source as Constant;
                                if (c != null) {
-                                       source = c.TryReduce (ec, s_x, loc);
+                                       source = c.TryReduce (ec, s_x);
                                } else {
                                        source = implicitOnly ?
                                                ImplicitConversionStandard (ec, source_type_expr, s_x, loc) :
@@ -1423,7 +1423,7 @@ namespace Mono.CSharp {
                        if (e != null)
                                return e;
 
-                       source.Error_ValueCannotBeConverted (ec, loc, target_type, false);
+                       source.Error_ValueCannotBeConverted (ec, target_type, false);
                        return null;
                }
 
@@ -2103,7 +2103,7 @@ namespace Mono.CSharp {
                        if (ec.IsUnsafe && expr.Type.IsPointer && target_type.IsPointer && ((PointerContainer)expr.Type).Element.Kind == MemberKind.Void)
                                return EmptyCast.Create (expr, target_type);
 
-                       expr.Error_ValueCannotBeConverted (ec, l, target_type, true);
+                       expr.Error_ValueCannotBeConverted (ec, target_type, true);
                        return null;
                }
 
@@ -2166,7 +2166,7 @@ namespace Mono.CSharp {
                        if (e != null)
                                return e;                       
 
-                       expr.Error_ValueCannotBeConverted (ec, loc, target_type, true);
+                       expr.Error_ValueCannotBeConverted (ec, target_type, true);
                        return null;
                }
        }
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 d3e2f2fad09f57090cad658bab5c3dce09bcaf1d..cd42b8974c631cd7efc4a86f15b8153f2090933b 100644 (file)
@@ -256,6 +256,12 @@ namespace Mono.CSharp
                                output_file = output_file_name;
                        } else {
                                output_file_name = Path.GetFileName (output_file);
+
+                               if (string.IsNullOrEmpty (Path.GetFileNameWithoutExtension (output_file_name)) ||
+                                       output_file_name.IndexOfAny (Path.GetInvalidFileNameChars ()) >= 0) {
+                                       Report.Error (2021, "Output file name is not valid");
+                                       return false;
+                               }
                        }
 
 #if STATIC
index b6ebc8f1c80b640ac686cb858dd104856d9c3b3a..2e3757d9616a7e47053797ea6855368fb536fe04 100644 (file)
@@ -240,7 +240,7 @@ namespace Mono.CSharp {
                        Report.Error (1547, loc, "Keyword `void' cannot be used in this context");
                }
 
-               public virtual void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl)
+               public virtual void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl)
                {
                        Error_ValueCannotBeConvertedCore (ec, loc, target, expl);
                }
@@ -320,7 +320,7 @@ namespace Mono.CSharp {
                                TypeManager.CSharpName (type), name);
                }
 
-               public void Error_ValueAssignment (ResolveContext rc, Expression rhs)
+               public virtual void Error_ValueAssignment (ResolveContext rc, Expression rhs)
                {
                        if (rhs == EmptyExpression.LValueMemberAccess || rhs == EmptyExpression.LValueMemberOutAccess) {
                                rc.Report.SymbolRelatedToPreviousError (type);
@@ -915,7 +915,7 @@ namespace Mono.CSharp {
                                        converted = Convert.ImplicitConversion (ec, source, btypes.ULong, source.loc);
 
                                if (converted == null) {
-                                       source.Error_ValueCannotBeConverted (ec, source.loc, btypes.Int, false);
+                                       source.Error_ValueCannotBeConverted (ec, btypes.Int, false);
                                        return null;
                                }
                        }
@@ -3348,7 +3348,7 @@ namespace Mono.CSharp {
                        call.Emit (ec, best_candidate, arguments, loc);                 
                }
 
-               public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl)
+               public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl)
                {
                        ec.Report.Error (428, loc, "Cannot convert method group `{0}' to non-delegate type `{1}'. Consider using parentheses to invoke the method",
                                Name, TypeManager.CSharpName (target));
@@ -6289,9 +6289,10 @@ namespace Mono.CSharp {
 
                        //
                        // Don't capture temporary variables except when using
-                       // state machine redirection
+                       // state machine redirection and block yields
                        //
-                       if (ec.CurrentAnonymousMethod != null && ec.CurrentAnonymousMethod is StateMachineInitializer && ec.IsVariableCapturingRequired) {
+                       if (ec.CurrentAnonymousMethod != null && ec.CurrentAnonymousMethod.IsIterator &&
+                               ec.CurrentBlock.Explicit.HasYield && ec.IsVariableCapturingRequired) {
                                AnonymousMethodStorey storey = li.Block.Explicit.CreateAnonymousMethodStorey (ec);
                                storey.CaptureLocalVariable (ec, li);
                        }
index c6d13c9a99091e4627cb5f4dd04b0f2394260cd3..db9babed55c3a22ca2cecd8a07879acf5869e195 100644 (file)
@@ -103,7 +103,12 @@ namespace Mono.CSharp
 
                protected override Expression DoResolve (ResolveContext ec)
                {
-                       return expr.Resolve (ec);
+                       var res = expr.Resolve (ec);
+                       var constant = res as Constant;
+                       if (constant != null && constant.IsLiteral)
+                               return Constant.CreateConstantFromValue (res.Type, constant.GetValue (), expr.Location);
+
+                       return res;
                }
 
                public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
@@ -142,10 +147,12 @@ namespace Mono.CSharp
                //   This routine will attempt to simplify the unary expression when the
                //   argument is a constant.
                // </summary>
-               Constant TryReduceConstant (ResolveContext ec, Constant e)
+               Constant TryReduceConstant (ResolveContext ec, Constant constant)
                {
-                       if (e is EmptyConstantCast)
-                               return TryReduceConstant (ec, ((EmptyConstantCast) e).child);
+                       var e = constant;
+
+                       while (e is EmptyConstantCast)
+                               e = ((EmptyConstantCast) e).child;
                        
                        if (e is SideEffectConstant) {
                                Constant r = TryReduceConstant (ec, ((SideEffectConstant) e).value);
@@ -220,7 +227,7 @@ namespace Mono.CSharp
                                        return new LongConstant (ec.BuiltinTypes, -lvalue, e.Location);
 
                                case BuiltinTypeSpec.Type.UInt:
-                                       UIntLiteral uil = e as UIntLiteral;
+                                       UIntLiteral uil = constant as UIntLiteral;
                                        if (uil != null) {
                                                if (uil.Value == int.MaxValue + (uint) 1)
                                                        return new IntLiteral (ec.BuiltinTypes, int.MinValue, e.Location);
@@ -230,13 +237,13 @@ namespace Mono.CSharp
 
 
                                case BuiltinTypeSpec.Type.ULong:
-                                       ULongLiteral ull = e as ULongLiteral;
+                                       ULongLiteral ull = constant as ULongLiteral;
                                        if (ull != null && ull.Value == 9223372036854775808)
                                                return new LongLiteral (ec.BuiltinTypes, long.MinValue, e.Location);
                                        return null;
 
                                case BuiltinTypeSpec.Type.Float:
-                                       FloatLiteral fl = e as FloatLiteral;
+                                       FloatLiteral fl = constant as FloatLiteral;
                                        // For better error reporting
                                        if (fl != null)
                                                return new FloatLiteral (ec.BuiltinTypes, -fl.Value, e.Location);
@@ -244,7 +251,7 @@ namespace Mono.CSharp
                                        return new FloatConstant (ec.BuiltinTypes, -((FloatConstant) e).Value, e.Location);
 
                                case BuiltinTypeSpec.Type.Double:
-                                       DoubleLiteral dl = e as DoubleLiteral;
+                                       DoubleLiteral dl = constant as DoubleLiteral;
                                        // For better error reporting
                                        if (dl != null)
                                                return new DoubleLiteral (ec.BuiltinTypes, -dl.Value, e.Location);
@@ -1687,19 +1694,19 @@ namespace Mono.CSharp
                                return null;
                        }
 
-                       eclass = ExprClass.Value;
+                       if (type.IsPointer && !ec.IsUnsafe) {
+                               UnsafeError (ec, loc);
+                       }
 
+                       eclass = ExprClass.Value;
+                       
                        Constant c = expr as Constant;
                        if (c != null) {
-                               c = c.TryReduce (ec, type, loc);
+                               c = c.TryReduce (ec, type);
                                if (c != null)
                                        return c;
                        }
 
-                       if (type.IsPointer && !ec.IsUnsafe) {
-                               UnsafeError (ec, loc);
-                       }
-
                        var res = Convert.ExplicitConversion (ec, expr, type, loc);
                        if (res == expr)
                                return EmptyCast.Create (res, type);
@@ -2654,7 +2661,7 @@ namespace Mono.CSharp
                                        return left;
                                
                                if (left.IsZeroInteger)
-                                       return left.TryReduce (ec, right.Type, loc);
+                                       return left.TryReduce (ec, right.Type);
                                
                                break;
                                
@@ -4497,7 +4504,7 @@ namespace Mono.CSharp
                        //
                        converted = GetOperatorTrue (ec, expr, loc);
                        if (converted == null) {
-                               expr.Error_ValueCannotBeConverted (ec, loc, type, false);
+                               expr.Error_ValueCannotBeConverted (ec, type, false);
                                return null;
                        }
 
@@ -5149,7 +5156,7 @@ namespace Mono.CSharp
 
                                if (ec.IsVariableCapturingRequired && !pi.Block.ParametersBlock.IsExpressionTree) {
                                        AnonymousMethodStorey storey = pi.Block.Explicit.CreateAnonymousMethodStorey (ec);
-                                       storey.CaptureParameter (ec, this);
+                                       storey.CaptureParameter (ec, pi, this);
                                }
                        }
 
@@ -6982,15 +6989,7 @@ namespace Mono.CSharp
                                return null;
 
                        AnonymousMethodStorey storey = ae.Storey;
-                       while (storey != null) {
-                               AnonymousMethodStorey temp = storey.Parent as AnonymousMethodStorey;
-                               if (temp == null)
-                                       return storey.HoistedThis;
-
-                               storey = temp;
-                       }
-
-                       return null;
+                       return storey != null ? storey.HoistedThis : null;
                }
 
                public static bool IsThisAvailable (ResolveContext ec, bool ignoreAnonymous)
@@ -7019,11 +7018,20 @@ namespace Mono.CSharp
 
                        var block = ec.CurrentBlock;
                        if (block != null) {
-                               if (block.ParametersBlock.TopBlock.ThisVariable != null)
-                                       variable_info = block.ParametersBlock.TopBlock.ThisVariable.VariableInfo;
+                               var top = block.ParametersBlock.TopBlock;
+                               if (top.ThisVariable != null)
+                                       variable_info = top.ThisVariable.VariableInfo;
 
                                AnonymousExpression am = ec.CurrentAnonymousMethod;
-                               if (am != null && ec.IsVariableCapturingRequired) {
+                               if (am != null && ec.IsVariableCapturingRequired && !block.Explicit.HasCapturedThis) {
+                                       //
+                                       // Hoisted this is almost like hoisted variable but not exactly. When
+                                       // there is no variable hoisted we can simply emit an instance method
+                                       // without lifting this into a storey. Unfotunatelly this complicates
+                                       // this in other cases because we don't know where this will be hoisted
+                                       // until top-level block is fully resolved
+                                       //
+                                       top.AddThisReferenceFromChildrenBlock (block.Explicit);
                                        am.SetHasThisAccess ();
                                }
                        }
@@ -9228,11 +9236,15 @@ namespace Mono.CSharp
                        return this;
                }
 
+               public override void Error_ValueAssignment (ResolveContext rc, Expression rhs)
+               {
+               }
+
                public override void Error_UnexpectedKind (ResolveContext ec, ResolveFlags flags, Location loc)
                {
                }
 
-               public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl)
+               public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl)
                {
                }
 
index 4041701835d24b72a10bbcada26d302f79184124..986445ad70a00ca976226561533eea802fa1e702 100644 (file)
 // Copyright 2011 Xamarin Inc.
 //
 
-// TODO:
-//    Flow analysis for Yield.
-//
-
 using System;
 using System.Collections.Generic;
 using Mono.CompilerServices.SymbolWriter;
@@ -160,8 +156,9 @@ namespace Mono.CSharp
 
                Field pc_field;
                StateMachineMethod method;
+               int local_name_idx;
 
-               protected StateMachine (Block block, TypeDefinition parent, MemberBase host, TypeParameters tparams, string name, MemberKind kind)
+               protected StateMachine (ParametersBlock block, TypeDefinition parent, MemberBase host, TypeParameters tparams, string name, MemberKind kind)
                        : base (block, parent, host, tparams, name, kind)
                {
                }
@@ -197,6 +194,14 @@ namespace Mono.CSharp
 
                        return base.DoDefineMembers ();
                }
+
+               protected override string GetVariableMangledName (LocalVariable local_info)
+               {
+                       if (local_info.IsCompilerGenerated)
+                               return base.GetVariableMangledName (local_info);
+
+                       return "<" + local_info.Name + ">__" + local_name_idx++.ToString ("X");
+               }
        }
 
        class IteratorStorey : StateMachine
@@ -399,7 +404,6 @@ namespace Mono.CSharp
                TypeExpr iterator_type_expr;
                Field current_field;
                Field disposing_field;
-               int local_name_idx;
 
                TypeSpec generic_enumerator_type;
                TypeSpec generic_enumerable_type;
@@ -558,19 +562,11 @@ namespace Mono.CSharp
                        reset.Block.AddStatement (new Throw (new New (new TypeExpression (ex_type, Location), null, Location), Location));
                }
 
-               protected override void EmitHoistedParameters (EmitContext ec, IList<HoistedParameter> hoisted)
+               protected override void EmitHoistedParameters (EmitContext ec, List<HoistedParameter> hoisted)
                {
                        base.EmitHoistedParameters (ec, hoisted);
                        base.EmitHoistedParameters (ec, hoisted_params_copy);
                }
-
-               protected override string GetVariableMangledName (LocalVariable local_info)
-               {
-                       if (local_info.IsCompilerGenerated)
-                               return base.GetVariableMangledName (local_info);
-
-                       return "<" + local_info.Name + ">__" + local_name_idx++.ToString ("X");
-               }
        }
 
        public class StateMachineMethod : Method
@@ -702,8 +698,6 @@ namespace Mono.CSharp
 
                protected override Expression DoResolve (ResolveContext ec)
                {
-                       storey = (StateMachine) block.Parent.ParametersBlock.AnonymousMethodStorey;
-
                        var ctx = CreateBlockContext (ec);
 
                        Block.Resolve (ctx);
@@ -730,7 +724,7 @@ namespace Mono.CSharp
                public override void Emit (EmitContext ec)
                {
                        //
-                       // Load Iterator storey instance
+                       // Load state machine instance
                        //
                        storey.Instance.Emit (ec);
                }
@@ -749,11 +743,7 @@ namespace Mono.CSharp
 
                        iterator_body_end = ec.DefineLabel ();
 
-                       if (ec.EmitAccurateDebugInfo && ec.Mark (Block.Original.StartLocation)) {
-                               ec.Emit (OpCodes.Nop);
-                       }
-
-                       block.Emit (ec);
+                       block.EmitEmbedded (ec);
 
                        ec.MarkLabel (iterator_body_end);
 
@@ -816,11 +806,7 @@ namespace Mono.CSharp
 
                        iterator_body_end = ec.DefineLabel ();
 
-                       if (ec.EmitAccurateDebugInfo && ec.Mark (Block.Original.StartLocation)) {
-                               ec.Emit (OpCodes.Nop);
-                       }
-
-                       block.Emit (ec);
+                       block.EmitEmbedded (ec);
 
                        ec.MarkLabel (iterator_body_end);
 
@@ -905,16 +891,51 @@ namespace Mono.CSharp
                                ec.Emit (OpCodes.Stloc, skip_finally);
                        }
                }
+
+               public void SetStateMachine (StateMachine stateMachine)
+               {
+                       this.storey = stateMachine;
+               }
        }
 
        //
-       // Iterators are implemented as hidden anonymous block
+       // Iterators are implemented as state machine blocks
        //
        public class Iterator : StateMachineInitializer
        {
+               sealed class TryFinallyBlockProxyStatement : Statement
+               {
+                       TryFinallyBlock block;
+                       Iterator iterator;
+
+                       public TryFinallyBlockProxyStatement (Iterator iterator, TryFinallyBlock block)
+                       {
+                               this.iterator = iterator;
+                               this.block = block;
+                       }
+
+                       protected override void CloneTo (CloneContext clonectx, Statement target)
+                       {
+                               throw new NotSupportedException ();
+                       }
+
+                       protected override void DoEmit (EmitContext ec)
+                       {
+                               //
+                               // Restore redirection for any captured variables
+                               //
+                               ec.CurrentAnonymousMethod = iterator;
+
+                               using (ec.With (BuilderContext.Options.OmitDebugInfo, !ec.HasMethodSymbolBuilder)) {
+                                       block.EmitFinallyBody (ec);
+                               }
+                       }
+               }
+
                public readonly IMethodData OriginalMethod;
                public readonly bool IsEnumerable;
                public readonly TypeSpec OriginalIteratorType;
+               int finally_hosts_counter;
 
                public Iterator (ParametersBlock block, IMethodData method, TypeDefinition host, TypeSpec iterator_type, bool is_enumerable)
                        : base (block, host, host.Compiler.BuiltinTypes.Bool)
@@ -925,7 +946,9 @@ namespace Mono.CSharp
                        this.type = method.ReturnType;
                }
 
-               public Block Container {
+               #region Properties
+
+               public ToplevelBlock Container {
                        get { return OriginalMethod.Block; }
                }
 
@@ -937,6 +960,22 @@ namespace Mono.CSharp
                        get { return true; }
                }
 
+               #endregion
+
+               public Method CreateFinallyHost (TryFinallyBlock block)
+               {
+                       var method = new Method (storey, new TypeExpression (storey.Compiler.BuiltinTypes.Void, loc),
+                               Modifiers.COMPILER_GENERATED, new MemberName (CompilerGeneratedContainer.MakeName (null, null, "Finally", finally_hosts_counter++), loc),
+                               ParametersCompiled.EmptyReadOnlyParameters, null);
+
+                       method.Block = new ToplevelBlock (method.Compiler, method.ParameterInfo, loc);
+                       method.Block.IsCompilerGenerated = true;
+                       method.Block.AddStatement (new TryFinallyBlockProxyStatement (this, block));
+
+                       storey.AddMember (method);
+                       return method;
+               }
+
                public void EmitYieldBreak (EmitContext ec, bool unwind_protect)
                {
                        ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, move_next_error);
@@ -972,11 +1011,13 @@ namespace Mono.CSharp
 
                public void EmitDispose (EmitContext ec)
                {
+                       if (resume_points == null)
+                               return;
+
                        Label end = ec.DefineLabel ();
 
                        Label[] labels = null;
-                       int n_resume_points = resume_points == null ? 0 : resume_points.Count;
-                       for (int i = 0; i < n_resume_points; ++i) {
+                       for (int i = 0; i < resume_points.Count; ++i) {
                                ResumableStatement s = resume_points[i];
                                Label ret = s.PrepareForDispose (ec, end);
                                if (ret.Equals (end) && labels == null)
@@ -1089,7 +1130,7 @@ namespace Mono.CSharp
                                parent.Compiler.Report.Error (1629, method.Location, "Unsafe code may not appear in iterators");
                        }
 
-                       method.Block.WrapIntoIterator (method, parent, iterator_type, is_enumerable);
+                       method.Block = method.Block.ConvertToIterator (method, parent, iterator_type, is_enumerable);
                }
 
                static bool CheckType (TypeSpec ret, TypeContainer parent, out TypeSpec original_iterator_type, out bool is_enumerable)
index 2fba7ed4738c3129f1d2fac536922d66afc74c43..d972450fc73d19327ecd4205c66a33338a59e321 100644 (file)
@@ -191,7 +191,7 @@ namespace Mono.CSharp {
                        return Expr.CreateExpressionTree (ec);
                }
 
-               public override void Emit (EmitContext ec)
+               protected override void DoEmit (EmitContext ec)
                {
                        if (statement != null) {
                                statement.EmitStatement (ec);
@@ -203,7 +203,7 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       base.Emit (ec);
+                       base.DoEmit (ec);
                }
 
                protected override bool DoResolve (BlockContext ec)
index bb0370914bed2af3e6603091c0f9f528910a520e..bdbd57a4f7d168e9337bac99e60d757be243f1db 100644 (file)
@@ -50,7 +50,7 @@ namespace Mono.CSharp
                {
                }
 
-               public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec t, bool expl)
+               public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec t, bool expl)
                {
                        if (t.IsGenericParameter) {
                                ec.Report.Error(403, loc,
@@ -65,7 +65,7 @@ namespace Mono.CSharp
                                return;
                        }
 
-                       base.Error_ValueCannotBeConverted (ec, loc, t, expl);
+                       base.Error_ValueCannotBeConverted (ec, t, expl);
                }
 
                public override string GetValueAsLiteral ()
@@ -253,7 +253,7 @@ namespace Mono.CSharp
                {
                }
 
-               public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl)
+               public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl)
                {
                        if (target.BuiltinType == BuiltinTypeSpec.Type.Float) {
                                Error_664 (ec, loc, "float", "f");
@@ -265,7 +265,7 @@ namespace Mono.CSharp
                                return;
                        }
 
-                       base.Error_ValueCannotBeConverted (ec, loc, target, expl);
+                       base.Error_ValueCannotBeConverted (ec, target, expl);
                }
 
                static void Error_664 (ResolveContext ec, Location loc, string type, string suffix)
index 3b608feaaaafc90814543c536d40d88bc418232e..b00f3f0bc070abffdff2e929894e7c3ac819c229 100644 (file)
@@ -1196,7 +1196,7 @@ namespace Mono.CSharp {
                                                Report.Error (1983, Location, "The return type of an async method must be void, Task, or Task<T>");
                                        }
 
-                                       AsyncInitializer.Create (this, block, parameters, Parent.PartialContainer, ReturnType, Location);
+                                       block = (ToplevelBlock) block.ConvertToAsyncTask (this, Parent.PartialContainer, parameters, ReturnType, Location);
                                        ModFlags |= Modifiers.DEBUGGER_HIDDEN;
                                }
                        }
index e0292b6c5f4627fd020537db7612b269caf81970..365f876f0aa4f318f21cd34f114b7a1703dd8d66 100644 (file)
@@ -235,7 +235,7 @@ namespace Mono.CSharp {
 
                TemporaryVariableReference expr_tree_variable;
 
-               HoistedVariable hoisted_variant;
+               HoistedParameter hoisted_variant;
 
                public Parameter (FullNamedExpression type, string name, Modifier mod, Attributes attrs, Location loc)
                {
@@ -549,7 +549,7 @@ namespace Mono.CSharp {
                //
                // Hoisted parameter variant
                //
-               public HoistedVariable HoistedVariant {
+               public HoistedParameter HoistedVariant {
                        get {
                                return hoisted_variant;
                        }
index cc06e38f472bcb237794868fc74f854876a337dc..3620c429f3c1ca5839d37f6823065d715fe5bda0 100644 (file)
@@ -922,7 +922,7 @@ namespace Mono.CSharp {
                        if (expr == null)
                                return false;
 
-                       if (expr.Type != block_return_type) {
+                       if (expr.Type != block_return_type && expr.Type != InternalType.ErrorType) {
                                expr = Convert.ImplicitConversionRequired (ec, expr, block_return_type, loc);
 
                                if (expr == null) {
@@ -1215,9 +1215,9 @@ namespace Mono.CSharp {
                                res = c;
                        } else {
                                TypeSpec type = ec.Switch.SwitchType;
-                               res = c.TryReduce (ec, type, c.Location);
+                               res = c.TryReduce (ec, type);
                                if (res == null) {
-                                       c.Error_ValueCannotBeConverted (ec, loc, type, true);
+                                       c.Error_ValueCannotBeConverted (ec, type, true);
                                        return false;
                                }
 
@@ -1681,7 +1681,7 @@ namespace Mono.CSharp {
                                if (TypeSpec.IsReferenceType (li.Type))
                                        initializer.Error_ConstantCanBeInitializedWithNullOnly (bc, li.Type, initializer.Location, li.Name);
                                else
-                                       initializer.Error_ValueCannotBeConverted (bc, initializer.Location, li.Type, false);
+                                       initializer.Error_ValueCannotBeConverted (bc, li.Type, false);
 
                                return null;
                        }
@@ -2423,14 +2423,22 @@ namespace Mono.CSharp {
                }
 
                public bool HasCapturedThis {
-                       set { flags = value ? flags | Flags.HasCapturedThis : flags & ~Flags.HasCapturedThis; }
+                       set {
+                               flags = value ? flags | Flags.HasCapturedThis : flags & ~Flags.HasCapturedThis;
+                       }
                        get {
                                return (flags & Flags.HasCapturedThis) != 0;
                        }
                }
 
+               //
+               // Used to indicate that the block has reference to parent
+               // block and cannot be made static when defining anonymous method
+               //
                public bool HasCapturedVariable {
-                       set { flags = value ? flags | Flags.HasCapturedVariable : flags & ~Flags.HasCapturedVariable; }
+                       set {
+                               flags = value ? flags | Flags.HasCapturedVariable : flags & ~Flags.HasCapturedVariable;
+                       }
                        get {
                                return (flags & Flags.HasCapturedVariable) != 0;
                        }
@@ -2457,11 +2465,12 @@ namespace Mono.CSharp {
                                return ec.CurrentAnonymousMethod.Storey;
 
                        //
-                       // When referencing a variable in parent iterator/async storey
-                       // from nested anonymous method
+                       // When referencing a variable inside iterator where all
+                       // 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) {
@@ -2479,7 +2488,7 @@ namespace Mono.CSharp {
                public override void Emit (EmitContext ec)
                {
                        if (am_storey != null) {
-                               DefineAnonymousStorey (ec);
+                               DefineStoreyContainer (ec, am_storey);
                                am_storey.EmitStoreyInstantiation (ec, this);
                        }
 
@@ -2503,57 +2512,112 @@ namespace Mono.CSharp {
                        }
                }
 
-               void DefineAnonymousStorey (EmitContext ec)
+               protected void DefineStoreyContainer (EmitContext ec, AnonymousMethodStorey storey)
                {
+                       if (ec.CurrentAnonymousMethod != null && ec.CurrentAnonymousMethod.Storey != null) {
+                               storey.SetNestedStoryParent (ec.CurrentAnonymousMethod.Storey);
+                               storey.Mutator = ec.CurrentAnonymousMethod.Storey.Mutator;
+                       }
+
                        //
                        // Creates anonymous method storey
                        //
-                       if (ec.CurrentAnonymousMethod != null && ec.CurrentAnonymousMethod.Storey != null) {
+                       storey.CreateContainer ();
+                       storey.DefineContainer ();
+
+                       if (Original.Explicit.HasCapturedThis && Original.ParametersBlock.TopBlock.ThisReferencesFromChildrenBlock != null) {
+
+                               //
+                               // Only first storey in path will hold this reference. All children blocks will
+                               // reference it indirectly using $ref field
+                               //
+                               for (Block b = Original.Explicit.Parent; b != null; b = b.Parent) {
+                                       var s = b.Explicit.AnonymousMethodStorey;
+                                       if (s != null) {
+                                               storey.HoistedThis = s.HoistedThis;
+                                               break;
+                                       }
+                               }
+
                                //
-                               // Creates parent storey reference when hoisted this is accessible
+                               // We are the first storey on path and this has to be hoisted
                                //
-                               if (am_storey.OriginalSourceBlock.Explicit.HasCapturedThis) {
-                                       ExplicitBlock parent = am_storey.OriginalSourceBlock.Explicit.Parent.Explicit;
+                               if (storey.HoistedThis == null) {
+                                       foreach (ExplicitBlock ref_block in Original.ParametersBlock.TopBlock.ThisReferencesFromChildrenBlock) {
+                                               //
+                                               // ThisReferencesFromChildrenBlock holds all reference even if they
+                                               // are not on this path. It saves some memory otherwise it'd have to
+                                               // be in every explicit block. We run this check to see if the reference
+                                               // is valid for this storey
+                                               //
+                                               Block block_on_path = ref_block;
+                                               for (; block_on_path != null && block_on_path != Original; block_on_path = block_on_path.Parent);
 
-                                       //
-                                       // Hoisted this exists in top-level parent storey only
-                                       //
-                                       while (parent.am_storey == null || parent.am_storey.Parent is AnonymousMethodStorey)
-                                               parent = parent.Parent.Explicit;
+                                               if (block_on_path == null)
+                                                       continue;
 
-                                       am_storey.AddParentStoreyReference (ec, parent.am_storey);
-                               }
+                                               if (storey.HoistedThis == null)
+                                                       storey.AddCapturedThisField (ec);
 
-                               am_storey.SetNestedStoryParent (ec.CurrentAnonymousMethod.Storey);
+                                               for (ExplicitBlock b = ref_block; b.AnonymousMethodStorey != storey; b = b.Parent.Explicit) {
+                                                       if (b.AnonymousMethodStorey != null) {
+                                                               b.AnonymousMethodStorey.AddParentStoreyReference (ec, storey);
+                                                               b.AnonymousMethodStorey.HoistedThis = storey.HoistedThis;
 
-                               // TODO MemberCache: Review
-                               am_storey.Mutator = ec.CurrentAnonymousMethod.Storey.Mutator;
-                       }
+                                                               //
+                                                               // Stop propagation inside same top block
+                                                               //
+                                                               if (b.ParametersBlock == ParametersBlock.Original)
+                                                                       break;
+
+                                                               b = b.ParametersBlock;
+                                                       }
+
+                                                       var pb = b as ParametersBlock;
+                                                       if (pb != null && pb.StateMachine != null) {
+                                                               if (pb.StateMachine == storey)
+                                                                       break;
+
+                                                               pb.StateMachine.AddParentStoreyReference (ec, storey);
+                                                       }
 
-                       am_storey.CreateContainer ();
-                       am_storey.DefineContainer ();
+                                                       b.HasCapturedVariable = true;
+                                               }
+                                       }
+                               }
+                       }
 
-                       var ref_blocks = am_storey.ReferencesFromChildrenBlock;
+                       var ref_blocks = storey.ReferencesFromChildrenBlock;
                        if (ref_blocks != null) {
                                foreach (ExplicitBlock ref_block in ref_blocks) {
-                                       for (ExplicitBlock b = ref_block.Explicit; b.am_storey != am_storey; b = b.Parent.Explicit) {
-                                               if (b.am_storey != null) {
-                                                       b.am_storey.AddParentStoreyReference (ec, am_storey);
+                                       for (ExplicitBlock b = ref_block; b.AnonymousMethodStorey != storey; b = b.Parent.Explicit) {
+                                               if (b.AnonymousMethodStorey != null) {
+                                                       b.AnonymousMethodStorey.AddParentStoreyReference (ec, storey);
 
+                                                       //
                                                        // Stop propagation inside same top block
-                                                       if (b.ParametersBlock.Original == ParametersBlock.Original)
+                                                       //
+                                                       if (b.ParametersBlock == ParametersBlock.Original)
                                                                break;
 
                                                        b = b.ParametersBlock;
                                                }
 
+                                               var pb = b as ParametersBlock;
+                                               if (pb != null && pb.StateMachine != null) {
+                                                       if (pb.StateMachine == storey)
+                                                               break;
+
+                                                       pb.StateMachine.AddParentStoreyReference (ec, storey);
+                                               }
+
                                                b.HasCapturedVariable = true;
                                        }
                                }
                        }
 
-                       am_storey.Define ();
-                       am_storey.Parent.PartialContainer.AddCompilerGeneratedClass (am_storey);
+                       storey.Define ();
+                       storey.Parent.PartialContainer.AddCompilerGeneratedClass (storey);
                }
 
                public void RegisterAsyncAwait ()
@@ -2562,7 +2626,7 @@ namespace Mono.CSharp {
                        while ((block.flags & Flags.AwaitBlock) == 0) {
                                block.flags |= Flags.AwaitBlock;
 
-                               if (block.Parent == null)
+                               if (block is ParametersBlock)
                                        return;
 
                                block = block.Parent.Explicit;
@@ -2611,7 +2675,13 @@ namespace Mono.CSharp {
 
                        #region Properties
 
-                       public Block Block {
+                       public ParametersBlock Block {
+                               get {
+                                       return block;
+                               }
+                       }
+
+                       Block INamedBlockVariable.Block {
                                get {
                                        return block;
                                }
@@ -2714,6 +2784,7 @@ namespace Mono.CSharp {
                bool resolved;
                protected bool unreachable;
                protected ToplevelBlock top_block;
+               protected StateMachine state_machine;
 
                public ParametersBlock (Block parent, ParametersCompiled parameters, Location start)
                        : base (parent, 0, start, start)
@@ -2753,6 +2824,7 @@ namespace Mono.CSharp {
                        this.resolved = true;
                        this.unreachable = source.unreachable;
                        this.am_storey = source.am_storey;
+                       this.state_machine = source.state_machine;
 
                        ParametersBlock = this;
 
@@ -2792,6 +2864,12 @@ namespace Mono.CSharp {
                        }
                }
 
+               public StateMachine StateMachine {
+                       get {
+                               return state_machine;
+                       }
+               }
+
                public ToplevelBlock TopBlock {
                        get {
                                return top_block;
@@ -2847,6 +2925,26 @@ namespace Mono.CSharp {
                        return base.CreateExpressionTree (ec);
                }
 
+               public override void Emit (EmitContext ec)
+               {
+                       if (state_machine != null && state_machine.OriginalSourceBlock != this) {
+                               DefineStoreyContainer (ec, state_machine);
+                               state_machine.EmitStoreyInstantiation (ec, this);
+                       }
+
+                       base.Emit (ec);
+               }
+
+               public void EmitEmbedded (EmitContext ec)
+               {
+                       if (state_machine != null && state_machine.OriginalSourceBlock != this) {
+                               DefineStoreyContainer (ec, state_machine);
+                               state_machine.EmitStoreyInstantiation (ec, this);
+                       }
+
+                       base.Emit (ec);
+               }
+
                public ParameterInfo GetParameterInfo (Parameter p)
                {
                        for (int i = 0; i < parameters.Count; ++i) {
@@ -2969,37 +3067,71 @@ namespace Mono.CSharp {
                        }
                }
 
-               public void WrapIntoIterator (IMethodData method, TypeDefinition host, TypeSpec iterator_type, bool is_enumerable)
+               public ToplevelBlock ConvertToIterator (IMethodData method, TypeDefinition host, TypeSpec iterator_type, bool is_enumerable)
                {
-                       ParametersBlock pb = new ParametersBlock (this, ParametersCompiled.EmptyReadOnlyParameters, Location.Null);
-                       pb.statements = statements;
-                       pb.Original = this;
+                       var iterator = new Iterator (this, method, host, iterator_type, is_enumerable);
+                       var stateMachine = new IteratorStorey (iterator);
 
-                       var iterator = new Iterator (pb, method, host, iterator_type, is_enumerable);
-                       am_storey = new IteratorStorey (iterator);
+                       state_machine = stateMachine;
+                       iterator.SetStateMachine (stateMachine);
 
-                       statements = new List<Statement> (1);
-                       AddStatement (new Return (iterator, iterator.Location));
-                       flags &= ~Flags.YieldBlock;
-                       IsCompilerGenerated = true;
+                       var tlb = new ToplevelBlock (host.Compiler, Parameters, Location.Null);
+                       tlb.Original = this;
+                       tlb.IsCompilerGenerated = true;
+                       tlb.state_machine = stateMachine;
+                       tlb.AddStatement (new Return (iterator, iterator.Location));
+                       return tlb;
                }
 
-               public void WrapIntoAsyncTask (IMemberContext context, TypeDefinition host, TypeSpec returnType)
+               public ParametersBlock ConvertToAsyncTask (IMemberContext context, TypeDefinition host, ParametersCompiled parameters, TypeSpec returnType, Location loc)
                {
-                       ParametersBlock pb = new ParametersBlock (this, ParametersCompiled.EmptyReadOnlyParameters, Location.Null);
-                       pb.statements = statements;
-                       pb.Original = this;
+                       for (int i = 0; i < parameters.Count; i++) {
+                               Parameter p = parameters[i];
+                               Parameter.Modifier mod = p.ModFlags;
+                               if ((mod & Parameter.Modifier.RefOutMask) != 0) {
+                                       host.Compiler.Report.Error (1988, p.Location,
+                                               "Async methods cannot have ref or out parameters");
+                                       return this;
+                               }
+
+                               if (p is ArglistParameter) {
+                                       host.Compiler.Report.Error (4006, p.Location,
+                                               "__arglist is not allowed in parameter list of async methods");
+                                       return this;
+                               }
+
+                               if (parameters.Types[i].IsPointer) {
+                                       host.Compiler.Report.Error (4005, p.Location,
+                                               "Async methods cannot have unsafe parameters");
+                                       return this;
+                               }
+                       }
+
+                       if (!HasAwait) {
+                               host.Compiler.Report.Warning (1998, 1, loc,
+                                       "Async block lacks `await' operator and will run synchronously");
+                       }
 
                        var block_type = host.Module.Compiler.BuiltinTypes.Void;
-                       var initializer = new AsyncInitializer (pb, host, block_type);
+                       var initializer = new AsyncInitializer (this, host, block_type);
                        initializer.Type = block_type;
 
-                       am_storey = new AsyncTaskStorey (context, initializer, returnType);
+                       var stateMachine = new AsyncTaskStorey (this, context, initializer, returnType);
 
-                       statements = new List<Statement> (1);
-                       AddStatement (new StatementExpression (initializer));
-                       flags &= ~Flags.AwaitBlock;
-                       IsCompilerGenerated = true;
+                       state_machine = stateMachine;
+                       initializer.SetStateMachine (stateMachine);
+
+                       var b = this is ToplevelBlock ?
+                               new ToplevelBlock (host.Compiler, Parameters, Location.Null) :
+                               new ParametersBlock (Parent, parameters, Location.Null) {
+                                       IsAsync = true,
+                               };
+
+                       b.Original = this;
+                       b.IsCompilerGenerated = true;
+                       b.state_machine = stateMachine;
+                       b.AddStatement (new StatementExpression (initializer));
+                       return b;
                }
        }
 
@@ -3013,11 +3145,7 @@ namespace Mono.CSharp {
                Dictionary<string, object> names;
                Dictionary<string, object> labels;
 
-               public HoistedVariable HoistedThisVariable;
-
-               public Report Report {
-                       get { return compiler.Report; }
-               }
+               List<ExplicitBlock> this_references;
 
                public ToplevelBlock (CompilerContext ctx, Location loc)
                        : this (ctx, ParametersCompiled.EmptyReadOnlyParameters, loc)
@@ -3054,6 +3182,31 @@ namespace Mono.CSharp {
                        }
                }
 
+               public Report Report {
+                       get {
+                               return compiler.Report;
+                       }
+               }
+
+               //
+               // Used by anonymous blocks to track references of `this' variable
+               //
+               public List<ExplicitBlock> ThisReferencesFromChildrenBlock {
+                       get {
+                               return this_references;
+                       }
+               }
+
+               //
+               // Returns the "this" instance variable of this block.
+               // See AddThisVariable() for more information.
+               //
+               public LocalVariable ThisVariable {
+                       get {
+                               return this_variable;
+                       }
+               }
+
                public void AddLocalName (string name, INamedBlockVariable li, bool ignoreChildrenBlocks)
                {
                        if (names == null)
@@ -3174,6 +3327,20 @@ namespace Mono.CSharp {
                        existing_list.Add (label);
                }
 
+               public void AddThisReferenceFromChildrenBlock (ExplicitBlock block)
+               {
+                       if (this_references == null)
+                               this_references = new List<ExplicitBlock> ();
+
+                       if (!this_references.Contains (block))
+                               this_references.Add (block);
+               }
+
+               public void RemoveThisReferenceFromChildrenBlock (ExplicitBlock block)
+               {
+                       this_references.Remove (block);
+               }
+
                //
                // Creates an arguments set from all parameters, useful for method proxy calls
                //
@@ -3284,14 +3451,6 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               // <summary>
-               //   Returns the "this" instance variable of this block.
-               //   See AddThisVariable() for more information.
-               // </summary>
-               public LocalVariable ThisVariable {
-                       get { return this_variable; }
-               }
-
                // <summary>
                //   This is used by non-static `struct' constructors which do not have an
                //   initializer - in this case, the constructor must initialize all of the
@@ -4333,6 +4492,7 @@ namespace Mono.CSharp {
                protected Statement stmt;
                Label dispose_try_block;
                bool prepared_for_dispose, emitted_dispose;
+               Method finally_host;
 
                protected TryFinallyBlock (Statement stmt, Location loc)
                        : base (loc)
@@ -4351,7 +4511,7 @@ namespace Mono.CSharp {
                #endregion
 
                protected abstract void EmitTryBody (EmitContext ec);
-               protected abstract void EmitFinallyBody (EmitContext ec);
+               public abstract void EmitFinallyBody (EmitContext ec);
 
                public override Label PrepareForDispose (EmitContext ec, Label end)
                {
@@ -4379,7 +4539,14 @@ namespace Mono.CSharp {
                        }
 
                        ec.MarkLabel (start_finally);
-                       EmitFinallyBody (ec);
+
+                       if (finally_host != null) {
+                               var ce = new CallEmitter ();
+                               ce.InstanceExpression = new CompilerGeneratedThis (ec.CurrentType, loc);
+                               ce.EmitPredefined (ec, finally_host.Spec, new Arguments (0));
+                       } else {
+                               EmitFinallyBody (ec);
+                       }
 
                        ec.EndExceptionBlock ();
                }
@@ -4423,12 +4590,10 @@ namespace Mono.CSharp {
                                bool emit_dispatcher = j < labels.Length;
 
                                if (emit_dispatcher) {
-                                       //SymbolWriter.StartIteratorDispatcher (ec.ig);
                                        ec.Emit (OpCodes.Ldloc, pc);
                                        ec.EmitInt (first_resume_pc);
                                        ec.Emit (OpCodes.Sub);
                                        ec.Emit (OpCodes.Switch, labels);
-                                       //SymbolWriter.EndIteratorDispatcher (ec.ig);
                                }
 
                                foreach (ResumableStatement s in resume_points)
@@ -4439,10 +4604,34 @@ namespace Mono.CSharp {
 
                        ec.BeginFinallyBlock ();
 
-                       EmitFinallyBody (ec);
+                       if (finally_host != null) {
+                               var ce = new CallEmitter ();
+                               ce.InstanceExpression = new CompilerGeneratedThis (ec.CurrentType, loc);
+                               ce.EmitPredefined (ec, finally_host.Spec, new Arguments (0));
+                       } else {
+                               EmitFinallyBody (ec);
+                       }
 
                        ec.EndExceptionBlock ();
                }
+
+               public override bool Resolve (BlockContext bc)
+               {
+                       //
+                       // Finally block inside iterator is called from MoveNext and
+                       // Dispose methods that means we need to lift the block into
+                       // newly created host method to emit the body only once. The
+                       // original block then simply calls the newly generated method.
+                       //
+                       if (bc.CurrentIterator != null && !bc.IsInProbingMode) {
+                               var b = stmt as Block;
+                               if (b != null && b.Explicit.HasYield) {
+                                       finally_host = bc.CurrentIterator.CreateFinallyHost (this);
+                               }
+                       }
+
+                       return base.Resolve (bc);
+               }
        }
 
        //
@@ -4631,7 +4820,7 @@ namespace Mono.CSharp {
                        Statement.Emit (ec);
                }
 
-               protected override void EmitFinallyBody (EmitContext ec)
+               public override void EmitFinallyBody (EmitContext ec)
                {
                        //
                        // if (lock_taken) Monitor.Exit (expr_copy)
@@ -5225,6 +5414,7 @@ namespace Mono.CSharp {
 
                        if (ok)
                                ec.CurrentBranching.CreateSibling (fini, FlowBranching.SiblingType.Finally);
+
                        using (ec.With (ResolveContext.Options.FinallyScope, true)) {
                                if (!fini.Resolve (ec))
                                        ok = false;
@@ -5242,7 +5432,7 @@ namespace Mono.CSharp {
                        stmt.Emit (ec);
                }
 
-               protected override void EmitFinallyBody (EmitContext ec)
+               public override void EmitFinallyBody (EmitContext ec)
                {
                        fini.Emit (ec);
                }
@@ -5586,7 +5776,7 @@ namespace Mono.CSharp {
                        stmt.Emit (ec);
                }
 
-               protected override void EmitFinallyBody (EmitContext ec)
+               public override void EmitFinallyBody (EmitContext ec)
                {
                        decl.EmitDispose (ec);
                }
@@ -6229,6 +6419,7 @@ namespace Mono.CSharp {
                        target.type = type.Clone (clonectx);
                        target.expr = expr.Clone (clonectx);
                        target.body = (Block) body.Clone (clonectx);
+                       target.statement = statement.Clone (clonectx);
                }
                
                public override object Accept (StructuralVisitor visitor)
diff --git a/mcs/tests/dtest-error-04.cs b/mcs/tests/dtest-error-04.cs
new file mode 100644 (file)
index 0000000..b085558
--- /dev/null
@@ -0,0 +1,25 @@
+using System;
+using Microsoft.CSharp.RuntimeBinder;
+
+class A
+{
+       public string Value;
+}
+
+public class Test
+{
+       public static int Main ()
+       {
+               dynamic d = new A ();
+               
+               try {
+                       d.Value = (object)"value";
+                       return 1;
+               } catch (RuntimeBinderException e) {
+                       if (e.Message != "Cannot implicitly convert type `object' to `string'. An explicit conversion exists (are you missing a cast?)")
+                               return 2;
+               }
+               
+               return 0;
+       }
+}
diff --git a/mcs/tests/gtest-iter-21.cs b/mcs/tests/gtest-iter-21.cs
new file mode 100644 (file)
index 0000000..5265dd4
--- /dev/null
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+
+class C
+{
+       IEnumerable<int> Test ()
+       {
+               Console.WriteLine ("init");
+               try {
+                       yield return 1;
+               } finally {
+                       int oo = 4;
+                       Action a = () => Console.WriteLine (oo);
+               }
+               
+               yield return 2;
+       }
+
+       public static int Main ()
+       {
+               var c = new C ();
+               foreach (var a in c.Test ())
+               {
+               }
+               
+               return 0;
+       }
+}
\ No newline at end of file
diff --git a/mcs/tests/gtest-iter-22.cs b/mcs/tests/gtest-iter-22.cs
new file mode 100644 (file)
index 0000000..f3e355b
--- /dev/null
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+
+class D : IDisposable
+{
+       public void Dispose ()
+       {
+               Console.WriteLine ("dispose");
+       }
+}
+
+class C
+{
+       IEnumerable<int> Test ()
+       {
+               try {
+                       using (var d = new D ()) {
+                               Console.WriteLine (1);
+                       }
+               } finally {
+                       Console.WriteLine (2);
+               }
+
+               yield break;
+       }
+
+       public static int Main ()
+       {
+               var c = new C ();
+               foreach (var a in c.Test ()) {
+                       Console.WriteLine (a);
+               }
+
+               return 0;
+       }
+}
\ No newline at end of file
index 11cf4b70e2c20654cba3f5511e36de535c997986..92fd6914b4518969ea02a0da30d313bafaebd5a5 100644 (file)
@@ -11,7 +11,20 @@ class X {
                int b = -2147483648;
                long c = -9223372036854775808;
                sbyte d = -128;
+               
+               object o = -(2147483648);
+               if (o.GetType () != typeof (long))
+                       return 1;
 
+               o = -(uint)2147483648;
+               Console.WriteLine (o.GetType ());
+               if (o.GetType () != typeof (long))
+                       return 2;
+
+               uint ui = (1);
+               byte b1 = (int)(0x30);
+               byte b2 = (int)0x30;
+               
                return 0;
        }
 }
diff --git a/mcs/tests/test-anon-170.cs b/mcs/tests/test-anon-170.cs
new file mode 100644 (file)
index 0000000..ef239d3
--- /dev/null
@@ -0,0 +1,48 @@
+using System;
+
+public class MyClass
+{
+       Func<int> ll;
+
+       int Test (int a)
+       {
+               return 1;
+       }
+
+       public void Run ()
+       {
+               Action<int> a = l => {
+                       ll = () => l;
+               };
+
+               a (1);
+
+               Action<int> a2 = l => {
+                       ll = () => l;
+               };
+
+               a2 (2);
+       }
+
+       public void Run2 ()
+       {
+               Action<int> a = l => {
+                       ll = () => Test (l);
+               };
+
+               a (1);
+
+               Action<int> a2 = l => {
+                       ll = () => Test (l);
+               };
+
+               a2 (1);
+       }
+
+       public static void Main ()
+       {
+               var mc = new MyClass ();
+               mc.Run ();
+               mc.Run2 ();
+       }
+}
\ No newline at end of file
diff --git a/mcs/tests/test-async-29.cs b/mcs/tests/test-async-29.cs
new file mode 100644 (file)
index 0000000..5681f7a
--- /dev/null
@@ -0,0 +1,19 @@
+using System;
+using System.Threading.Tasks;
+
+class C
+{
+       static async Task<int> Test()
+       {
+               await Task.Yield();
+               await Task.Yield();
+               await Task.Yield();
+               return 1;
+       } 
+       
+       public static int Main ()
+       {
+               Test ().Wait ();
+               return 0;
+       }
+}
diff --git a/mcs/tests/test-async-30.cs b/mcs/tests/test-async-30.cs
new file mode 100644 (file)
index 0000000..4c345da
--- /dev/null
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+class C
+{
+       private IEnumerable<string> Test (string s)
+       {
+               Func<Task<string>> a = async () => await Task.FromResult(s + "a");
+               yield return a ().Result;
+       }
+       
+       private IEnumerable<string> Test2 ()
+       {
+               var s = "bb";
+               Func<Task<string>> a = async () => await Task.FromResult(s + "a");
+               yield return a ().Result;
+       }
+
+       public static int Main ()
+       {
+               var c = new C ();
+               string res = "";
+               foreach (var e in c.Test ("tt"))
+                       res += e;
+               
+               if (res != "tta")
+                       return 1;
+               
+               res = "";
+               foreach (var e in c.Test2 ())
+                       res += e;
+               
+               if (res != "bba")
+                       return 2;
+
+               return 0;
+       }
+}
diff --git a/mcs/tests/test-async-31.cs b/mcs/tests/test-async-31.cs
new file mode 100644 (file)
index 0000000..bbff8e3
--- /dev/null
@@ -0,0 +1,57 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+class C
+{
+       async Task<int> M(int v)
+       {
+               {
+                       await Task.Yield();
+                       int vv = 0;
+                       Func<int> a = () => vv;
+                       vv = 3;
+                       Func<int> a2 = () => v + vv;
+                       if (a() != vv)
+                               return 1;
+
+                       if (a2() != 58)
+                               return 2;
+               }
+               return 0;
+       }
+
+       async Task<int> M2(int v, int o)
+       {
+               await Task.Yield();
+               var xo = await Task.FromResult(v);
+               int vv = v;
+               Action a2;
+               int b = o;
+               {
+                       a2 = () => {
+                               v = 500;
+                               b = 2;
+                       };
+               }
+
+               await Task.Yield();
+               a2 ();
+               if (v != 500)
+                       return 1;
+
+               return 0;
+       }
+       
+       public static int Main()
+       {
+               var c = new C();
+               if (c.M(55).Result != 0)
+                       return 1;
+
+               if (c.M2(55, 22).Result != 0)
+                       return 2;
+
+               return 0;
+       }
+}
index e84a56a79f9e7e59278032ce01a1ef11e29c6c54..d9bdcf2973133cde08386dda7955ec36521c4e38 100644 (file)
@@ -54,9 +54,7 @@
         <entry il="0x3d" row="14" file_ref="1" hidden="false" />
       </sequencepoints>
       <locals />
-      <scopes>
-        <entry index="0" start="0x22" end="0x3d" />
-      </scopes>
+      <scopes />
     </method>
     <method token="0x600000a">
       <sequencepoints />
@@ -99,9 +97,7 @@
         <entry il="0x13" row="18" file_ref="1" hidden="false" />
       </sequencepoints>
       <locals />
-      <scopes>
-        <entry index="0" start="0x13" end="0x18" />
-      </scopes>
+      <scopes />
     </method>
     <method token="0x6000012">
       <sequencepoints />
index d0f0b1101f4bd91bd1bcb5277a67c0543ac7979e..b1f9f78f9fd4812331c4c9447560dda24c0746c5 100644 (file)
@@ -62,7 +62,9 @@
       <scopes />
     </method>
     <method token="0x6000007">
-      <sequencepoints />
+      <sequencepoints>
+        <entry il="0x0" row="13" file_ref="1" hidden="false" />
+      </sequencepoints>
       <locals />
       <scopes />
     </method>
index a54299513b23de12663332b641113edac1442ba2..ae145805f9210a277fd98ac950cafb6b38cb4806 100644 (file)
       <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>
-        <entry index="0" start="0x22" end="0x6e" />
-      </scopes>
+      <scopes />
     </method>
     <method token="0x600000b">
       <sequencepoints />
       <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>
-        <entry index="0" start="0x22" end="0x74" />
-      </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>
-        <entry index="0" start="0x22" end="0x4a1" />
-      </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-debug-21-ref.xml b/mcs/tests/test-debug-21-ref.xml
new file mode 100644 (file)
index 0000000..ce4fbe3
--- /dev/null
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8"?>
+<symbols>
+  <files>
+    <file id="1" name="test-debug-21.cs" checksum="4d61ccab0e08defc5c9c97012b30aa70" />
+  </files>
+  <methods>
+    <method token="0x6000001">
+      <sequencepoints />
+      <locals />
+      <scopes />
+    </method>
+    <method token="0x6000002">
+      <sequencepoints>
+        <entry il="0x0" row="22" file_ref="1" hidden="false" />
+        <entry il="0x1" row="23" file_ref="1" hidden="false" />
+      </sequencepoints>
+      <locals />
+      <scopes />
+    </method>
+    <method token="0x6000003">
+      <sequencepoints />
+      <locals />
+      <scopes />
+    </method>
+    <method token="0x6000004">
+      <sequencepoints />
+      <locals />
+      <scopes />
+    </method>
+    <method token="0x6000005">
+      <sequencepoints />
+      <locals />
+      <scopes />
+    </method>
+    <method token="0x6000006">
+      <sequencepoints />
+      <locals />
+      <scopes />
+    </method>
+    <method token="0x6000007">
+      <sequencepoints />
+      <locals />
+      <scopes />
+    </method>
+    <method token="0x6000008">
+      <sequencepoints>
+        <entry il="0x0" row="14" file_ref="1" hidden="false" />
+        <entry il="0x1" row="15" file_ref="1" hidden="false" />
+        <entry il="0xb" row="16" file_ref="1" hidden="false" />
+      </sequencepoints>
+      <locals />
+      <scopes>
+        <entry index="0" start="0x1" end="0xb" />
+      </scopes>
+    </method>
+    <method token="0x6000009">
+      <sequencepoints>
+        <entry il="0x27" row="7" file_ref="1" hidden="false" />
+        <entry il="0x28" row="8" file_ref="1" hidden="false" />
+        <entry il="0x32" row="9" file_ref="1" hidden="false" />
+        <entry il="0x41" row="10" file_ref="1" hidden="false" />
+        <entry il="0x42" row="11" file_ref="1" hidden="false" />
+        <entry il="0x5f" row="12" file_ref="1" hidden="false" />
+        <entry il="0x70" row="18" file_ref="1" hidden="false" />
+        <entry il="0x8b" row="19" file_ref="1" hidden="false" />
+      </sequencepoints>
+      <locals />
+      <scopes>
+        <entry index="0" start="0x42" end="0x5f" />
+      </scopes>
+    </method>
+    <method token="0x600000a">
+      <sequencepoints />
+      <locals />
+      <scopes />
+    </method>
+    <method token="0x600000b">
+      <sequencepoints />
+      <locals />
+      <scopes />
+    </method>
+    <method token="0x600000c">
+      <sequencepoints />
+      <locals />
+      <scopes />
+    </method>
+  </methods>
+</symbols>
\ No newline at end of file
diff --git a/mcs/tests/test-debug-21.cs b/mcs/tests/test-debug-21.cs
new file mode 100644 (file)
index 0000000..76727b5
--- /dev/null
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+
+class C
+{
+       IEnumerable<int> Test ()
+       {
+               Console.WriteLine ("init");
+               try
+               {
+                       yield return 1;
+               }
+               finally
+               {
+                       Console.WriteLine ("aa");
+               }
+               
+               yield return 2;
+       }
+
+       public static void Main ()
+       {
+       }
+}
\ No newline at end of file
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 4cd01da83bd2652f992a2a929731ab2f54ffef07..33a35dd5736eb5d869b02fa15fc42fb5fc423ad4 100644 (file)
       </method>
     </type>
   </test>
+  <test name="dtest-error-04.cs">
+    <type name="A">
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="Test">
+      <method name="Int32 Main()" attrs="150">
+        <size>153</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="dtest-etree-01.cs">
     <type name="C">
       <method name="Void Conv1(System.Linq.Expressions.Expression`1[System.Func`2[System.Object,System.Object]])" attrs="145">
         <size>26</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>15</size>
+        <size>1</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
         <size>26</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>15</size>
+        <size>1</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
         <size>26</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>15</size>
+        <size>1</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
         <size>80</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>15</size>
+        <size>1</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
         <size>26</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>15</size>
+        <size>1</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
         <size>26</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>15</size>
+        <size>1</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
         <size>26</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>15</size>
+        <size>1</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
         <size>26</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>15</size>
+        <size>1</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
         <size>49</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>15</size>
+        <size>1</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
         <size>26</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>15</size>
+        <size>1</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
         <size>26</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>15</size>
+        <size>1</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
         <size>49</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>15</size>
+        <size>1</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
         <size>26</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>15</size>
+        <size>1</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
         <size>26</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>15</size>
+        <size>1</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
         <size>26</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>15</size>
+        <size>1</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
         <size>26</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>15</size>
+        <size>1</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
         <size>26</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>15</size>
+        <size>1</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
         <size>26</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>15</size>
+        <size>1</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
         <size>26</size>
       </method>
       <method name="Boolean MoveNext()" attrs="486">
-        <size>117</size>
+        <size>115</size>
       </method>
       <method name="Void Dispose()" attrs="486">
         <size>53</size>
         <size>7</size>
       </method>
     </type>
+    <type name="TestGoto+&lt;setX&gt;c__Iterator0">
+      <method name="Void &lt;&gt;__Finally0()" attrs="129">
+        <size>9</size>
+      </method>
+    </type>
   </test>
   <test name="gtest-382.cs">
     <type name="C">
         <size>26</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>15</size>
+        <size>1</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
         <size>38</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>15</size>
+        <size>1</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
         <size>37</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>15</size>
+        <size>1</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
       </method>
     </type>
   </test>
+  <test name="gtest-iter-21.cs">
+    <type name="C">
+      <method name="IEnumerable`1 Test()" attrs="129">
+        <size>23</size>
+      </method>
+      <method name="Int32 Main()" attrs="150">
+        <size>72</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="C+&lt;Test&gt;c__Iterator0">
+      <method name="Int32 System.Collections.Generic.IEnumerator&lt;int&gt;.get_Current()" attrs="2529">
+        <size>14</size>
+      </method>
+      <method name="System.Object System.Collections.IEnumerator.get_Current()" attrs="2529">
+        <size>19</size>
+      </method>
+      <method name="IEnumerator System.Collections.IEnumerable.GetEnumerator()" attrs="481">
+        <size>14</size>
+      </method>
+      <method name="IEnumerator`1 System.Collections.Generic.IEnumerable&lt;int&gt;.GetEnumerator()" attrs="481">
+        <size>26</size>
+      </method>
+      <method name="Void &lt;&gt;__Finally0()" attrs="129">
+        <size>23</size>
+      </method>
+      <method name="Boolean MoveNext()" attrs="486">
+        <size>150</size>
+      </method>
+      <method name="Void Dispose()" attrs="486">
+        <size>57</size>
+      </method>
+      <method name="Void Reset()" attrs="486">
+        <size>6</size>
+      </method>
+      <method name="Void &lt;&gt;m__0()" attrs="131">
+        <size>12</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
+  <test name="gtest-iter-22.cs">
+    <type name="D">
+      <method name="Void Dispose()" attrs="486">
+        <size>12</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="C">
+      <method name="IEnumerable`1 Test()" attrs="129">
+        <size>23</size>
+      </method>
+      <method name="Int32 Main()" attrs="150">
+        <size>78</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="C+&lt;Test&gt;c__Iterator0">
+      <method name="Int32 System.Collections.Generic.IEnumerator&lt;int&gt;.get_Current()" attrs="2529">
+        <size>14</size>
+      </method>
+      <method name="System.Object System.Collections.IEnumerator.get_Current()" attrs="2529">
+        <size>19</size>
+      </method>
+      <method name="IEnumerator System.Collections.IEnumerable.GetEnumerator()" attrs="481">
+        <size>14</size>
+      </method>
+      <method name="IEnumerator`1 System.Collections.Generic.IEnumerable&lt;int&gt;.GetEnumerator()" attrs="481">
+        <size>26</size>
+      </method>
+      <method name="Boolean MoveNext()" attrs="486">
+        <size>74</size>
+      </method>
+      <method name="Void Dispose()" attrs="486">
+        <size>1</size>
+      </method>
+      <method name="Void Reset()" attrs="486">
+        <size>6</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="gtest-lambda-01.cs">
     <type name="IntFunc">
       <method name="Int32 Invoke(Int32)" attrs="454">
   <test name="test-129.cs">
     <type name="X">
       <method name="Int32 Main()" attrs="145">
-        <size>37</size>
+        <size>156</size>
       </method>
       <method name="Void .ctor()" attrs="6278">
         <size>7</size>
   <test name="test-anon-10.cs">
     <type name="S">
       <method name="Void Test()" attrs="134">
-        <size>108</size>
+        <size>101</size>
       </method>
       <method name="Int32 Main()" attrs="145">
         <size>79</size>
     </type>
     <type name="S+&lt;Test&gt;c__AnonStorey1">
       <method name="Void &lt;&gt;m__0()" attrs="131">
-        <size>77</size>
+        <size>87</size>
       </method>
       <method name="Void .ctor()" attrs="6278">
         <size>7</size>
         <size>40</size>
       </method>
       <method name="Boolean MoveNext()" attrs="486">
-        <size>197</size>
+        <size>181</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>73</size>
+        <size>57</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
       <method name="Void .ctor()" attrs="6278">
         <size>7</size>
       </method>
+      <method name="Void &lt;&gt;__Finally0()" attrs="129">
+        <size>23</size>
+      </method>
     </type>
   </test>
   <test name="test-anon-108.cs">
     </type>
     <type name="T+&lt;GetD&gt;c__AnonStorey2`1[T]">
       <method name="Void &lt;&gt;m__0(System.Object)" attrs="131">
-        <size>82</size>
+        <size>75</size>
       </method>
       <method name="Void .ctor()" attrs="6278">
         <size>7</size>
       </method>
     </type>
   </test>
+  <test name="test-anon-170.cs">
+    <type name="MyClass">
+      <method name="Int32 Test(Int32)" attrs="129">
+        <size>10</size>
+      </method>
+      <method name="Void Run()" attrs="134">
+        <size>42</size>
+      </method>
+      <method name="Void Run2()" attrs="134">
+        <size>42</size>
+      </method>
+      <method name="Void Main()" attrs="150">
+        <size>20</size>
+      </method>
+      <method name="Void &lt;Run&gt;m__0(Int32)" attrs="129">
+        <size>33</size>
+      </method>
+      <method name="Void &lt;Run&gt;m__1(Int32)" attrs="129">
+        <size>33</size>
+      </method>
+      <method name="Void &lt;Run2&gt;m__2(Int32)" attrs="129">
+        <size>40</size>
+      </method>
+      <method name="Void &lt;Run2&gt;m__3(Int32)" attrs="129">
+        <size>40</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="MyClass+&lt;Run&gt;c__AnonStorey0">
+      <method name="Int32 &lt;&gt;m__4()" attrs="131">
+        <size>14</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="MyClass+&lt;Run&gt;c__AnonStorey1">
+      <method name="Int32 &lt;&gt;m__5()" attrs="131">
+        <size>14</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="MyClass+&lt;Run2&gt;c__AnonStorey2">
+      <method name="Int32 &lt;&gt;m__6()" attrs="131">
+        <size>25</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="MyClass+&lt;Run2&gt;c__AnonStorey3">
+      <method name="Int32 &lt;&gt;m__7()" attrs="131">
+        <size>25</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="test-anon-18.cs">
     <type name="A">
       <method name="Void Invoke()" attrs="454">
         <size>2</size>
       </method>
       <method name="Void Test(Int32)" attrs="134">
-        <size>156</size>
+        <size>142</size>
       </method>
       <method name="Void .ctor()" attrs="6278">
         <size>7</size>
     </type>
     <type name="World+&lt;Test&gt;c__AnonStorey2">
       <method name="Void &lt;&gt;m__0()" attrs="131">
-        <size>46</size>
+        <size>51</size>
       </method>
       <method name="Void .ctor()" attrs="6278">
         <size>7</size>
         <size>2</size>
       </method>
       <method name="Void Test(Int32)" attrs="134">
-        <size>204</size>
+        <size>190</size>
       </method>
       <method name="Void .ctor()" attrs="6278">
         <size>7</size>
     </type>
     <type name="World+&lt;Test&gt;c__AnonStorey0">
       <method name="Void &lt;&gt;m__0()" attrs="131">
-        <size>64</size>
+        <size>79</size>
       </method>
       <method name="Void .ctor()" attrs="6278">
         <size>7</size>
   <test name="test-anon-61.cs">
     <type name="X">
       <method name="Int32 Test()" attrs="134">
-        <size>381</size>
+        <size>374</size>
       </method>
       <method name="Int32 Main()" attrs="150">
         <size>67</size>
     </type>
     <type name="X+&lt;Test&gt;c__AnonStorey1">
       <method name="Void &lt;&gt;m__0()" attrs="131">
-        <size>158</size>
+        <size>173</size>
       </method>
       <method name="Void .ctor()" attrs="6278">
         <size>7</size>
         <size>2</size>
       </method>
       <method name="Void TestMe()" attrs="129">
-        <size>159</size>
+        <size>152</size>
       </method>
       <method name="Boolean &lt;TestMe&gt;m__0()" attrs="145">
         <size>10</size>
     </type>
     <type name="Test+&lt;TestMe&gt;c__AnonStorey0">
       <method name="Boolean &lt;&gt;m__1()" attrs="131">
-        <size>62</size>
+        <size>67</size>
       </method>
       <method name="Boolean &lt;&gt;m__2()" attrs="131">
         <size>22</size>
   <test name="test-anon-97.cs">
     <type name="Space">
       <method name="Void Leak(Boolean, Int32)" attrs="134">
-        <size>88</size>
+        <size>81</size>
       </method>
       <method name="Void .ctor()" attrs="6278">
         <size>14</size>
     </type>
     <type name="Space+&lt;Leak&gt;c__AnonStorey0">
       <method name="Void &lt;&gt;m__0()" attrs="131">
-        <size>19</size>
+        <size>24</size>
       </method>
       <method name="Void &lt;&gt;m__1()" attrs="131">
         <size>70</size>
         <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>45</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>39</size>
+        <size>35</size>
       </method>
       <method name="Void &lt;&gt;m__1()" attrs="131">
-        <size>39</size>
+        <size>35</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.String] &lt;&gt;m__2(System.String)" attrs="131">
-        <size>52</size>
+        <size>49</size>
       </method>
       <method name="System.Threading.Tasks.Task`1[System.Decimal] &lt;&gt;m__3(Decimal)" attrs="131">
-        <size>52</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>214</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>214</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>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__async5+&lt;Main&gt;c__AnonStorey6">
+      <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__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>52</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>38</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task &lt;Main&gt;m__2(Int32)" attrs="145">
-        <size>38</size>
+        <size>33</size>
       </method>
       <method name="System.Threading.Tasks.Task &lt;Main&gt;m__3(Int32)" attrs="145">
-        <size>38</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>159</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>37</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
+        <size>38</size>
       </method>
     </type>
     <type name="AsyncTypeInference+&lt;Main&gt;c__async2">
         <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>
     </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 name="Decimal &lt;&gt;m__39()" attrs="145">
         <size>15</size>
       </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
-      </method>
     </type>
     <type name="Tester+&lt;CastTest_2&gt;c__async17">
       <method name="Void MoveNext()" attrs="486">
       <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>38</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>368</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>
       </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>
-      </method>
-      <method name="Int32 &lt;&gt;m__0()" attrs="145">
-        <size>9</size>
-      </method>
-      <method name="Void .ctor()" attrs="6278">
-        <size>7</size>
+        <size>197</size>
       </method>
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
         <size>13</size>
       </method>
+      <method name="Int32 &lt;&gt;m__0()" attrs="145">
+        <size>9</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>
+    </type>
+  </test>
+  <test name="test-async-30.cs">
+    <type name="C">
+      <method name="IEnumerable`1 Test(System.String)" attrs="129">
+        <size>37</size>
+      </method>
+      <method name="IEnumerable`1 Test2()" attrs="129">
+        <size>23</size>
+      </method>
+      <method name="Int32 Main()" attrs="150">
+        <size>214</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="C+&lt;Test&gt;c__Iterator0">
+      <method name="System.String System.Collections.Generic.IEnumerator&lt;string&gt;.get_Current()" attrs="2529">
+        <size>14</size>
+      </method>
+      <method name="System.Object System.Collections.IEnumerator.get_Current()" attrs="2529">
+        <size>14</size>
+      </method>
+      <method name="IEnumerator System.Collections.IEnumerable.GetEnumerator()" attrs="481">
+        <size>14</size>
+      </method>
+      <method name="IEnumerator`1 System.Collections.Generic.IEnumerable&lt;string&gt;.GetEnumerator()" attrs="481">
+        <size>40</size>
+      </method>
+      <method name="Boolean MoveNext()" attrs="486">
+        <size>105</size>
+      </method>
+      <method name="Void Dispose()" attrs="486">
+        <size>15</size>
+      </method>
+      <method name="Void Reset()" attrs="486">
+        <size>6</size>
+      </method>
+      <method name="System.Threading.Tasks.Task`1[System.String] &lt;&gt;m__0()" attrs="131">
+        <size>41</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="C+&lt;Test2&gt;c__Iterator1">
+      <method name="System.String System.Collections.Generic.IEnumerator&lt;string&gt;.get_Current()" attrs="2529">
+        <size>14</size>
+      </method>
+      <method name="System.Object System.Collections.IEnumerator.get_Current()" attrs="2529">
+        <size>14</size>
+      </method>
+      <method name="IEnumerator System.Collections.IEnumerable.GetEnumerator()" attrs="481">
+        <size>14</size>
+      </method>
+      <method name="IEnumerator`1 System.Collections.Generic.IEnumerable&lt;string&gt;.GetEnumerator()" attrs="481">
+        <size>26</size>
+      </method>
+      <method name="Boolean MoveNext()" attrs="486">
+        <size>116</size>
+      </method>
+      <method name="Void Dispose()" attrs="486">
+        <size>15</size>
+      </method>
+      <method name="Void Reset()" attrs="486">
+        <size>6</size>
+      </method>
+      <method name="System.Threading.Tasks.Task`1[System.String] &lt;&gt;m__1()" attrs="131">
+        <size>41</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="C+&lt;Test&gt;c__Iterator0+&lt;Test&gt;c__async2">
+      <method name="Void MoveNext()" attrs="486">
+        <size>183</size>
+      </method>
+      <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
+        <size>13</size>
+      </method>
+    </type>
+    <type name="C+&lt;Test2&gt;c__Iterator1+&lt;Test2&gt;c__async3">
+      <method name="Void MoveNext()" attrs="486">
+        <size>183</size>
+      </method>
+      <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
+        <size>13</size>
+      </method>
+    </type>
+  </test>
+  <test name="test-async-31.cs">
+    <type name="C">
+      <method name="System.Threading.Tasks.Task`1[System.Int32] M(Int32)" attrs="129">
+        <size>41</size>
+      </method>
+      <method name="System.Threading.Tasks.Task`1[System.Int32] M2(Int32, Int32)" attrs="129">
+        <size>49</size>
+      </method>
+      <method name="Int32 Main()" attrs="150">
+        <size>68</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="C+&lt;M&gt;c__async0">
+      <method name="Void MoveNext()" attrs="486">
+        <size>354</size>
+      </method>
+      <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
+        <size>13</size>
+      </method>
+    </type>
+    <type name="C+&lt;M2&gt;c__async1">
+      <method name="Void MoveNext()" attrs="486">
+        <size>469</size>
+      </method>
+      <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
+        <size>13</size>
+      </method>
+    </type>
+    <type name="C+&lt;M&gt;c__async0+&lt;M&gt;c__AnonStorey3">
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="C+&lt;M&gt;c__async0+&lt;M&gt;c__AnonStorey2">
+      <method name="Int32 &lt;&gt;m__0()" attrs="131">
+        <size>14</size>
+      </method>
+      <method name="Int32 &lt;&gt;m__1()" attrs="131">
+        <size>26</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="C+&lt;M2&gt;c__async1+&lt;M2&gt;c__AnonStorey4">
+      <method name="Void &lt;&gt;m__2()" attrs="131">
+        <size>20</size>
+      </method>
       <method name="Void .ctor()" attrs="6278">
         <size>7</size>
       </method>
         <size>26</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>15</size>
+        <size>1</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
         <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">
       </method>
     </type>
   </test>
+  <test name="test-debug-21.cs">
+    <type name="C">
+      <method name="IEnumerable`1 Test()" attrs="129">
+        <size>23</size>
+      </method>
+      <method name="Void Main()" attrs="150">
+        <size>2</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="C+&lt;Test&gt;c__Iterator0">
+      <method name="Int32 System.Collections.Generic.IEnumerator&lt;int&gt;.get_Current()" attrs="2529">
+        <size>14</size>
+      </method>
+      <method name="System.Object System.Collections.IEnumerator.get_Current()" attrs="2529">
+        <size>19</size>
+      </method>
+      <method name="IEnumerator System.Collections.IEnumerable.GetEnumerator()" attrs="481">
+        <size>14</size>
+      </method>
+      <method name="IEnumerator`1 System.Collections.Generic.IEnumerable&lt;int&gt;.GetEnumerator()" attrs="481">
+        <size>26</size>
+      </method>
+      <method name="Void &lt;&gt;__Finally0()" attrs="129">
+        <size>13</size>
+      </method>
+      <method name="Boolean MoveNext()" attrs="486">
+        <size>150</size>
+      </method>
+      <method name="Void Dispose()" attrs="486">
+        <size>57</size>
+      </method>
+      <method name="Void Reset()" attrs="486">
+        <size>6</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="test-externalias-01.cs">
     <type name="Test">
       <method name="Int32 Main()" attrs="145">
         <size>40</size>
       </method>
       <method name="Boolean MoveNext()" attrs="486">
-        <size>282</size>
+        <size>264</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>119</size>
+        <size>107</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
       <method name="Void .ctor()" attrs="6278">
         <size>7</size>
       </method>
+      <method name="Void &lt;&gt;__Finally0()" attrs="129">
+        <size>13</size>
+      </method>
+      <method name="Void &lt;&gt;__Finally1()" attrs="129">
+        <size>13</size>
+      </method>
+      <method name="Void &lt;&gt;__Finally2()" attrs="129">
+        <size>13</size>
+      </method>
     </type>
   </test>
   <test name="test-iter-08.cs">
         <size>52</size>
       </method>
       <method name="Boolean MoveNext()" attrs="486">
-        <size>393</size>
+        <size>377</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>109</size>
+        <size>93</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
       <method name="Void .ctor()" attrs="6278">
         <size>7</size>
       </method>
+      <method name="Void &lt;&gt;__Finally0()" attrs="129">
+        <size>23</size>
+      </method>
     </type>
   </test>
   <test name="test-iter-09.cs">
         <size>40</size>
       </method>
       <method name="Boolean MoveNext()" attrs="486">
-        <size>203</size>
+        <size>190</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>70</size>
+        <size>57</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
       <method name="Void .ctor()" attrs="6278">
         <size>7</size>
       </method>
+      <method name="Void &lt;&gt;__Finally0()" attrs="129">
+        <size>20</size>
+      </method>
     </type>
   </test>
   <test name="test-iter-13.cs">
         <size>27</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>15</size>
+        <size>1</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
         <size>38</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>15</size>
+        <size>1</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
         <size>54</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>15</size>
+        <size>1</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
         <size>37</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>15</size>
+        <size>1</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
         <size>37</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>15</size>
+        <size>1</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
         <size>37</size>
       </method>
       <method name="Void Dispose()" attrs="486">
-        <size>15</size>
+        <size>1</size>
       </method>
       <method name="Void Reset()" attrs="486">
         <size>6</size>
index 6817f3f9441f3c538b1b5be7528844075706a1a1..b1a78ddf6d4ef39b5e64cf46caf7143d46a0a421 100644 (file)
@@ -38,6 +38,7 @@ net_4_0_dirs := \
        macpack         \
        dtd2rng         \
        dtd2xsd         \
+       monodoc         \
        mdoc            \
        mod             \
        installvst      \
@@ -48,8 +49,7 @@ net_4_0_dirs := \
        security
 
 net_2_0_dirs := \
-       $(per_profile_dirs) \
-       monodoc
+       $(per_profile_dirs)
 
 build_SUBDIRS = gacutil security culevel
 net_2_0_SUBDIRS := $(basic_SUBDIRS) $(net_2_0_dirs)
index f305499dec51538bff86dd0261a1ca3e38932e49..b7e5eb9fec2e87bf5f2ad693f60300ee309f0f0d 100644 (file)
@@ -18,9 +18,9 @@ MDOC_COMMON_FLAGS = \
        /r:Mono.Cecil.dll
 
 LOCAL_MCS_FLAGS = $(MDOC_COMMON_FLAGS) \
-       /r:$(topdir)/class/lib/net_2_0/monodoc.dll
+       /r:monodoc.dll
 PROGRAM = mdoc.exe
-PROGRAM_DEPS = $(topdir)/class/lib/net_2_0/monodoc.dll
+PROGRAM_DEPS = $(topdir)/class/lib/$(PROFILE)/monodoc.dll
 
 ifdef NET
 all : copy-with-deps
@@ -28,10 +28,10 @@ all : copy-with-deps
 copy-with-deps:
        -mkdir mdoc-net
        cp $(PROGRAM) mdoc-net
-       cp $(topdir)/class/lib/net_2_0/Commons.Xml.Relaxng.dll mdoc-net
-       cp $(topdir)/class/lib/net_2_0/ICSharpCode.SharpZipLib.dll mdoc-net
-       cp $(topdir)/class/lib/net_2_0/Mono.Cecil.dll mdoc-net
-       cp $(topdir)/class/lib/net_2_0/monodoc.dll mdoc-net
+       cp $(topdir)/class/lib/$(PROFILE)/Commons.Xml.Relaxng.dll mdoc-net
+       cp $(topdir)/class/lib/$(PROFILE)/ICSharpCode.SharpZipLib.dll mdoc-net
+       cp $(topdir)/class/lib/$(PROFILE)/Mono.Cecil.dll mdoc-net
+       cp $(topdir)/class/lib/$(PROFILE)/monodoc.dll mdoc-net
 endif
 
 MONODOC_RESOURCES = \
index c3361ca2f521fbb60b56b1030ef507499cb9980e..a67b71d4d8f36ce1edce292d0d37ad431877c9c3 100644 (file)
@@ -275,10 +275,12 @@ add masterdoc support?
       <enumeration value="sample"/>
       <!-- e.g. ECMA, OPC, OData, ... specs -->
       <enumeration value="specification"/>
-      <!-- e.g. Apple documentation -->
+      <!-- e.g. Apple/Android documentation -->
       <enumeration value="externalDocumentation" />
       <!-- e.g. a more in-depth article at docs.xamarin.com -->
       <enumeration value="article" />
+         <!-- e.g. a small article describing succintly a feature -->
+         <enumeration value="recipe" />
     </restriction>
   </xs:simpleType>
 
index 0d4dc93797967121ff1e82cbeb5fd56e590c8292..0e565c6a59165809d6aca91f156536361cc3ed26 100644 (file)
@@ -293,7 +293,7 @@ class MakeBundle {
                                        return;
                                }
                                Console.WriteLine ("System config from: " + config_file);
-                               tc.WriteLine ("extern const unsigned char system_config;");
+                               tc.WriteLine ("extern const char system_config;");
                                WriteSymbol (ts, "system_config", config_file.Length);
 
                                int n;
@@ -316,7 +316,7 @@ class MakeBundle {
                                        return;
                                }
                                Console.WriteLine ("Machine config from: " + machine_config_file);
-                               tc.WriteLine ("extern const unsigned char machine_config;");
+                               tc.WriteLine ("extern const char machine_config;");
                                WriteSymbol (ts, "machine_config", machine_config_file.Length);
 
                                int n;
index a21bca5eeffd8b7d898594ef2d5f8da7208ffc62..90c9afcb026b42f8208b7e4bc4ea6ce7bf61fff9 100644 (file)
@@ -2,8 +2,7 @@ thisdir = tools/mod
 SUBDIRS = 
 include ../../build/rules.make
 
-LOCAL_MCS_FLAGS = \
-       /r:$(topdir)/class/lib/net_2_0/monodoc.dll
+LOCAL_MCS_FLAGS = /r:monodoc.dll
 
 PROGRAM = mod.exe
 
index db7ecd7a9951006ad5213b6cb2f539a795645836..28ff180413c2e6b5fe6df47d717d9cc2d6ed6061 100644 (file)
@@ -26,7 +26,9 @@ using System.Xml;
 using System.Xml.XPath;
 using System.Xml.Xsl;
 using System.Text;
+using System.Linq;
 using System.Collections;
+using System.Collections.Generic;
 using Mono.Lucene.Net.Index;
 using Mono.Lucene.Net.Documents;
 
@@ -135,6 +137,73 @@ public static class EcmaDoc {
                return type;
        }
 
+       // Lala
+       static bool IsItReallyAGenericType (string type)
+       {
+               switch (type) {
+               case "Type":
+               case "TimeZone":
+               case "TimeZoneInfo":
+               case "TimeSpan":
+               case "TypeReference":
+               case "TypeCode":
+               case "TimeZoneInfo+AdjustmentRule":
+               case "TimeZoneInfo+TransitionTime":
+                       return false;
+               }
+               if (type.StartsWith ("Tuple"))
+                       return false;
+               return true;
+       }
+
+       public static string ConvertFromCTSName (string ctsType)
+       {
+               if (string.IsNullOrEmpty (ctsType))
+                       return string.Empty;
+
+               // Most normal type should have a namespace part and thus a point in their name
+               if (ctsType.IndexOf ('.') != -1)
+                       return ctsType;
+
+               if (ctsType.EndsWith ("*"))
+                       return ConvertFromCTSName(ctsType.Substring(0, ctsType.Length - 1)) + "*";
+               if (ctsType.EndsWith ("&"))
+                       return ConvertFromCTSName(ctsType.Substring(0, ctsType.Length - 1)) + "&";
+               if (ctsType.EndsWith ("]")) { // Array may be multidimensional
+                       var idx = ctsType.LastIndexOf ('[');
+                       return ConvertFromCTSName (ctsType.Substring (0, idx)) + ctsType.Substring (idx);
+               }
+
+               // Big hack here, we tentatively try to say if a type is a generic when it starts with a upper case T
+               if ((char.IsUpper (ctsType, 0) && ctsType.Length == 1) || (ctsType[0] == 'T' && IsItReallyAGenericType (ctsType)))
+                       return ctsType;
+
+               switch (ctsType) {
+               case "byte": return "System.Byte";
+               case "sbyte": return "System.SByte";
+               case "short": return "System.Int16";
+               case "int": return "System.Int32";
+               case "long": return "System.Int64";
+                       
+               case "ushort": return "System.UInt16";
+               case "uint": return "System.UInt32";
+               case "ulong": return "System.UInt64";
+                       
+               case "float":  return "System.Single";
+               case "double":  return "System.Double";
+               case "decimal": return "System.Decimal";
+               case "bool": return "System.Boolean";
+               case "char":    return "System.Char";
+               case "string":  return "System.String";
+                       
+               case "object":  return "System.Object";
+               case "void":  return "System.Void";
+               }
+
+               // If we arrive here, the type was probably stripped of its 'System.'
+               return "System." + ctsType;
+       }
+
        internal static string GetNamespaceFile (string dir, string ns)
        {
                string nsxml = Path.Combine (dir, "ns-" + ns + ".xml");
@@ -179,7 +248,7 @@ public static class EcmaDoc {
        {
                XmlNodeList parameters = member.SelectNodes ("Parameters/Parameter");
                if (parameters.Count == 0)
-                       return "";
+                       return member.SelectSingleNode ("MemberType").InnerText != "Property" ? "()" : "";
                StringBuilder args = new StringBuilder ();
                args.Append ("(");
                args.Append (XmlDocUtils.ToTypeName (parameters [0].Attributes ["Type"].Value, member));
@@ -1125,7 +1194,7 @@ public class EcmaHelpSource : HelpSource {
 
        static string ToEscapedMemberName (string membername)
        {
-               return ToEscapedName (membername, "``");
+               return ToEscapedName (membername, "`");
        }
        
        public override string GetNodeXPath (XPathNavigator n)
@@ -1998,6 +2067,63 @@ public class EcmaHelpSource : HelpSource {
                        }
                }
        }
+
+       IEnumerable<string> ExtractArguments (string rawArgList)
+       {
+               var sb = new System.Text.StringBuilder ();
+               int genericDepth = 0;
+               int arrayDepth = 0;
+
+               for (int i = 0; i < rawArgList.Length; i++) {
+                       char c = rawArgList[i];
+
+                       switch (c) {
+                       case ',':
+                               if (genericDepth == 0 && arrayDepth == 0) {
+                                       yield return sb.ToString ();
+                                       sb.Clear ();
+                                       continue;
+                               }
+                               break;
+                       case '<':
+                               genericDepth++;
+                               break;
+                       case '>':
+                               genericDepth--;
+                               break;
+                       case '[':
+                               arrayDepth++;
+                               break;
+                       case ']':
+                               arrayDepth--;
+                               break;
+                       }
+                       sb.Append (c);
+               }
+               if (sb.Length > 0)
+                       yield return sb.ToString ();
+       }
+
+       // Caption is what you see on a tree node, either SomeName or SomeName(ArgList)
+       void TryCreateXPathPredicateFragment (string caption, out string name, out string argListPredicate)
+       {
+               name = argListPredicate = null;
+               int parenIdx = caption.IndexOf ('(');
+               // In case of simple name, there is no need for processing
+               if (parenIdx == -1) {
+                       name = caption;
+                       return;
+               }
+               name = caption.Substring (0, parenIdx);
+               // Now we create a xpath predicate which will check for all the args in the argsList
+               var rawArgList = caption.Substring (parenIdx + 1, caption.Length - parenIdx - 2); // Only take what's inside the parens
+               if (string.IsNullOrEmpty (rawArgList))
+                       return;
+
+               var argList = ExtractArguments (rawArgList).Select (arg => arg.Trim ()).Select (type => EcmaDoc.ConvertFromCTSName (type));
+               argListPredicate = "and " + argList.Select (type => string.Format ("Parameters/Parameter[@Type='{0}']", type)).Aggregate ((e1, e2) => e1 + " and " + e2);
+       }
+
        //
        // Create list of documents for searching
        //
@@ -2046,22 +2172,50 @@ public class EcmaHelpSource : HelpSource {
                                                
                                                if (c.Element == "*")
                                                        continue;
-                                               int i = 1;
                                                const float innerTypeBoost = 0.2f;
 
-                                               foreach (Node nc in c.Nodes) {
-                                                       // Disable constructors indexing as it's often "polluting" search queries
-                                                       // because it has the same hottext than standard types
-                                                       if (c.Caption == "Constructors")
-                                                               continue;
+                                               var ncnodes = c.Nodes.Cast<Node> ();
+                                               // The rationale is that we need to properly handle method overloads
+                                               // so for those method node which have children, flatten them
+                                               if (c.Caption == "Methods") {
+                                                       ncnodes = ncnodes
+                                                               .Where (n => n.Nodes == null || n.Nodes.Count == 0)
+                                                               .Concat (ncnodes.Where (n => n.Nodes.Count > 0).SelectMany (n => n.Nodes.Cast<Node> ()));
+                                               } else if (c.Caption == "Operators") {
+                                                       ncnodes = ncnodes
+                                                               .Where (n => n.Caption != "Conversion")
+                                                               .Concat (ncnodes.Where (n => n.Caption == "Conversion").SelectMany (n => n.Nodes.Cast<Node> ()));
+                                               }
+                                               foreach (Node nc in ncnodes) {
                                                        //xpath to the docs xml node
                                                        string xpath;
-                                                       if (c.Caption == "Constructors")
-                                                               xpath = String.Format ("/Type/Members/Member[{0}]/Docs", i++);
-                                                       else if (c.Caption == "Operators")
-                                                               xpath = String.Format ("/Type/Members/Member[@MemberName='op_{0}']/Docs", nc.Caption);
-                                                       else
+                                                       string name, argListPredicate;
+
+                                                       switch (c.Caption) {
+                                                       case "Constructors":
+                                                               TryCreateXPathPredicateFragment (nc.Caption, out name, out argListPredicate);
+                                                               xpath = String.Format ("/Type/Members/Member[@MemberName='.ctor'{0}]/Docs", argListPredicate ?? string.Empty);
+                                                               break;
+                                                       case "Operators":
+                                                               // The first case are explicit and implicit conversion operators which are grouped specifically
+                                                               if (nc.Caption.IndexOf (" to ") != -1) {
+                                                                       var convArgs = nc.Caption.Split (new[] { " to " }, StringSplitOptions.None);
+                                                                       xpath = String.Format ("/Type/Members/Member[(@MemberName='op_Explicit' or @MemberName='op_Implicit')" +
+                                                                                              " and ReturnValue/ReturnType='{0}'" +
+                                                                                              " and Parameters/Parameter[@Type='{1}']]/Docs",
+                                                                                              EcmaDoc.ConvertFromCTSName (convArgs[1]), EcmaDoc.ConvertFromCTSName (convArgs[0]));
+                                                               } else {
+                                                                       xpath = String.Format ("/Type/Members/Member[@MemberName='op_{0}']/Docs", nc.Caption);
+                                                               }
+                                                               break;
+                                                       case "Methods":
+                                                               TryCreateXPathPredicateFragment (nc.Caption, out name, out argListPredicate);
+                                                               xpath = String.Format ("/Type/Members/Member[@MemberName='{0}'{1}]/Docs", name, argListPredicate ?? string.Empty);
+                                                               break;
+                                                       default:
                                                                xpath = String.Format ("/Type/Members/Member[@MemberName='{0}']/Docs", nc.Caption);
+                                                               break;
+                                                       }
                                                        //construct url of the form M:Array.Sort
                                                        string urlnc;
                                                        if (c.Caption == "Constructors")
@@ -2085,16 +2239,25 @@ public class EcmaHelpSource : HelpSource {
                                                        case 'O':
                                                                doc_nod.title += " Operator";
                                                                break;
+                                                       case 'C':
+                                                               doc_nod.title += " Constructor";
+                                                               break;
                                                        default:
                                                                break;
                                                        }
                                                        doc_nod.fulltitle = string.Format ("{0}.{1}::{2}", ns_node.Caption, typename, nc.Caption);
-                                                       //dont add the parameters to the hottext
-                                                       int ppos = nc.Caption.IndexOf ('(');
-                                                       if (ppos != -1)
-                                                               doc_nod.hottext =  nc.Caption.Substring (0, ppos);
-                                                       else
-                                                               doc_nod.hottext = nc.Caption;
+                                                       // Disable constructors hottext indexing as it's often "polluting" search queries
+                                                       // because it has the same hottext than standard types
+                                                       if (c.Caption != "Constructors") {
+                                                               //dont add the parameters to the hottext
+                                                               int ppos = nc.Caption.IndexOf ('(');
+                                                               if (ppos != -1)
+                                                                       doc_nod.hottext =  nc.Caption.Substring (0, ppos);
+                                                               else
+                                                                       doc_nod.hottext = nc.Caption;
+                                                       } else {
+                                                               doc_nod.hottext = string.Empty;
+                                                       }
 
                                                        doc_nod.url = urlnc;
 
@@ -2108,7 +2271,7 @@ public class EcmaHelpSource : HelpSource {
                                                        GetTextFromNode (xmln, text);
                                                        doc_nod.text = text.ToString ();
 
-                                                       text = new StringBuilder ();
+                                                       text.Clear ();
                                                        GetExamples (xmln, text);
                                                        doc_nod.examples = text.ToString ();
 
index 4678ea1114915361f3613b9911e3e1de8eaddf41..c6034f656575aaa29bd554373f08e11908c669ad 100644 (file)
                <h3 class="{$type}"><xsl:value-of select="$section" /></h3>
                <ul class="{$type}">
                  <xsl:for-each select="Docs/related[@type=$type]">
-                       <li><a href="{@href}"><xsl:value-of select="." /></a></li>
+                       <li><a href="{@href}" target="_blank"><xsl:value-of select="." /></a></li>
                  </xsl:for-each>
                </ul>
          </xsl:if>
                                  <xsl:with-param name="type" select="'article'" />
                                </xsl:call-template>
                                <xsl:call-template name="CreateRelatedSection">
-                                 <xsl:with-param name="section" select="'Available Samples'" />
+                                 <xsl:with-param name="section" select="'Recipes'" />
+                                 <xsl:with-param name="type" select="'recipe'" />
+                               </xsl:call-template>
+                               <xsl:call-template name="CreateRelatedSection">
+                                 <xsl:with-param name="section" select="'Samples'" />
                                  <xsl:with-param name="type" select="'sample'" />
                                </xsl:call-template>
                                <xsl:call-template name="CreateRelatedSection">
                          <xsl:when test="count(@src)&gt;0">
                                <xsl:value-of select="@src" />
                          </xsl:when>
-                         <xsl:otherwise>
-                               <xsl:value-of select="source-id:{$source-id}:{@href}" />
-                         </xsl:otherwise>
+                         <xsl:when test="count(@href)&gt;0">
+                               <xsl:value-of select="concat('source-id:', $source-id, ':', @href)" />
+                         </xsl:when>
                        </xsl:choose>
                  </xsl:attribute>
                  <xsl:attribute name="class">
@@ -2547,7 +2551,7 @@ SkipGenericArgument: invalid type substring '<xsl:value-of select="$s" />'
                        <xsl:with-param name="type" select="$type" />
                        <xsl:with-param name="member" select="$member" />
                </xsl:call-template>
-               <xsl:if test="count($member/Parameters/Parameter) &gt; 0">
+               <xsl:if test="count($member/Parameters/Parameter) &gt; 0 or $member/MemberType='Method' or $member/MemberType='Constructor'">
                        <xsl:text>(</xsl:text>
                        <xsl:for-each select="Parameters/Parameter">
                                <xsl:if test="not(position()=1)">,</xsl:if>
index 6d44358bf327b3d0dd2bb9f48073f314af2e8809..75e02a001494fe79d80b749e269393cbe8090345 100644 (file)
@@ -881,12 +881,18 @@ Mono implementation of ASP.NET, Remoting and Web Services.
 %_prefix/lib/mono/4.5/Mono.Web.dll
 %_prefix/lib/mono/4.5/System.ComponentModel.Composition.dll
 %_prefix/lib/mono/4.5/System.ComponentModel.DataAnnotations.dll
+%_prefix/lib/mono/4.5/System.Net.Http.Formatting.dll
 %_prefix/lib/mono/4.5/System.Runtime.Remoting.dll
 %_prefix/lib/mono/4.5/System.Runtime.Serialization.Formatters.Soap.dll
 %_prefix/lib/mono/4.5/System.Web.Abstractions.dll
 %_prefix/lib/mono/4.5/System.Web.ApplicationServices.dll
+%_prefix/lib/mono/4.5/System.Web.Http.dll
 %_prefix/lib/mono/4.5/System.Web.Routing.dll
+%_prefix/lib/mono/4.5/System.Web.Razor.dll
 %_prefix/lib/mono/4.5/System.Web.Services.dll
+%_prefix/lib/mono/4.5/System.Web.WebPages.Deployment.dll
+%_prefix/lib/mono/4.5/System.Web.WebPages.Razor.dll
+%_prefix/lib/mono/4.5/System.Web.WebPages.dll
 %_prefix/lib/mono/4.5/System.Web.dll
 %_prefix/lib/mono/4.5/disco.exe*
 %_prefix/lib/mono/4.5/mconfig.exe*
@@ -899,13 +905,19 @@ Mono implementation of ASP.NET, Remoting and Web Services.
 %_prefix/lib/mono/gac/Mono.Web
 %_prefix/lib/mono/gac/System.ComponentModel.Composition
 %_prefix/lib/mono/gac/System.ComponentModel.DataAnnotations
+%_prefix/lib/mono/gac/System.Net.Http.Formatting
 %_prefix/lib/mono/gac/System.Runtime.Remoting
 %_prefix/lib/mono/gac/System.Runtime.Serialization.Formatters.Soap
 %_prefix/lib/mono/gac/System.Web
 %_prefix/lib/mono/gac/System.Web.Abstractions
 %_prefix/lib/mono/gac/System.Web.ApplicationServices
+%_prefix/lib/mono/gac/System.Web.Http
 %_prefix/lib/mono/gac/System.Web.Routing
+%_prefix/lib/mono/gac/System.Web.Razor
 %_prefix/lib/mono/gac/System.Web.Services
+%_prefix/lib/mono/gac/System.Web.WebPages.Deployment
+%_prefix/lib/mono/gac/System.Web.WebPages.Razor
+%_prefix/lib/mono/gac/System.Web.WebPages
 
 %package -n mono-mvc
 License:        MIT License (or similar) ; Ms-Pl
@@ -938,6 +950,7 @@ Mono implementation of ASP.NET MVC.
 %_prefix/lib/mono/4.5/System.Web.DynamicData.dll
 %_prefix/lib/mono/4.5/System.Web.Extensions.Design.dll
 %_prefix/lib/mono/4.5/System.Web.Extensions.dll
+%_prefix/lib/mono/4.5/System.Web.Mvc.dll
 %_prefix/lib/mono/compat-2.0/System.Web.Extensions.Design.dll
 %_prefix/lib/mono/compat-2.0/System.Web.Extensions.dll
 %_prefix/lib/mono/compat-2.0/System.Web.Mvc.dll
@@ -1201,7 +1214,6 @@ Mono development tools.
 %_prefix/lib/mono/4.0/Microsoft.Common.tasks
 %_prefix/lib/mono/4.0/Microsoft.VisualBasic.targets
 %_prefix/lib/mono/4.0/Mono.Debugger.Soft.dll
-%_prefix/lib/mono/4.0/Mono.CodeContracts.dll
 %_prefix/lib/mono/4.0/PEAPI.dll
 %_prefix/lib/mono/4.5/Microsoft.Build.dll
 %_prefix/lib/mono/4.5/Microsoft.Build.Engine.dll
index 7f74e3d740d4e2175c9c7af43310046d6ee81d5a..d3292bffb907295510f3f20f3602fc1955d63153 100644 (file)
@@ -146,6 +146,8 @@ typedef enum {
 #define s390_is_uimm12(val)            ((glong)val >= 0 && (glong)val <= 4095)
 
 #define STK_BASE                       s390_r15
+#define S390_SP                                s390_r15
+#define S390_FP                                s390_r11
 #define S390_MINIMAL_STACK_SIZE                160
 #define S390_REG_SAVE_OFFSET           48
 #define S390_PARM_SAVE_OFFSET          16
index 24fcd94f81b2ff0e05e950af183fccc0428d7d7f..9c397f4e41bb1c6c689dc5efe2ee8404efc33aaa 100644 (file)
@@ -10,9 +10,13 @@ else
 runtime_lib=../interpreter/libmint.la
 endif
 
+if DISABLE_EXECUTABLES
+bin_PROGRAMS =
+else
 if SUPPORT_BOEHM
 bin_PROGRAMS = monodis
 endif
+endif
 
 noinst_LIBRARIES = libmonodis.a
 
index d46023bb865759f21d481f5df7c7f863fbf96b27..41f271ec4cfeab7f19be3291d245893cd6d605db 100644 (file)
@@ -409,8 +409,9 @@ gpointer CreateThread(WapiSecurityAttributes *security G_GNUC_UNUSED, guint32 st
                                                                           thread_start_routine, (void *)thread_handle_p);
 
        if (ret != 0) {
-               DEBUG ("%s: Thread create error: %s", __func__,
-                          strerror(ret));
+               g_warning ("%s: Error creating native thread handle %s (%d)", __func__,
+                          strerror (ret), ret);
+               SetLastError (ERROR_GEN_FAILURE);
 
                /* Two, because of the reference we took above */
                unrefs = 2;
index 630a1c3be3a0fcefcb0e9fef3769a6ea6a1af3d7..12d15944ef973d514a80af432d97df139ff23995 100644 (file)
@@ -60,7 +60,11 @@ moon-do-clean:
        -test -z "libmonoruntimemoon.la" || rm -f libmonoruntimemoon.la
 endif
 
+if DISABLE_EXECUTABLES
+noinst_LTLIBRARIES = $(shared_sgen_libraries) $(shared_boehm_libraries)
+else
 noinst_LTLIBRARIES = $(boehm_libraries) $(sgen_libraries) $(moonlight_libraries)
+endif
 
 INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/mono $(LIBGC_CPPFLAGS) $(GLIB_CFLAGS) -DMONO_BINDIR=\"$(bindir)/\" -DMONO_ASSEMBLIES=\"$(assembliesdir)\" -DMONO_CFG_DIR=\"$(confdir)\"
 
index f6e175e7a4639632b4b270c2d8f5909ea6b9f401..71e0d722a03c0a9835e696076b6909a118c8862b 100644 (file)
@@ -1388,7 +1388,11 @@ mono_class_setup_fields (MonoClass *class)
        explicit_size = mono_metadata_packing_from_typedef (class->image, class->type_token, &packing_size, &real_size);
 
        if (explicit_size) {
-               g_assert ((packing_size & 0xfffffff0) == 0);
+               if ((packing_size & 0xfffffff0) != 0) {
+                       char *err_msg = g_strdup_printf ("Could not load struct '%s' with packing size %d >= 16", class->name, packing_size);
+                       mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, err_msg);
+                       return;
+               }
                class->packing_size = packing_size;
                real_size += class->instance_size;
        }
@@ -2407,7 +2411,7 @@ mono_unload_interface_ids (MonoBitSet *bitset)
 void
 mono_unload_interface_id (MonoClass *class)
 {
-       if (class->interface_id) {
+       if (global_interface_bitset && class->interface_id) {
                mono_loader_lock ();
                mono_bitset_clear (global_interface_bitset, class->interface_id);
                mono_loader_unlock ();
@@ -9021,6 +9025,7 @@ mono_classes_cleanup (void)
 {
        if (global_interface_bitset)
                mono_bitset_free (global_interface_bitset);
+       global_interface_bitset = NULL;
 }
 
 /**
index 7527d598c238de91c39a08c17655e3cdc6e34d88..8aaa6d21447ee374b2c47f3d63eaaeb4663c68a8 100644 (file)
@@ -392,7 +392,7 @@ cominterop_com_visible (MonoClass* klass)
        MonoError error;
        MonoCustomAttrInfo *cinfo;
        GPtrArray *ifaces;
-       MonoBoolean visible = 0;
+       MonoBoolean visible = 1;
 
        /* Handle the ComVisibleAttribute */
        if (!ComVisibleAttribute)
index 0320be82630a6c60a31dfbf2a908a67b42c58bbc..1a89248dd0f9b6ba7086b9297fac5c49e67f0d25 100644 (file)
@@ -1533,7 +1533,7 @@ mono_gc_bzero (void *dest, size_t size)
 {
        char *p = (char*)dest;
        char *end = p + size;
-       char *align_end = p + unaligned_bytes (p);
+       char *align_end = align_up (p);
        char *word_end;
 
        while (p < align_end)
index 2b704c281a55d47f82c1f163654b7106fe72279a..2431465f431deadfe4dc7c09cb77f8d6a7ad0f7d 100644 (file)
@@ -330,19 +330,18 @@ mono_loader_error_prepare_exception (MonoLoaderError *error)
        }
                
        case MONO_EXCEPTION_MISSING_FIELD: {
-               char *cnspace = g_strdup ((error->klass && *error->klass->name_space) ? error->klass->name_space : "");
-               char *cname = g_strdup (error->klass ? error->klass->name : "");
+               char *class_name;
                char *cmembername = g_strdup (error->member_name);
-                char *class_name;
+               if (error->klass)
+                       class_name = mono_type_get_full_name (error->klass);
+               else
+                       class_name = g_strdup ("");
 
                mono_loader_clear_error ();
-               class_name = g_strdup_printf ("%s%s%s", cnspace, cnspace ? "." : "", cname);
                
                ex = mono_get_exception_missing_field (class_name, cmembername);
                g_free (class_name);
-               g_free (cname);
                g_free (cmembername);
-               g_free (cnspace);
                break;
         }
        
index e4405061ba577a713e016817e9f99b7eb5c26312..ae38a0a63dd4f0fed8ab340d6e79a5c4010bcee5 100644 (file)
@@ -8035,6 +8035,10 @@ emit_marshal (EmitMarshalContext *m, int argnum, MonoType *t,
        /* Ensure that we have marshalling info for this param */
        mono_marshal_load_type_info (mono_class_from_mono_type (t));
 
+#ifdef DISABLE_JIT
+       /* Not JIT support, no need to generate correct IL */
+       return conv_arg;
+#else
        if (spec && spec->native == MONO_NATIVE_CUSTOM)
                return emit_marshal_custom (m, argnum, t, spec, conv_arg, conv_arg_type, action);
 
@@ -8099,6 +8103,7 @@ emit_marshal (EmitMarshalContext *m, int argnum, MonoType *t,
                else
                        return emit_marshal_object (m, argnum, t, spec, conv_arg, conv_arg_type, action);
        }
+#endif
 
        return conv_arg;
 }
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 664d6f90b55ed11c6900823e2ecd97f467f1802c..373e0f5ead8d5af28c4aea8b1d044ef833d13769 100644 (file)
@@ -10927,7 +10927,11 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
        mono_error_init (error);
 
        if (tb->class_size) {
-               g_assert ((tb->packing_size & 0xfffffff0) == 0);
+               if ((tb->packing_size & 0xfffffff0) != 0) {
+                       char *err_msg = g_strdup_printf ("Could not load struct '%s' with packing size %d >= 16", klass->name, tb->packing_size);
+                       mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg);
+                       return;
+               }
                klass->packing_size = tb->packing_size;
                real_size = klass->instance_size + tb->class_size;
        }
index 4470b4ab07a4f1149ab5d17394e78386adb49b95..200c6eaec90303188622694455cbb4a0bb661c28 100644 (file)
@@ -110,15 +110,6 @@ static __thread char **tlab_next_addr;
 #define TLAB_REAL_END  (__thread_info__->tlab_real_end)
 #endif
 
-static inline void
-set_nursery_scan_start (char *p)
-{
-       int idx = (p - (char*)nursery_section->data) / SGEN_SCAN_START_SIZE;
-       char *old = nursery_section->scan_starts [idx];
-       if (!old || old > p)
-               nursery_section->scan_starts [idx] = p;
-}
-
 static void*
 alloc_degraded (MonoVTable *vtable, size_t size, gboolean for_mature)
 {
@@ -134,6 +125,7 @@ alloc_degraded (MonoVTable *vtable, size_t size, gboolean for_mature)
                                fprintf (stderr, "Warning: Repeated degraded allocation.  Consider increasing nursery-size.\n");
                        last_major_gc_warned = stat_major_gcs;
                }
+               InterlockedExchangeAdd (&degraded_mode, size);
        }
 
        if (mono_sgen_need_major_collection (0)) {
@@ -311,13 +303,13 @@ mono_gc_alloc_obj_nolock (MonoVTable *vtable, size_t size)
                                /* Allocate from the TLAB */
                                p = (void*)TLAB_NEXT;
                                TLAB_NEXT += size;
-                               set_nursery_scan_start ((char*)p);
+                               mono_sgen_set_nursery_scan_start ((char*)p);
                        }
                } else {
                        /* Reached tlab_temp_end */
 
                        /* record the scan start so we can find pinned objects more easily */
-                       set_nursery_scan_start ((char*)p);
+                       mono_sgen_set_nursery_scan_start ((char*)p);
                        /* we just bump tlab_temp_end as well */
                        TLAB_TEMP_END = MIN (TLAB_REAL_END, TLAB_NEXT + SGEN_SCAN_START_SIZE);
                        DEBUG (5, fprintf (gc_debug_file, "Expanding local alloc: %p-%p\n", TLAB_NEXT, TLAB_TEMP_END));
@@ -351,7 +343,7 @@ mono_gc_try_alloc_obj_nolock (MonoVTable *vtable, size_t size)
                p = mono_sgen_nursery_alloc (size);
                if (!p)
                        return NULL;
-               set_nursery_scan_start ((char*)p);
+               mono_sgen_set_nursery_scan_start ((char*)p);
 
                /*FIXME we should use weak memory ops here. Should help specially on x86. */
                if (nursery_clear_policy == CLEAR_AT_TLAB_CREATION)
@@ -373,7 +365,7 @@ mono_gc_try_alloc_obj_nolock (MonoVTable *vtable, size_t size)
 
                        /* Second case, we overflowed temp end */
                        if (G_UNLIKELY (new_next >= TLAB_TEMP_END)) {
-                               set_nursery_scan_start (new_next);
+                               mono_sgen_set_nursery_scan_start (new_next);
                                /* we just bump tlab_temp_end as well */
                                TLAB_TEMP_END = MIN (TLAB_REAL_END, TLAB_NEXT + SGEN_SCAN_START_SIZE);
                                DEBUG (5, fprintf (gc_debug_file, "Expanding local alloc: %p-%p\n", TLAB_NEXT, TLAB_TEMP_END));         
@@ -399,7 +391,7 @@ mono_gc_try_alloc_obj_nolock (MonoVTable *vtable, size_t size)
                        TLAB_NEXT = new_next + size;
                        TLAB_REAL_END = new_next + alloc_size;
                        TLAB_TEMP_END = new_next + MIN (SGEN_SCAN_START_SIZE, alloc_size);
-                       set_nursery_scan_start ((char*)p);
+                       mono_sgen_set_nursery_scan_start ((char*)p);
 
                        if (nursery_clear_policy == CLEAR_AT_TLAB_CREATION)
                                memset (new_next, 0, alloc_size);
@@ -848,7 +840,11 @@ create_allocator (int atype)
                mono_mb_emit_ldloc (mb, p_var);
                mono_mb_emit_ldflda (mb, G_STRUCT_OFFSET (MonoArray, max_length));
                mono_mb_emit_ldarg (mb, 1);
+#ifdef MONO_BIG_ARRAYS
                mono_mb_emit_byte (mb, CEE_STIND_I);
+#else
+               mono_mb_emit_byte (mb, CEE_STIND_I4);
+#endif
        }
 
        /*
index 0da21b0e3a08e3fcd0197f15d72f5f7ede0c9c40..6ebeaedd0ea978d0308f6be669c0a4add10e3cad 100644 (file)
@@ -279,17 +279,18 @@ static int current_time;
 void
 mono_gc_register_bridge_callbacks (MonoGCBridgeCallbacks *callbacks)
 {
-       if (callbacks->bridge_version != MONO_SGEN_BRIDGE_VERSION) {
-               fprintf (stderr, "Invalid bridge callback version. Expected %d but got %d\n", MONO_SGEN_BRIDGE_VERSION, callbacks->bridge_version);
-               exit (1);
-       }
+       if (callbacks->bridge_version != MONO_SGEN_BRIDGE_VERSION)
+               g_error ("Invalid bridge callback version. Expected %d but got %d\n", MONO_SGEN_BRIDGE_VERSION, callbacks->bridge_version);
+
        bridge_callbacks = *callbacks;
 }
 
 gboolean
 mono_sgen_is_bridge_object (MonoObject *obj)
 {
-       return (obj->vtable->gc_bits & SGEN_GC_BIT_BRIDGE_OBJECT) == SGEN_GC_BIT_BRIDGE_OBJECT;
+       if ((obj->vtable->gc_bits & SGEN_GC_BIT_BRIDGE_OBJECT) != SGEN_GC_BIT_BRIDGE_OBJECT)
+               return FALSE;
+       return bridge_callbacks.is_bridge_object (obj);
 }
 
 gboolean
@@ -762,6 +763,12 @@ bridge_test_is_bridge_class (MonoClass *class)
        return !strcmp (bridge_class, class->name);
 }
 
+static gboolean
+bridge_test_is_bridge_object (MonoObject *object)
+{
+       return TRUE;
+}
+
 static void
 bridge_test_cross_reference (int num_sccs, MonoGCBridgeSCC **sccs, int num_xrefs, MonoGCBridgeXRef *xrefs)
 {
@@ -789,6 +796,7 @@ mono_sgen_register_test_bridge_callbacks (const char *bridge_class_name)
        MonoGCBridgeCallbacks callbacks;
        callbacks.bridge_version = MONO_SGEN_BRIDGE_VERSION;
        callbacks.is_bridge_class = bridge_test_is_bridge_class;
+       callbacks.is_bridge_object = bridge_test_is_bridge_object;
        callbacks.cross_references = bridge_test_cross_reference;
        mono_gc_register_bridge_callbacks (&callbacks);
        bridge_class = bridge_class_name;
index 0b92d110f890b0dc239e7decb13d3646eda54ca8..2512542b3c6f4bde943e32a2b28e6fde64cbd68d 100644 (file)
@@ -29,7 +29,7 @@
 MONO_BEGIN_DECLS
 
 enum {
-       MONO_SGEN_BRIDGE_VERSION = 1
+       MONO_SGEN_BRIDGE_VERSION = 2
 };
        
 typedef struct {
@@ -45,6 +45,7 @@ typedef struct {
 typedef struct {
        int bridge_version;
        mono_bool (*is_bridge_class) (MonoClass *class);
+       mono_bool (*is_bridge_object) (MonoObject *object);
        void (*cross_references) (int num_sccs, MonoGCBridgeSCC **sccs, int num_xrefs, MonoGCBridgeXRef *xrefs);
 } MonoGCBridgeCallbacks;
 
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 03c515d057c846592a0d6fcbce5c50e28720e460..5a7c03ae4ba292ae6d03145da56a98e50aabcd8a 100644 (file)
@@ -1928,9 +1928,7 @@ finish_gray_stack (char *start_addr, char *end_addr, int generation, GrayQueue *
 {
        TV_DECLARE (atv);
        TV_DECLARE (btv);
-       int fin_ready;
        int done_with_ephemerons, ephemeron_rounds = 0;
-       int num_loops;
        CopyOrMarkObjectFunc copy_func = mono_sgen_get_copy_object ();
 
        /*
@@ -1995,26 +1993,13 @@ finish_gray_stack (char *start_addr, char *end_addr, int generation, GrayQueue *
         * finalized: use the finalized objects as new roots so the objects they depend
         * on are also not reclaimed. As with the roots above, only objects in the nursery
         * are marked/copied.
-        * We need a loop here, since objects ready for finalizers may reference other objects
-        * that are fin-ready. Speedup with a flag?
         */
-       num_loops = 0;
-       do {            
-               fin_ready = num_ready_finalizers;
-               finalize_in_range (copy_func, start_addr, end_addr, generation, queue);
-               if (generation == GENERATION_OLD)
-                       finalize_in_range (copy_func, mono_sgen_get_nursery_start (), mono_sgen_get_nursery_end (), GENERATION_NURSERY, queue);
-
-               if (fin_ready != num_ready_finalizers)
-                       ++num_loops;
-
-               /* drain the new stack that might have been created */
-               DEBUG (6, fprintf (gc_debug_file, "Precise scan of gray area post fin\n"));
-               mono_sgen_drain_gray_stack (queue, -1);
-       } while (fin_ready != num_ready_finalizers);
-
-       if (mono_sgen_need_bridge_processing ())
-               g_assert (num_loops <= 1);
+       finalize_in_range (copy_func, start_addr, end_addr, generation, queue);
+       if (generation == GENERATION_OLD)
+               finalize_in_range (copy_func, mono_sgen_get_nursery_start (), mono_sgen_get_nursery_end (), GENERATION_NURSERY, queue);
+       /* drain the new stack that might have been created */
+       DEBUG (6, fprintf (gc_debug_file, "Precise scan of gray area post fin\n"));
+       mono_sgen_drain_gray_stack (queue, -1);
 
        /*
         * This must be done again after processing finalizable objects since CWL slots are cleared only after the key is finalized.
@@ -2475,6 +2460,21 @@ job_scan_thread_data (WorkerData *worker_data, void *job_data_untyped)
                        mono_sgen_workers_get_job_gray_queue (worker_data));
 }
 
+typedef struct
+{
+       FinalizeReadyEntry *list;
+} ScanFinalizerEntriesJobData;
+
+static void
+job_scan_finalizer_entries (WorkerData *worker_data, void *job_data_untyped)
+{
+       ScanFinalizerEntriesJobData *job_data = job_data_untyped;
+
+       scan_finalizer_entries (mono_sgen_get_copy_object (),
+                       job_data->list,
+                       mono_sgen_workers_get_job_gray_queue (worker_data));
+}
+
 static void
 verify_scan_starts (char *start, char *end)
 {
@@ -2540,6 +2540,7 @@ collect_nursery (size_t requested_size)
        char *nursery_next;
        FinishRememberedSetScanJobData frssjd;
        ScanFromRegisteredRootsJobData scrrjd_normal, scrrjd_wbarrier;
+       ScanFinalizerEntriesJobData sfejd_fin_ready, sfejd_critical_fin;
        ScanThreadDataJobData stdjd;
        mword fragment_total;
        TV_DECLARE (all_atv);
@@ -2575,9 +2576,6 @@ collect_nursery (size_t requested_size)
        TV_GETTIME (all_atv);
        atv = all_atv;
 
-       /* Pinning no longer depends on clearing all nursery fragments */
-       mono_sgen_clear_current_nursery_fragment ();
-
        TV_GETTIME (btv);
        time_minor_pre_collection_fragment_clear += TV_ELAPSED (atv, btv);
 
@@ -2610,6 +2608,7 @@ collect_nursery (size_t requested_size)
        mono_sgen_optimize_pin_queue (0);
        mono_sgen_pinning_setup_section (nursery_section);
        mono_sgen_pin_objects_in_section (nursery_section, WORKERS_DISTRIBUTE_GRAY_QUEUE);      
+       mono_sgen_pinning_trim_queue_to_section (nursery_section);
 
        TV_GETTIME (atv);
        time_minor_pinning += TV_ELAPSED (btv, atv);
@@ -2685,6 +2684,13 @@ collect_nursery (size_t requested_size)
        if (mono_sgen_collection_is_parallel ())
                g_assert (mono_sgen_gray_object_queue_is_empty (&gray_queue));
 
+       /* Scan the list of objects ready for finalization. If */
+       sfejd_fin_ready.list = fin_ready_list;
+       mono_sgen_workers_enqueue_job (job_scan_finalizer_entries, &sfejd_fin_ready);
+
+       sfejd_critical_fin.list = critical_fin_list;
+       mono_sgen_workers_enqueue_job (job_scan_finalizer_entries, &sfejd_critical_fin);
+
        finish_gray_stack (mono_sgen_get_nursery_start (), nursery_next, GENERATION_NURSERY, &gray_queue);
        TV_GETTIME (atv);
        time_minor_finish_gray_stack += TV_ELAPSED (btv, atv);
@@ -2772,21 +2778,6 @@ mono_sgen_collect_nursery_no_lock (size_t requested_size)
        mono_profiler_gc_event (MONO_GC_EVENT_END, 0);
 }
 
-typedef struct
-{
-       FinalizeReadyEntry *list;
-} ScanFinalizerEntriesJobData;
-
-static void
-job_scan_finalizer_entries (WorkerData *worker_data, void *job_data_untyped)
-{
-       ScanFinalizerEntriesJobData *job_data = job_data_untyped;
-
-       scan_finalizer_entries (major_collector.copy_or_mark_object,
-                       job_data->list,
-                       mono_sgen_workers_get_job_gray_queue (worker_data));
-}
-
 static gboolean
 major_do_collection (const char *reason)
 {
@@ -3211,17 +3202,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_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_is_object_alive (object);
 }
 
 static gboolean
@@ -3256,7 +3253,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_is_object_alive (object);
 }
 
 #include "sgen-fin-weak-hash.c"
@@ -3266,6 +3264,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 b3a6b707ecacc6f872234243a5b7d5f9bc0a5053..7f0e4fc989908781dc1204f0356fa2ba6291ff6d 100644 (file)
@@ -524,6 +524,7 @@ struct _SgenMajorCollector {
        void (*copy_object) (void **obj_slot, SgenGrayQueue *queue);
        void (*nopar_copy_object) (void **obj_slot, SgenGrayQueue *queue);
        void* (*alloc_object) (int size, gboolean has_references);
+       void* (*par_alloc_object) (int size, gboolean has_references);
        void (*free_pinned_object) (char *obj, size_t size);
        void (*iterate_objects) (gboolean non_pinned, gboolean pinned, IterateObjectCallbackFunc callback, void *data);
        void (*free_non_pinned_object) (char *obj, size_t size);
@@ -723,7 +724,6 @@ FILE *mono_sgen_get_logfile (void) MONO_INTERNAL;
 
 void mono_sgen_clear_nursery_fragments (void) MONO_INTERNAL;
 void mono_sgen_nursery_allocator_prepare_for_pinning (void) MONO_INTERNAL;
-void mono_sgen_clear_current_nursery_fragment (void) MONO_INTERNAL;
 void mono_sgen_nursery_allocator_set_nursery_bounds (char *nursery_start, char *nursery_end) MONO_INTERNAL;
 mword mono_sgen_build_nursery_fragments (GCMemSection *nursery_section, void **start, int num_entries) MONO_INTERNAL;
 void mono_sgen_init_nursery_allocator (void) MONO_INTERNAL;
@@ -882,6 +882,18 @@ extern LOCK_DECLARE (gc_mutex);
 
 extern int do_pin_stats;
 
+/* Nursery helpers. */
+
+static inline void
+mono_sgen_set_nursery_scan_start (char *p)
+{
+       int idx = (p - (char*)nursery_section->data) / SGEN_SCAN_START_SIZE;
+       char *old = nursery_section->scan_starts [idx];
+       if (!old || old > p)
+               nursery_section->scan_starts [idx] = p;
+}
+
+
 /* Object Allocation */
 
 typedef enum {
index 40bbe2561fb3695dca1f3f22542b5927b505d4d8..2ff7853fd2f4614ca47b84b85a8f15d8dc2bb2d1 100644 (file)
@@ -154,7 +154,7 @@ nopar_copy_object (void **obj_slot, SgenGrayQueue *queue)
         */
 
        if ((forwarded = SGEN_OBJECT_IS_FORWARDED (obj))) {
-               DEBUG (9, g_assert (((MonoVTable*)SGEN_LOAD_VTABLE(obj))->gc_descr));
+               DEBUG (9, g_assert ((*(MonoVTable**)SGEN_LOAD_VTABLE(obj))->gc_descr));
                DEBUG (9, fprintf (gc_debug_file, " (already forwarded to %p)\n", forwarded));
                HEAVY_STAT (++stat_nursery_copy_object_failed_forwarded);
                *obj_slot = forwarded;
index 7098576736649a12b33dd63b655c5c12b9fdb52e..5f48c865114ed5d9eab326dada5f32ec6908d5d2 100644 (file)
@@ -714,6 +714,12 @@ alloc_obj_par (int size, gboolean pinned, gboolean has_references)
 
        return obj;
 }
+
+static void*
+major_par_alloc_object (int size, gboolean has_references)
+{
+       return alloc_obj_par (size, FALSE, has_references);
+}
 #endif
 
 static void*
@@ -2068,6 +2074,9 @@ mono_sgen_marksweep_init
        collector->alloc_degraded = major_alloc_degraded;
        collector->copy_or_mark_object = major_copy_or_mark_object;
        collector->alloc_object = major_alloc_object;
+#ifdef SGEN_PARALLEL_MARK
+       collector->par_alloc_object = major_par_alloc_object;
+#endif
        collector->free_pinned_object = free_pinned_object;
        collector->iterate_objects = major_iterate_objects;
        collector->free_non_pinned_object = major_free_non_pinned_object;
index 49e2b239f437a72f967d405f01934d40b1bbd815..51e5d2a361710bc76d0e97f25c8272c49f3fe9ec 100644 (file)
@@ -106,14 +106,20 @@ struct _Fragment {
        char *fragment_start;
        char *fragment_next; /* the current soft limit for allocation */
        char *fragment_end;
-       Fragment *next_free; /* We use a different entry for the free list so we can avoid SMR */
+       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 FragmentAllocator nursery_allocator;
+
 /* freeelist of fragment structures */
 static Fragment *fragment_freelist = NULL;
 
@@ -131,6 +137,8 @@ int mono_sgen_nursery_bits = 22;
 #endif
 
 
+static void mono_sgen_clear_range (char *start, char *end);
+
 #ifdef HEAVY_STATISTICS
 
 static gint32 stat_wasted_bytes_trailer = 0;
@@ -288,17 +296,17 @@ alloc_fragment (void)
 {
        Fragment *frag = fragment_freelist;
        if (frag) {
-               fragment_freelist = frag->next_free;
-               frag->next_free = NULL;
+               fragment_freelist = frag->next_in_order;
+               frag->next = frag->next_in_order = NULL;
                return frag;
        }
        frag = mono_sgen_alloc_internal (INTERNAL_MEM_FRAGMENT);
-       frag->next_free = NULL;
+       frag->next = frag->next_in_order = NULL;
        return frag;
 }
 
 static void
-add_fragment (char *start, char *end)
+add_fragment (FragmentAllocator *allocator, char *start, char *end)
 {
        Fragment *fragment;
 
@@ -306,21 +314,41 @@ add_fragment (char *start, char *end)
        fragment->fragment_start = start;
        fragment->fragment_next = start;
        fragment->fragment_end = end;
-       fragment->next = unmask (nursery_fragments);
-       nursery_fragments = fragment;
+       fragment->next_in_order = fragment->next = unmask (allocator->region_head);
+
+       allocator->region_head = allocator->alloc_head = fragment;
+}
+
+static void
+release_fragment_list (FragmentAllocator *allocator)
+{
+       Fragment *last = allocator->region_head;
+       if (!last)
+               return;
+
+       /* Find the last fragment in insert order */
+       for (; last->next_in_order; last = last->next_in_order) ;
+
+       last->next_in_order = fragment_freelist;
+       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;
-       if (count > 5)
+       prev = &allocator->alloc_head;
+#ifdef NALLOC_DEBUG
+       if (count++ > 5)
                printf ("retry count for fppf is %d\n", count);
+#endif
 
        cur = unmask (*prev);
 
@@ -368,7 +396,7 @@ claim_remaining_size (Fragment *frag, char *alloc_end)
 }
 
 static void*
-alloc_from_fragment (Fragment *frag, size_t size)
+par_alloc_from_fragment (FragmentAllocator *allocator, Fragment *frag, size_t size)
 {
        char *p = frag->fragment_next;
        char *end = p + size;
@@ -392,15 +420,14 @@ alloc_from_fragment (Fragment *frag, size_t size)
                 * when doing second chance allocation.
                 */
                if (mono_sgen_get_nursery_clear_policy () == CLEAR_AT_TLAB_CREATION && claim_remaining_size (frag, end)) {
-                       /* Clear the remaining space, pinning depends on this. FIXME move this to use phony arrays */
-                       memset (end, 0, frag->fragment_end - end);
+                       mono_sgen_clear_range (end, frag->fragment_end);
                        HEAVY_STAT (InterlockedExchangeAdd (&stat_wasted_bytes_trailer, frag->fragment_end - end));
 #ifdef NALLOC_DEBUG
                        add_alloc_record (end, frag->fragment_end - end, BLOCK_ZEROING);
 #endif
                }
 
-               prev_ptr = find_previous_pointer_fragment (frag);
+               prev_ptr = find_previous_pointer_fragment (allocator, frag);
 
                /*Use Michaels linked list remove*/
 
@@ -424,15 +451,9 @@ 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;
                        }
-
-                       /* No need to membar here since the worst that can happen is a CAS failure. */
-                       do {
-                               frag->next_free = fragment_freelist;
-                       } while (InterlockedCompareExchangePointer ((volatile gpointer*)&fragment_freelist, frag, frag->next_free) != frag->next_free);
-
                        break;
                }
        }
@@ -440,57 +461,194 @@ alloc_from_fragment (Fragment *frag, size_t size)
        return p;
 }
 
-void
-mono_sgen_clear_current_nursery_fragment (void)
+static void*
+serial_alloc_from_fragment (Fragment **previous, Fragment *frag, size_t size)
 {
+       char *p = frag->fragment_next;
+       char *end = p + size;
+
+       if (end > frag->fragment_end)
+               return NULL;
+
+       frag->fragment_next = end;
+
+       if (frag->fragment_end - end < SGEN_MAX_NURSERY_WASTE) {
+               *previous = frag->next;
+               
+               /* Clear the remaining space, pinning depends on this. FIXME move this to use phony arrays */
+               memset (end, 0, frag->fragment_end - end);
+
+               *previous = frag->next;
+       }
+
+       return p;
 }
 
-/* Clear all remaining nursery fragments */
-void
-mono_sgen_clear_nursery_fragments (void)
+static void*
+par_alloc (FragmentAllocator *allocator, size_t size)
 {
        Fragment *frag;
 
-       if (mono_sgen_get_nursery_clear_policy () == CLEAR_AT_TLAB_CREATION) {
-               mono_sgen_clear_current_nursery_fragment ();
+#ifdef NALLOC_DEBUG
+       InterlockedIncrement (&alloc_count);
+#endif
 
-               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));
-                       memset (frag->fragment_next, 0, frag->fragment_end - frag->fragment_next);
+restart:
+       for (frag = unmask (allocator->alloc_head); unmask (frag); frag = unmask (frag->next)) {
+               HEAVY_STAT (InterlockedIncrement (&stat_alloc_iterations));
+
+               if (size <= (frag->fragment_end - frag->fragment_next)) {
+                       void *p = par_alloc_from_fragment (allocator, frag, size);
+                       if (!p) {
+                               HEAVY_STAT (InterlockedIncrement (&stat_alloc_retries));
+                               goto restart;
+                       }
 #ifdef NALLOC_DEBUG
-                       add_alloc_record (frag->fragment_next, frag->fragment_end - frag->fragment_next, CLEAR_NURSERY_FRAGS);
+                       add_alloc_record (p, size, FIXED_ALLOC);
 #endif
+                       return p;
                }
        }
+       return NULL;
 }
 
-void
-mono_sgen_nursery_allocator_prepare_for_pinning (void)
+static void*
+serial_alloc (FragmentAllocator *allocator, size_t size)
+{
+       Fragment *frag;
+       Fragment **previous;
+#ifdef NALLOC_DEBUG
+       InterlockedIncrement (&alloc_count);
+#endif
+
+       previous = &allocator->alloc_head;
+
+       for (frag = *previous; frag; frag = *previous) {
+               HEAVY_STAT (InterlockedIncrement (&stat_alloc_iterations));
+               char *p = serial_alloc_from_fragment (previous, frag, size);
+               if (p) {
+#ifdef NALLOC_DEBUG
+                       add_alloc_record (p, size, FIXED_ALLOC);
+#endif
+                       return p;
+               }
+               previous = &frag->next;
+       }
+       return NULL;
+}
+
+static void*
+par_range_alloc (FragmentAllocator *allocator, size_t desired_size, size_t minimum_size, int *out_alloc_size)
+{
+       Fragment *frag, *min_frag;
+restart:
+       min_frag = NULL;
+
+#ifdef NALLOC_DEBUG
+       InterlockedIncrement (&alloc_count);
+#endif
+
+       for (frag = unmask (allocator->alloc_head); frag; frag = unmask (frag->next)) {
+               int frag_size = frag->fragment_end - frag->fragment_next;
+
+               HEAVY_STAT (InterlockedIncrement (&stat_alloc_range_iterations));
+
+               if (desired_size <= frag_size) {
+                       void *p;
+                       *out_alloc_size = desired_size;
+
+                       p = par_alloc_from_fragment (allocator, frag, desired_size);
+                       if (!p) {
+                               HEAVY_STAT (InterlockedIncrement (&stat_alloc_range_retries));
+                               goto restart;
+                       }
+#ifdef NALLOC_DEBUG
+                       add_alloc_record (p, desired_size, RANGE_ALLOC);
+#endif
+                       return p;
+               }
+               if (minimum_size <= frag_size)
+                       min_frag = frag;
+       }
+
+       /* The second fragment_next read should be ordered in respect to the first code block */
+       mono_memory_barrier ();
+
+       if (min_frag) {
+               void *p;
+               int frag_size;
+
+               frag_size = min_frag->fragment_end - min_frag->fragment_next;
+               if (frag_size < minimum_size)
+                       goto restart;
+
+               *out_alloc_size = frag_size;
+
+               mono_memory_barrier ();
+               p = par_alloc_from_fragment (allocator, min_frag, frag_size);
+
+               /*XXX restarting here is quite dubious given this is already second chance allocation. */
+               if (!p) {
+                       HEAVY_STAT (InterlockedIncrement (&stat_alloc_retries));
+                       goto restart;
+               }
+#ifdef NALLOC_DEBUG
+               add_alloc_record (p, frag_size, RANGE_ALLOC);
+#endif
+               return p;
+       }
+
+       return NULL;
+}
+
+static void
+clear_allocator_fragments (FragmentAllocator *allocator)
 {
        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)) {
-               MonoArray *o;
-
-               g_assert (frag->fragment_end - frag->fragment_next >= sizeof (MonoArray));
-               o = (MonoArray*)frag->fragment_next;
-               memset (o, 0, sizeof (MonoArray));
-               g_assert (mono_sgen_get_array_fill_vtable ());
-               o->obj.vtable = mono_sgen_get_array_fill_vtable ();
-               /* Mark this as not a real object */
-               o->obj.synchronisation = GINT_TO_POINTER (-1);
-               o->max_length = (frag->fragment_end - frag->fragment_next) - sizeof (MonoArray);
-               g_assert (frag->fragment_next + mono_sgen_safe_object_get_size ((MonoObject*)o) == frag->fragment_end);
+       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)
+{
+       if (mono_sgen_get_nursery_clear_policy () == CLEAR_AT_TLAB_CREATION) {
+               clear_allocator_fragments (&nursery_allocator);
+       }
+}
+
+static void
+mono_sgen_clear_range (char *start, char *end)
+{
+       MonoArray *o;
+       size_t size = end - start;
+
+       if (size < sizeof (MonoArray)) {
+               memset (start, 0, size);
+               return;
        }
+
+       o = (MonoArray*)start;
+       o->obj.vtable = mono_sgen_get_array_fill_vtable ();
+       /* Mark this as not a real object */
+       o->obj.synchronisation = GINT_TO_POINTER (-1);
+       o->bounds = NULL;
+       o->max_length = size - sizeof (MonoArray);
+       mono_sgen_set_nursery_scan_start (start);
+       g_assert (start + mono_sgen_safe_object_get_size ((MonoObject*)o) == end);
+}
+
+void
+mono_sgen_nursery_allocator_prepare_for_pinning (void)
+{
+       clear_allocator_fragments (&nursery_allocator);
 }
 
 static mword fragment_total = 0;
@@ -500,7 +658,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);
@@ -515,12 +673,11 @@ 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 */
-               /*TODO place an int[] here instead of the memset if size justify it*/
-               memset (frag_start, 0, frag_size);
+               mono_sgen_clear_range (frag_start, frag_end);
                HEAVY_STAT (InterlockedExchangeAdd (&stat_wasted_bytes_small_areas, frag_size));
        }
 }
@@ -536,14 +693,8 @@ mono_sgen_build_nursery_fragments (GCMemSection *nursery_section, void **start,
        reset_alloc_records ();
 #endif
 
-       while (unmask (nursery_fragments)) {
-               Fragment *nf = unmask (nursery_fragments);
-               Fragment *next = unmask (nf->next);
+       release_fragment_list (&nursery_allocator);
 
-               nf->next_free = fragment_freelist;
-               fragment_freelist = nf;
-               nursery_fragments = next;
-       }
        frag_start = mono_sgen_nursery_start;
        fragment_total = 0;
        /* clear scan starts */
@@ -552,10 +703,10 @@ mono_sgen_build_nursery_fragments (GCMemSection *nursery_section, void **start,
                frag_end = start [i];
                /* remove the pin bit from pinned objects */
                SGEN_UNPIN_OBJECT (frag_end);
-               nursery_section->scan_starts [((char*)frag_end - (char*)nursery_section->data)/SGEN_SCAN_START_SIZE] = frag_end;
+               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);
@@ -566,15 +717,13 @@ 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])));
                }
-               
        }
-
        return fragment_total;
 }
 
@@ -584,7 +733,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);
@@ -603,7 +752,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;
        }
@@ -613,101 +762,22 @@ mono_sgen_can_alloc_size (size_t size)
 void*
 mono_sgen_nursery_alloc (size_t size)
 {
-       Fragment *frag;
        DEBUG (4, fprintf (gc_debug_file, "Searching nursery for size: %zd\n", size));
        size = SGEN_ALIGN_UP (size);
 
        HEAVY_STAT (InterlockedIncrement (&stat_nursery_alloc_requests));
 
-#ifdef NALLOC_DEBUG
-       InterlockedIncrement (&alloc_count);
-#endif
-
-restart:
-       for (frag = unmask (nursery_fragments); 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);
-                       if (!p) {
-                               HEAVY_STAT (InterlockedIncrement (&stat_alloc_retries));
-                               goto restart;
-                       }
-#ifdef NALLOC_DEBUG
-                       add_alloc_record (p, size, FIXED_ALLOC);
-#endif
-                       return p;
-               }
-       }
-       return NULL;
+       return par_alloc (&nursery_allocator, size);
 }
 
 void*
 mono_sgen_nursery_alloc_range (size_t desired_size, size_t minimum_size, int *out_alloc_size)
 {
-       Fragment *frag, *min_frag;
        DEBUG (4, fprintf (gc_debug_file, "Searching for byte range desired size: %zd minimum size %zd\n", desired_size, minimum_size));
 
        HEAVY_STAT (InterlockedIncrement (&stat_nursery_alloc_range_requests));
 
-restart:
-       min_frag = NULL;
-
-#ifdef NALLOC_DEBUG
-       InterlockedIncrement (&alloc_count);
-#endif
-
-       for (frag = unmask (nursery_fragments); frag; frag = unmask (frag->next)) {
-               int frag_size = frag->fragment_end - frag->fragment_next;
-
-               HEAVY_STAT (InterlockedIncrement (&stat_alloc_range_iterations));
-
-               if (desired_size <= frag_size) {
-                       void *p;
-                       *out_alloc_size = desired_size;
-
-                       p = alloc_from_fragment (frag, desired_size);
-                       if (!p) {
-                               HEAVY_STAT (InterlockedIncrement (&stat_alloc_range_retries));
-                               goto restart;
-                       }
-#ifdef NALLOC_DEBUG
-                       add_alloc_record (p, desired_size, RANGE_ALLOC);
-#endif
-                       return p;
-               }
-               if (minimum_size <= frag_size)
-                       min_frag = frag;
-       }
-
-       /* The second fragment_next read should be ordered in respect to the first code block */
-       mono_memory_barrier ();
-
-       if (min_frag) {
-               void *p;
-               int frag_size;
-
-               frag_size = min_frag->fragment_end - min_frag->fragment_next;
-               if (frag_size < minimum_size)
-                       goto restart;
-
-               *out_alloc_size = frag_size;
-
-               mono_memory_barrier ();
-               p = alloc_from_fragment (min_frag, frag_size);
-
-               /*XXX restarting here is quite dubious given this is already second chance allocation. */
-               if (!p) {
-                       HEAVY_STAT (InterlockedIncrement (&stat_alloc_retries));
-                       goto restart;
-               }
-#ifdef NALLOC_DEBUG
-               add_alloc_record (p, frag_size, RANGE_ALLOC);
-#endif
-               return p;
-       }
-
-       return NULL;
+       return par_range_alloc (&nursery_allocator, desired_size, minimum_size, out_alloc_size);
 }
 
 /*** Initialization ***/
@@ -745,7 +815,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 5a1f53dbc982a798153f754b68e5202fdffd6cc7..fc05f4e624bd1fd4938f36119bec60e883162da2 100644 (file)
@@ -51,6 +51,7 @@ static MonoSemType suspend_ack_semaphore;
 static MonoSemType *suspend_ack_semaphore_ptr;
 
 static sigset_t suspend_signal_mask;
+static sigset_t suspend_ack_signal_mask;
 
 static void
 suspend_thread (SgenThreadInfo *info, void *context)
@@ -104,6 +105,14 @@ suspend_thread (SgenThreadInfo *info, void *context)
                mono_gc_get_gc_callbacks ()->thread_suspend_func (info->runtime_data, context);
 
        DEBUG (4, fprintf (gc_debug_file, "Posting suspend_ack_semaphore for suspend from %p %p\n", info, (gpointer)mono_native_thread_id_get ()));
+
+       /*
+       Block the restart signal. 
+       We need to block the restart signal while posting to the suspend_ack semaphore or we race to sigsuspend,
+       which might miss the signal and get stuck.
+       */
+       pthread_sigmask (SIG_BLOCK, &suspend_ack_signal_mask, NULL);
+
        /* notify the waiting thread */
        MONO_SEM_POST (suspend_ack_semaphore_ptr);
        info->stop_count = stop_count;
@@ -114,6 +123,9 @@ suspend_thread (SgenThreadInfo *info, void *context)
                sigsuspend (&suspend_signal_mask);
        } while (info->signal != restart_signal_num && info->doing_handshake);
 
+       /* Unblock the restart signal. */
+       pthread_sigmask (SIG_UNBLOCK, &suspend_ack_signal_mask, NULL);
+
        DEBUG (4, fprintf (gc_debug_file, "Posting suspend_ack_semaphore for resume from %p %p\n", info, (gpointer)mono_native_thread_id_get ()));
        /* notify the waiting thread */
        MONO_SEM_POST (suspend_ack_semaphore_ptr);
@@ -145,6 +157,15 @@ restart_handler (int sig)
        int old_errno = errno;
 
        info = mono_thread_info_current ();
+       /*
+       If the thread info is null is means we're currently in the process of cleaning up,
+       the pthread destructor has already kicked in and it has explicitly invoked the suspend handler.
+       
+       This means this thread has been suspended, TLS is dead, so the only option we have is to
+       rely on pthread_self () and seatch over the thread list.
+       */
+       if (!info)
+               info = mono_thread_info_lookup (pthread_self ());
 
        /*
         * If a thread is dying there might be no thread info.  In
@@ -154,7 +175,6 @@ restart_handler (int sig)
                info->signal = restart_signal_num;
                DEBUG (4, fprintf (gc_debug_file, "Restart handler in %p %p\n", info, (gpointer)mono_native_thread_id_get ()));
        }
-
        errno = old_errno;
 }
 
@@ -254,6 +274,10 @@ mono_sgen_os_init (void)
 
        sigfillset (&suspend_signal_mask);
        sigdelset (&suspend_signal_mask, restart_signal_num);
+
+       sigemptyset (&suspend_ack_signal_mask);
+       sigaddset (&suspend_ack_signal_mask, restart_signal_num);
+       
 }
 
 int
index ee5c5ec55159a3e970590bbd74db2d8e1b4642a5..10f7d2a336116bc1aba5f8b294ae3a47e5d36404 100644 (file)
@@ -120,6 +120,11 @@ mono_sgen_pinning_setup_section (GCMemSection *section)
        section->pin_queue_num_entries = next_pin_slot;
 }
 
+void
+mono_sgen_pinning_trim_queue_to_section (GCMemSection *section)
+{
+       next_pin_slot = section->pin_queue_num_entries;
+}
 
 void
 mono_sgen_pin_queue_clear_discarded_entries (GCMemSection *section, int max_pin_slot)
@@ -128,6 +133,9 @@ mono_sgen_pin_queue_clear_discarded_entries (GCMemSection *section, int max_pin_
        void **end = pin_queue + max_pin_slot;
        void *addr;
 
+       if (!start)
+               return;
+
        for (; start < end; ++start) {
                addr = *start;
                if ((char*)addr < section->data || (char*)addr > section->end_data)
index 75b0f63047229b83bcd1bb2d64d8debcab8e5728..c9ef0004e44cfd52236c0fde5c7b5556e8b11e92 100644 (file)
@@ -1,4 +1,6 @@
 /*
+void
+mono_sgen_pinning_trim_queue_to_section (GCMemSection *section)
  * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
  *
  * Permission is hereby granted, free of charge, to any person obtaining
@@ -36,7 +38,8 @@ void mono_sgen_init_pinning (void) MONO_INTERNAL;
 void mono_sgen_finish_pinning (void) MONO_INTERNAL;
 void mono_sgen_pin_queue_clear_discarded_entries (GCMemSection *section, int max_pin_slot) MONO_INTERNAL;
 int mono_sgen_get_pinned_count (void) MONO_INTERNAL;
-void mono_sgen_pinning_setup_section (GCMemSection *section);
+void mono_sgen_pinning_setup_section (GCMemSection *section) MONO_INTERNAL;
+void mono_sgen_pinning_trim_queue_to_section (GCMemSection *section) MONO_INTERNAL;
 
 void mono_sgen_dump_pin_queue (void) MONO_INTERNAL;
 
index 9ee0bb46bb7949c1e52c440c39ac81cecda1e59b..a0f98fb9d86d7e8d71ca7eb400b13b1ec0da6004 100644 (file)
@@ -918,6 +918,8 @@ mono_thread_detach (MonoThread *thread)
 
        THREAD_DEBUG (g_message ("%s: mono_thread_detach for %p (%"G_GSIZE_FORMAT")", __func__, thread, (gsize)thread->internal_thread->tid));
        
+       mono_profiler_thread_end (thread->internal_thread->tid);
+
        thread_cleanup (thread->internal_thread);
 
        SET_CURRENT_OBJECT (NULL);
index 5f3ea84517ad2531339477f398ccaf67c8b1f5c1..35168cf85e135bc9f9cb0bbee1da9fa939aed001 100644 (file)
@@ -32,4 +32,5 @@
 /buildver.h
 /TAGS
 /mono-sgen
+/buildver-sgen.h
 
index cbc9bbb905a4f785f546cb2ddc39d816283cc493..7be273943ef95c312e40392644af360070fca12b 100644 (file)
@@ -101,11 +101,14 @@ boehm_static_libraries = libmono-static.la
 boehm_binaries  = mono
 endif
 
+if DISABLE_EXECUTABLES
+else
 if HOST_WIN32
 bin_PROGRAMS = $(boehm_binaries) $(sgen_binaries) monow
 else
 bin_PROGRAMS = $(boehm_binaries) $(sgen_binaries)
 endif
+endif
 
 noinst_PROGRAMS = genmdesc
 
@@ -114,7 +117,12 @@ shared_libraries = $(boehm_libraries) $(sgen_libraries)
 endif
 
 lib_LTLIBRARIES = $(shared_libraries)
+
+if DISABLE_EXECUTABLES
+noinst_LTLIBRARIES =
+else
 noinst_LTLIBRARIES = $(boehm_static_libraries) $(sgen_static_libraries)
+endif
 
 if MOONLIGHT
 noinst_LTLIBRARIES += libmono-moon.la
index 21a67ba800e1a2494b7070909fae887d0a88a0f7..e32d6e49bc591f36abe744c2d64c4bd251a38fc6 100644 (file)
@@ -1939,7 +1939,7 @@ decode_llvm_mono_eh_frame (MonoAotModule *amodule, MonoDomain *domain,
        guint8 *fde, *cie, *code_start, *code_end;
        int version, fde_count;
        gint32 *table;
-       int i, j, pos, left, right, offset, offset1, offset2, code_len;
+       int i, j, pos, left, right, offset, offset1, offset2, code_len, func_encoding;
        MonoJitExceptionInfo *ei;
        guint32 fde_len, ei_len, nested_len, nindex;
        gpointer *type_info;
@@ -1954,8 +1954,14 @@ decode_llvm_mono_eh_frame (MonoAotModule *amodule, MonoDomain *domain,
 
        /* Header */
        version = *p;
-       g_assert (version == 1);
+       g_assert (version == 1 || version == 2);
        p ++;
+       if (version == 2) {
+               func_encoding = *p;
+               p ++;
+       } else {
+               func_encoding = DW_EH_PE_pcrel;
+       }
        p = ALIGN_PTR_TO (p, 4);
 
        fde_count = *(guint32*)p;
@@ -1974,11 +1980,23 @@ decode_llvm_mono_eh_frame (MonoAotModule *amodule, MonoDomain *domain,
                pos = (left + right) / 2;
 
                offset1 = table [(pos * 2)];
-               if (pos + 1 == fde_count)
+               if (pos + 1 == fde_count) {
                        /* FIXME: */
                        offset2 = amodule->code_end - amodule->code;
-               else
+               } else {
+                       /* Encoded as DW_EH_PE_pcrel, but relative to mono_eh_frame */
                        offset2 = table [(pos + 1) * 2];
+               }
+
+               if (func_encoding == DW_EH_PE_absptr) {
+                       /*
+                        * Encoded as DW_EH_PE_absptr, because the ios linker can move functions inside object files to make thumb work,
+                        * so the offsets between two symbols in the text segment are not assembler constant.
+                        */
+                       g_assert (sizeof(gpointer) == 4);
+                       offset1 -= (gint32)(gsize)amodule->mono_eh_frame;
+                       offset2 -= (gint32)(gsize)amodule->mono_eh_frame;
+               }
 
                if (offset < offset1)
                        right = pos;
@@ -1988,13 +2006,22 @@ decode_llvm_mono_eh_frame (MonoAotModule *amodule, MonoDomain *domain,
                        break;
        }
 
-       code_start = amodule->mono_eh_frame + table [(pos * 2)];
-       /* This won't overflow because there is +1 entry in the table */
-       code_end = amodule->mono_eh_frame + table [(pos * 2) + 2];
+       if (func_encoding == DW_EH_PE_absptr) {
+               code_start = (gpointer)(gsize)table [(pos * 2)];
+               code_end = (gpointer)(gsize)table [(pos * 2) + 2];
+       } else {
+               code_start = amodule->mono_eh_frame + table [(pos * 2)];
+               /* This won't overflow because there is +1 entry in the table */
+               code_end = amodule->mono_eh_frame + table [(pos * 2) + 2];
+       }
        code_len = code_end - code_start;
 
        g_assert (code >= code_start && code < code_end);
 
+       if (amodule->thumb_end && (guint8*)code_start < amodule->thumb_end)
+               /* Clear thumb flag */
+               code_start = (char*)(((mgreg_t)code_start) & ~1);
+
        fde = amodule->mono_eh_frame + table [(pos * 2) + 1];   
        /* This won't overflow because there is +1 entry in the table */
        fde_len = table [(pos * 2) + 2 + 1] - table [(pos * 2) + 1];
index 4bd0175c6bb6b38db999bedc8f3920c334d3a031..b24a426545a0edd24e4cab2a67a8d6bc449bd291 100644 (file)
@@ -381,3 +381,8 @@ s390_long_add_ovf: dest:i src1:i src2:i len:32
 s390_long_add_ovf_un: dest:i src1:i src2:i len:32
 s390_long_sub_ovf: dest:i src1:i src2:i len:32
 s390_long_sub_ovf_un: dest:i src1:i src2:i len:32
+
+gc_liveness_def: len:0
+gc_liveness_use: len:0
+gc_spill_slot_liveness_def: len:0
+gc_param_slot_liveness_def: len:0
index 63a13bdd5af3eb0efb26adbeb3141d251774f38c..20daf88d352fcad687a2ed706c3574c49f090c37 100644 (file)
@@ -862,6 +862,8 @@ mono_debugger_agent_parse_options (char *options)
                }
        }
 
+       //agent_config.log_level = 0;
+
        if (agent_config.transport == NULL) {
                fprintf (stderr, "debugger-agent: The 'transport' option is mandatory.\n");
                exit (1);
@@ -2616,7 +2618,7 @@ resume_vm (void)
        g_assert (suspend_count > 0);
        suspend_count --;
 
-       DEBUG(1, fprintf (log_file, "[%p] Resuming vm...\n", (gpointer)GetCurrentThreadId ()));
+       DEBUG(1, fprintf (log_file, "[%p] Resuming vm, suspend count=%d...\n", (gpointer)GetCurrentThreadId (), suspend_count));
 
        if (suspend_count == 0) {
                // FIXME: Is it safe to call this inside the lock ?
@@ -3621,13 +3623,15 @@ thread_end (MonoProfiler *prof, uintptr_t tid)
        mono_loader_lock ();
        thread = mono_g_hash_table_lookup (tid_to_thread, (gpointer)tid);
        if (thread) {
-               tls = mono_g_hash_table_lookup (thread_to_tls, thread);
-               /* FIXME: Maybe we need to free this instead, but some code can't handle that */
-               tls->terminated = TRUE;
                mono_g_hash_table_remove (tid_to_thread_obj, (gpointer)tid);
-               /* Can't remove from tid_to_thread, as that would defeat the check in thread_start () */
-               MONO_GC_UNREGISTER_ROOT (tls->thread);
-               tls->thread = NULL;
+               tls = mono_g_hash_table_lookup (thread_to_tls, thread);
+               if (tls) {
+                       /* FIXME: Maybe we need to free this instead, but some code can't handle that */
+                       tls->terminated = TRUE;
+                       /* Can't remove from tid_to_thread, as that would defeat the check in thread_start () */
+                       MONO_GC_UNREGISTER_ROOT (tls->thread);
+                       tls->thread = NULL;
+               }
        }
        mono_loader_unlock ();
 
@@ -4275,7 +4279,7 @@ process_breakpoint_inner (DebuggerTlsData *tls)
        ss_reqs = g_ptr_array_new ();
        ss_reqs_orig = g_ptr_array_new ();
 
-       DEBUG(1, fprintf (log_file, "[%p] Breakpoint hit, method=%s, offset=0x%x.\n", (gpointer)GetCurrentThreadId (), ji->method->name, native_offset));
+       DEBUG(1, fprintf (log_file, "[%p] Breakpoint hit, method=%s, ip=%p, offset=0x%x.\n", (gpointer)GetCurrentThreadId (), ji->method->name, ip, native_offset));
 
        mono_loader_lock ();
 
@@ -5892,7 +5896,7 @@ invoke_method (void)
        DebuggerTlsData *tls;
        InvokeData *invoke;
        int id;
-       int err;
+       int i, err;
        Buffer buf;
        static void (*restore_context) (void *);
        MonoContext restore_ctx;
@@ -5928,8 +5932,10 @@ invoke_method (void)
        err = do_invoke_method (tls, &buf, invoke);
 
        /* Start suspending before sending the reply */
-       if (!(invoke->flags & INVOKE_FLAG_SINGLE_THREADED))
-               suspend_vm ();
+       if (!(invoke->flags & INVOKE_FLAG_SINGLE_THREADED)) {
+               for (i = 0; i < invoke->suspend_count; ++i)
+                       suspend_vm ();
+       }
 
        send_reply_packet (id, err, &buf);
        
@@ -6160,7 +6166,7 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf)
                int objid = decode_objid (p, &p, end);
                MonoThread *thread;
                DebuggerTlsData *tls;
-               int err, flags;
+               int i, count, err, flags;
 
                err = get_object (objid, (MonoObject**)&thread);
                if (err)
@@ -6188,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;
@@ -6197,10 +6203,14 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf)
                tls->pending_invoke->endp = tls->pending_invoke->p + (end - p);
                tls->pending_invoke->suspend_count = suspend_count;
 
-               if (flags & INVOKE_FLAG_SINGLE_THREADED)
+               if (flags & INVOKE_FLAG_SINGLE_THREADED) {
                        resume_thread (THREAD_TO_INTERNAL (thread));
-               else
-                       resume_vm ();
+               }
+               else {
+                       count = suspend_count;
+                       for (i = 0; i < count; ++i)
+                               resume_vm ();
+               }
                break;
        }
        case CMD_VM_ABORT_INVOKE: {
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 9e9af931519dd70f130100e8f6285b12802e7617..3e926c59de292e1489303d02f9ff2d67a8cb753b 100644 (file)
@@ -8012,6 +8012,8 @@ mono_arch_finish_init (void)
                appdomain_tls_offset = -1;
        if (lmf_tls_offset >= 64)
                lmf_tls_offset = -1;
+       if (lmf_addr_tls_offset >= 64)
+               lmf_addr_tls_offset = -1;
 #else
 #ifdef MONO_XEN_OPT
        optimize_for_xen = access ("/proc/xen", F_OK) == 0;
index 43c7cfcd05a447afe9b7245bc5d618283f9dae90..fbb737c23ef09ef497f7ca434ccefb986a8340d9 100644 (file)
@@ -376,6 +376,11 @@ encode_frame_reg (int frame_reg)
                return 0;
        else if (frame_reg == ARMREG_FP)
                return 1;
+#elif defined(TARGET_S390X)
+       if (frame_reg == S390_SP)
+               return 0;
+       else if (frame_reg == S390_FP)
+               return 1;
 #else
        NOT_IMPLEMENTED;
 #endif
@@ -401,6 +406,11 @@ decode_frame_reg (int encoded)
                return ARMREG_SP;
        else if (encoded == 1)
                return ARMREG_FP;
+#elif defined(TARGET_S390X)
+       if (encoded == 0)
+               return S390_SP;
+       else if (encoded == 1)
+               return S390_FP;
 #else
        NOT_IMPLEMENTED;
 #endif
@@ -418,6 +428,8 @@ static int callee_saved_regs [] = { AMD64_RBP, AMD64_RBX, AMD64_R12, AMD64_R13,
 static int callee_saved_regs [] = { X86_EBX, X86_ESI, X86_EDI };
 #elif defined(TARGET_ARM)
 static int callee_saved_regs [] = { ARMREG_V1, ARMREG_V2, ARMREG_V3, ARMREG_V4, ARMREG_V5, ARMREG_V7, ARMREG_FP };
+#elif defined(TARGET_S390X)
+static int callee_saved_regs [] = { s390_r6, s390_r7, s390_r8, s390_r9, s390_r10, s390_r11, s390_r12, s390_r13, s390_r14 };
 #endif
 
 static guint32
@@ -653,6 +665,11 @@ get_frame_pointer (MonoContext *ctx, int frame_reg)
                        return (mgreg_t)MONO_CONTEXT_GET_SP (ctx);
                else if (frame_reg == ARMREG_FP)
                        return (mgreg_t)MONO_CONTEXT_GET_BP (ctx);
+#elif defined(TARGET_S390X)
+               if (frame_reg == S390_SP)
+                       return (mgreg_t)MONO_CONTEXT_GET_SP (ctx);
+               else if (frame_reg == S390_FP)
+                       return (mgreg_t)MONO_CONTEXT_GET_BP (ctx);
 #endif
                g_assert_not_reached ();
                return 0;
@@ -1981,7 +1998,7 @@ compute_frame_size (MonoCompile *cfg)
        /* Compute min/max offsets from the fp */
 
        /* Locals */
-#if defined(TARGET_AMD64) || defined(TARGET_X86) || defined(TARGET_ARM)
+#if defined(TARGET_AMD64) || defined(TARGET_X86) || defined(TARGET_ARM) || defined(TARGET_S390X)
        locals_min_offset = ALIGN_TO (cfg->locals_min_stack_offset, SIZEOF_SLOT);
        locals_max_offset = cfg->locals_max_stack_offset;
 #else
@@ -2033,6 +2050,8 @@ compute_frame_size (MonoCompile *cfg)
        min_offset = MIN (min_offset, - (cfg->arch.sp_fp_offset + cfg->arch.param_area_size));
 #elif defined(TARGET_ARM)
        // FIXME:
+#elif defined(TARGET_s390X)
+       // FIXME:
 #else
        NOT_IMPLEMENTED;
 #endif
index ba7633ea86ef817bd00c370162bb57487b8c8fb1..67fbe4b44a81d677838d440aefe18a5aabf3f47f 100644 (file)
@@ -2180,6 +2180,8 @@ printf("%s %4d cookine %x\n",__FUNCTION__,__LINE__,cfg->sig_cookie);
                curinst++;
        }
 
+       cfg->locals_min_stack_offset = offset;
+
        curinst = cfg->locals_start;
        for (iVar = curinst; iVar < cfg->num_varinfo; ++iVar) {
                inst = cfg->varinfo [iVar];
@@ -2207,6 +2209,8 @@ printf("%s %4d cookine %x\n",__FUNCTION__,__LINE__,cfg->sig_cookie);
                                iVar, inst->inst_offset, size));
        }
 
+       cfg->locals_max_stack_offset = offset;
+
        /*------------------------------------------------------*/
        /* Allow space for the trace method stack area if needed*/
        /*------------------------------------------------------*/
@@ -2478,6 +2482,12 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
                                                         frmReg, ainfo->offparm);
                                MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG,
                                                             ainfo->reg, ainfo->offset, treg);
+
+                               if (cfg->compute_gc_maps) {
+                                       MonoInst *def;
+
+                                       EMIT_NEW_GC_PARAM_SLOT_LIVENESS_DEF (cfg, def, ainfo->offset, t);
+                               }
                        }
                        break;
                }
@@ -2589,6 +2599,12 @@ mono_arch_emit_outarg_vt (MonoCompile *cfg, MonoInst *ins, MonoInst *src)
 
                MONO_EMIT_NEW_MOVE (cfg, srcReg, ainfo->offparm,
                                                         src->dreg, 0, size);
+
+               if (cfg->compute_gc_maps) {
+                       MonoInst *def;
+
+                       EMIT_NEW_GC_PARAM_SLOT_LIVENESS_DEF (cfg, def, ainfo->offset, &ins->klass->byval_arg);
+               }
        }
 }
 
@@ -4871,6 +4887,15 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                case OP_MEMORY_BARRIER: {
                }
                        break;
+               case OP_GC_LIVENESS_DEF:
+               case OP_GC_LIVENESS_USE:
+               case OP_GC_PARAM_SLOT_LIVENESS_DEF:
+                       ins->backend.pc_offset = code - cfg->native_code;
+                       break;
+               case OP_GC_SPILL_SLOT_LIVENESS_DEF:
+                       ins->backend.pc_offset = code - cfg->native_code;
+                       bb->spill_slot_defs = g_slist_prepend_mempool (cfg->mempool, bb->spill_slot_defs, ins);
+                       break;
                default:
                        g_warning ("unknown opcode %s in %s()\n", mono_inst_name (ins->opcode), __FUNCTION__);
                        g_assert_not_reached ();
index b0c1d46ab2afd3b7153f74f57ae25fedbe1cfad8..930ef14de7e8d2ac617a8ea736e248c374f02bf2 100644 (file)
@@ -123,6 +123,7 @@ typedef struct
 #define MONO_ARCH_SOFT_DEBUG_SUPPORTED                 1
 #define MONO_ARCH_HAVE_CONTEXT_SET_INT_REG             1
 #define MONO_ARCH_USE_SIGACTION                        1
+#define MONO_ARCH_GC_MAPS_SUPPORTED                    1
 
 #define S390_STACK_ALIGNMENT            8
 #define S390_FIRST_ARG_REG             s390_r2
index f93e9bcefb8827927e1f5623b48c940e29f9a730..1d5be3190da6ae669686d365b8226e45ef936234 100644 (file)
@@ -92,6 +92,24 @@ typedef struct {
 #define mono_add_unwind_op_same_value(op_list,code,buf,reg) do { (op_list) = g_slist_append ((op_list), mono_create_unwind_op ((code) - (buf), DW_CFA_same_value, (reg), 0)); } while (0)
 #define mono_add_unwind_op_offset(op_list,code,buf,reg,offset) do { (op_list) = g_slist_append ((op_list), mono_create_unwind_op ((code) - (buf), DW_CFA_offset, (reg), (offset))); } while (0)
 
+/* Pointer Encoding in the .eh_frame */
+enum {
+       DW_EH_PE_absptr = 0x00,
+       DW_EH_PE_omit = 0xff,
+
+       DW_EH_PE_udata4 = 0x03,
+       DW_EH_PE_sdata4 = 0x0b,
+       DW_EH_PE_sdata8 = 0x0c,
+
+       DW_EH_PE_pcrel = 0x10,
+       DW_EH_PE_textrel = 0x20,
+       DW_EH_PE_datarel = 0x30,
+       DW_EH_PE_funcrel = 0x40,
+       DW_EH_PE_aligned = 0x50,
+
+       DW_EH_PE_indirect = 0x80
+};
+
 int
 mono_hw_reg_to_dwarf_reg (int reg) MONO_INTERNAL;
 
index 5774b99f09e2b8feb2c7afe17e06fa1538dac069..fe68ceede1e778944aca2b2a3eb7ee7df40b640c 100644 (file)
@@ -801,6 +801,10 @@ mono_arch_init (void)
 void
 mono_arch_cleanup (void)
 {
+       if (ss_trigger_page)
+               mono_vfree (ss_trigger_page, mono_pagesize ());
+       if (bp_trigger_page)
+               mono_vfree (bp_trigger_page, mono_pagesize ());
        DeleteCriticalSection (&mini_arch_mutex);
 }
 
index 55b938b9afa309476266ee7ddf4bd53eee0d79f2..11caa60166c115018f96ac558e85ac15bbdab1c2 100644 (file)
@@ -613,24 +613,6 @@ decode_cie_op (guint8 *p, guint8 **endp)
        *endp = p;
 }
 
-/* Pointer Encoding in the .eh_frame */
-enum {
-       DW_EH_PE_absptr = 0x00,
-       DW_EH_PE_omit = 0xff,
-
-       DW_EH_PE_udata4 = 0x03,
-       DW_EH_PE_sdata4 = 0x0b,
-       DW_EH_PE_sdata8 = 0x0c,
-
-       DW_EH_PE_pcrel = 0x10,
-       DW_EH_PE_textrel = 0x20,
-       DW_EH_PE_datarel = 0x30,
-       DW_EH_PE_funcrel = 0x40,
-       DW_EH_PE_aligned = 0x50,
-
-       DW_EH_PE_indirect = 0x80
-};
-
 static gint64
 read_encoded_val (guint32 encoding, guint8 *p, guint8 **endp)
 {
index cc3d41474d0ea8d252cc34a6ff4ce602efd7b94d..58c0b98da2479de9d324a3e03c141416a5bf32c3 100644 (file)
@@ -16,6 +16,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
+#include <glib.h>
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
@@ -1858,6 +1859,15 @@ helper_thread (void* arg)
                tv.tv_sec = 1;
                tv.tv_usec = 0;
                len = select (max_fd + 1, &rfds, NULL, NULL, &tv);
+               
+               if (len < 0) {
+                       if (errno == EINTR)
+                               continue;
+                       
+                       g_warning ("Error in proflog server: %s", strerror (errno));
+                       return NULL;
+               }
+               
                if (FD_ISSET (prof->pipes [0], &rfds)) {
                        char c;
                        int r = read (prof->pipes [0], &c, 1);
index a72f337e8bd5c6f5c47e75a34ea604cd44c040a4..971cb1681255a2bfaf276d63fea39f1a1805c60b 100644 (file)
@@ -379,6 +379,7 @@ BASE_TEST_CS_SRC=           \
        bug-696593.cs   \
        bug-705140.cs   \
        bug-1147.cs     \
+       mono-path.cs    \
        bug-bxc-795.cs
 
 TEST_CS_SRC_DIST=      \
@@ -607,7 +608,7 @@ if ARM
 test-sgen : sgen-tests
 else
 if S390x
-test-sgen : sgen-tests
+test-sgen : sgen-regular-tests
 endif
 endif
 endif
index b5be6e8de5445f524f0bf95008d9e1fae2182f4e..d541e5860c6e674f004bed8f799b99dc7eb9040d 100644 (file)
@@ -8,6 +8,7 @@ using System;
 using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 
+
 public class Tests
 {
 
@@ -653,6 +654,13 @@ public class Tests
                                }
                        }
                        #endregion // SafeArray Tests
+
+                       #region COM Visible Test
+                       TestVisible test_vis = new TestVisible();
+                       IntPtr pDisp = Marshal.GetIDispatchForObject(test_vis);
+                       if (pDisp == IntPtr.Zero)
+                               return 200;
+                       #endregion 
                }
 
         return 0;
@@ -1214,3 +1222,7 @@ public class Tests
                return 0;
        }
 }
+
+public class TestVisible
+{
+}
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 */
diff --git a/mono/tests/mono-path.cs b/mono/tests/mono-path.cs
new file mode 100644 (file)
index 0000000..8f60e11
--- /dev/null
@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+
+public class Program
+{
+       static bool failure;
+
+       [DllImport ("__Internal")]
+       static extern string mono_path_canonicalize (string input);
+
+       static void CanonicalizeAssert (string input, string expected)
+       {
+               string actual = mono_path_canonicalize (input);
+               if (expected != actual) {
+                       failure = true;
+                       Console.WriteLine ("ERROR: Expected canonicalization of '{0}' to be '{1}', but it was '{2}'.", input, expected, actual);
+               } else {
+                       Console.WriteLine ("SUCCESS: Canonicalization of '{0}' => '{1}'", input, actual);
+               }
+       }
+       
+       static void CanonicalizeTest ()
+       {
+               bool isWindows = !(((int)Environment.OSVersion.Platform == 4) || ((int)Environment.OSVersion.Platform == 128));
+
+               if (!isWindows) {
+                       CanonicalizeAssert ("", Environment.CurrentDirectory);
+                       CanonicalizeAssert ("/", "/");
+                       CanonicalizeAssert ("/..", "/");
+                       CanonicalizeAssert ("/foo", "/foo");
+                       CanonicalizeAssert ("/foo/././", "/foo");
+                       CanonicalizeAssert ("/../../foo", "/foo");
+                       CanonicalizeAssert ("/foo/", "/foo");
+                       CanonicalizeAssert ("/foo/../../../", "/");
+                       CanonicalizeAssert ("/foo/../../..", "/");
+               }
+       }
+       
+       public static int Main()
+       {
+               CanonicalizeTest ();
+               return failure ? 1 : 0;
+       }
+}
\ No newline at end of file
index d449564910191746063b7e011d99a36f67755f68..2c9e0941bb930e77d7a9c49ede3f449af8d4def9 100644 (file)
@@ -436,8 +436,8 @@ typedef struct ucontext MonoContext;
        } while (0) 
 
 #define MONO_CONTEXT_GET_IP(ctx) (gpointer) (ctx)->uc_mcontext.psw.addr
-#define MONO_CONTEXT_GET_BP(ctx) MONO_CONTEXT_GET_SP((ctx))
 #define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->uc_mcontext.gregs[15]))
+#define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->uc_mcontext.gregs[11]))
 
 #define MONO_CONTEXT_GET_CURRENT(ctx)  \
        __asm__ __volatile__(   \
index e04c3dfe8b9f46519816c61b90b9a835e9f2c44d..88b5d25a71904ff89e0923b1b7f967034f0b3c34 100644 (file)
@@ -33,6 +33,8 @@
 
 /* For Native Client, the above is not true.  Since there is no getcwd we fill */
 /* in the file being passed in relative to '.' and don't resolve it            */
+
+/* There are a couple of tests for this method in mono/test/mono-path.cs */
 gchar *
 mono_path_canonicalize (const char *path)
 {
@@ -90,7 +92,20 @@ mono_path_canonicalize (const char *path)
 #endif
        
        if (dest != lastpos) strcpy (dest, lastpos);
-       return g_strreverse (abspath);
+       
+       g_strreverse (abspath);
+
+       /* We strip away all trailing dir separators. This is not correct for the root directory,
+        * since we'll return an empty string, so re-append a dir separator if there is none in the
+        * result */
+       if (strchr (abspath, G_DIR_SEPARATOR) == NULL) {
+               int len = strlen (abspath);
+               abspath = g_realloc (abspath, len + 2);
+               abspath [len] = G_DIR_SEPARATOR;
+               abspath [len+1] = 0;
+       }
+
+       return abspath;
 }
 
 /*
index 014c75502b49c66419296322ff5ebc4b8cc01ab0..2d8715c9069242e09e5871400d11722825d92051 100644 (file)
@@ -66,6 +66,7 @@
 /mozroots
 /nunit-console
 /nunit-console2
+/nunit-console4
 /pdb2mdb
 /permview
 /peverify