/// <summary>
        /// Maps a navigation parameters to target action parameter.
        /// </summary>
        /// <param name="controllerContext">The controller context.</param>
        /// <param name="bindingContext">The binding context.</param>
        /// <returns>
        /// The value that will be supplied to the action.
        /// </returns>
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            var requestParameter = bindingContext.RouteValues.FirstOrDefault(x => string.Equals(x.Key, bindingContext.TargetParameterName, StringComparison.InvariantCultureIgnoreCase));
            if (requestParameter.Key == null)
            {
                TraceSources.MagellanSource.TraceError("DefaultModelBinder could not find a parameter '{0}' for the action method '{1}' in the list of navigation parameters.", controllerContext.ActionName, bindingContext.TargetParameterName);
                throw new ArgumentException(string.Format("The action '{0}' on controller '{1}' requires a parameter named '{2}', which was not supplied.",
                    controllerContext.ActionName,
                    controllerContext.Controller.GetType().FullName,
                    bindingContext.TargetParameterName));
            }

            var source = requestParameter.Value;
            if (source == null)
            {
                TraceSources.MagellanSource.TraceWarning("The parameter '{0}' which was supplied to action '{1}' was null, but the parameter is declared as type '{2}', which is a value type. DefaultModelBinder is creating a new default instance of the type instead.",
                    bindingContext.TargetParameterName,
                    controllerContext.ActionName,
                    bindingContext.TargetParameterType
                    );

                return bindingContext.TargetParameterType.IsValueType
                    ? Activator.CreateInstance(bindingContext.TargetParameterType)
                    : null;
            }

            if (bindingContext.TargetParameterType.IsAssignableFrom(source.GetType()))
            {
                return source;
            }
            return Convert.ChangeType(source, bindingContext.TargetParameterType, CultureInfo.InvariantCulture);
        }
        /// <summary>
        /// Maps a navigation parameters to target action parameter.
        /// </summary>
        /// <param name="request">The controller context.</param>
        /// <param name="bindingContext">The binding context.</param>
        /// <returns>
        /// The value that will be supplied to the action.
        /// </returns>
        public object BindModel(ResolvedNavigationRequest request, ModelBindingContext bindingContext)
        {
            var requestParameter = bindingContext.RouteValues.FirstOrDefault(x => string.Equals(x.Key, bindingContext.TargetParameterName, StringComparison.InvariantCultureIgnoreCase));
            if (requestParameter.Key == null)
            {
                TraceSources.MagellanSource.TraceError("DefaultModelBinder could not find a parameter '{0}' for the method '{1}' in the list of navigation parameters.", request.RouteValues, bindingContext.TargetParameterName);
                throw new ModelBindingException(bindingContext, request);
            }


            var source = requestParameter.Value;
            var targetType = bindingContext.TargetParameterType;

            return AmazingConverter.Convert(source, targetType);
        }
        private static string BuildMessage(ModelBindingContext context, ResolvedNavigationRequest request)
        {
            var message = new StringBuilder();
            message.AppendFormat(
                "The method '{0}' on target '{1}' requires a parameter named '{2}', which was not supplied.",
                context.TargetMethod.Name,
                context.TargetMethod.DeclaringType.FullName,
                context.TargetParameterName
                );

            message.AppendLine().AppendLine();

            message.Append("Candidate route parameters are:");
            foreach (var key in request.RouteValues.Keys)
            {
                message.AppendLine().Append(" - " + key);
            }
            return message.ToString();
        }
        /// <summary>
        /// Executes the action on the controller using the parameters and model binders in the current request.
        /// </summary>
        /// <param name="controllerContext">The controller context.</param>
        /// <param name="modelBinders">The model binders.</param>
        /// <returns>
        /// The <see cref="ActionResult"/> returned by the controller action.
        /// </returns>
        public ActionResult Execute(ControllerContext controllerContext, ModelBinderDictionary modelBinders)
        {
            var arguments = new List<object>();
            foreach (var parameterInfo in method.GetParameters())
            {
                var bindingContext = new ModelBindingContext(parameterInfo.Name, Method, parameterInfo.ParameterType, controllerContext.Request.RouteValues);
                var binder = modelBinders.GetBinder(parameterInfo.ParameterType);
                var argument = binder.BindModel(controllerContext.Request, bindingContext);
                arguments.Add(argument);
            }

            try
            {
                var wrapper = DelegateInvoker.CreateInvoker(controller, method);
                return (ActionResult) wrapper.Call(arguments.ToArray());
            }
            catch (Exception ex)
            {
                TraceSources.MagellanSource.TraceError(ex, "The action '{0}' on controller '{1} threw an exception.", controllerContext.ActionName, controllerContext.ActionName);
                throw;
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="ModelBindingException"/> class.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="request">The request.</param>
 public ModelBindingException(ModelBindingContext context, ResolvedNavigationRequest request)
     : base(BuildMessage(context, request))
 {
 }
        /// <summary>
        /// Discovers and invokes any Initialize methods according to the initializeMethodSelector passed to 
        /// the constructor.
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="request">The request.</param>
        protected virtual void CallInitializeMethods(object model, ResolvedNavigationRequest request)
        {
            if (model == null || initializeMethodSelector == null)
                return;

            var initializers = model.GetType().GetMethods() as IEnumerable<MethodInfo>;
            var initializer = initializeMethodSelector(initializers);
            if (initializer == null)
            {
                return;
            }

            var arguments = new List<object>();
            foreach (var parameterInfo in initializer.GetParameters())
            {
                var bindingContext = new ModelBindingContext(parameterInfo.Name, initializer, parameterInfo.ParameterType, request.RouteValues);
                var binder = modelBinders.GetBinder(parameterInfo.ParameterType);
                var argument = binder.BindModel(request, bindingContext);
                arguments.Add(argument);
            }

            initializer.Invoke(model, arguments.ToArray());
        }