/// <summary>
        /// Gets the and create list.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="map">The map.</param>
        /// <returns></returns>
        private List<ControllerInvocationInfo> getAndCreateList(ControllerInvocationInfo key, Dictionary<ControllerInvocationInfo, List<ControllerInvocationInfo>> map)
        {
            List<ControllerInvocationInfo> res = null;
            if (map.TryGetValue(key, out res))
                return res;

            res = new List<ControllerInvocationInfo>();
            map.Add(key, res);
            return res;
        }
        /// <summary>
        /// Gets the controller instance.
        /// </summary>
        /// <param name="info">The info.</param>
        /// <param name="context">The context.</param>
        /// <param name="requestContext">The request context.</param>
        /// <returns></returns>
		public override IController GetControllerInstance(ControllerInvocationInfo invocationInfo, System.Web.HttpContextBase context, IContext requestContext)
        {
			var instance = base.GetControllerInstance(invocationInfo, context, requestContext);
            var validatable = (IValidatable)instance;

            validatable.Messages = new List<IValidationResult>();
            validatable.IsValid = true;

            foreach (IValidator validator in validators)
            {
                var messages = new List<IValidationResult>();
                validatable.IsValid = validator.IsValid(instance, out messages) && validatable.IsValid;
                validatable.Messages.InsertRange(0, messages);

            }

            return instance;
        }
        /// <summary>
		/// Gets the controller instance.
		/// </summary>
		/// <param name="info">The info.</param>
		/// <param name="context">The context.</param>
		/// <param name="requestContext">The request context.</param>
		/// <returns></returns>
		public virtual IController GetControllerInstance(ControllerInvocationInfo info, HttpContextBase context, IContext requestContext)
		{
			IController instance = controllerConstructor.Invoke(EmptyParams) as IController;
			instance.Initialize();

			// the order here matters. we may have something that's both a session field
			// and a request field. want to make sure that it gets set in a consistent fashion

			// also, keep checking for presence of values. this way, if something is
			// marked as more than one scope, and is present in one but not the other,
			// it won't get overriden with a null.

			foreach (string field in info.Parameters.Keys)
				// not all path parameters may be present on the controller
				if (info.BindPoint.ParameterFields.ContainsKey(field))
					SetValue(
						instance, 
						info.BindPoint.ParameterFields[field], 
						info.Parameters[field]);

            if (context != null)
            {
                if (context.Session != null)
                {
                    // asking for a non-existant session value will simply return null
                    ArrayList allSessionFields = new ArrayList(context.Session.Keys);
                    foreach (string sessionField in descriptor.SessionFields.Keys)
                        if (allSessionFields.Contains(sessionField))
                            SetValue(instance, descriptor.SessionFields[sessionField], context.Session[sessionField]);
                }

                //TODO: both the allCookies and allFormFields collections should be computed once per request, not for every controller
                List<string> allCookies = new List<string>(context.Request.Cookies.AllKeys);
                foreach (string cookie in descriptor.CookieFields.Keys)
                    if (allCookies.Contains(cookie))
                        SetValue(instance, descriptor.CookieFields[cookie].Field, context.Request.Cookies[cookie].Value);

                HttpFileCollectionBase files = context.Request.Files;
                foreach (string file in files.AllKeys)
                    if (descriptor.FormFields.ContainsKey(file))
                        SetFileValue(instance, descriptor.FormFields[file], files[file]);

                List<string> allFormFields = new List<string>(context.Request.Form.AllKeys);
                foreach (string formField in descriptor.FormFields.Keys)
                    if (allFormFields.Contains(formField))
                        SetValue(instance, descriptor.FormFields[formField], context.Request.Form[formField]);
            }

			foreach (string requestField in descriptor.RequestFields.Keys)
				if (requestContext.Contains(requestField))
					SetValue(instance, descriptor.RequestFields[requestField], requestContext[requestField]);

            if (mapper != null)
            {
                IMappable mappable = instance as IMappable;
                if (mappable != null)
                    mappable.Mapper = mapper;
            }

			return instance;
		}
 /// <summary>
 /// Gets the controller.
 /// </summary>
 /// <param name="t">The t.</param>
 /// <param name="requestPoint">The request point.</param>
 /// <returns></returns>
 public IController GetController(ControllerInvocationInfo invocation, HttpContextBase context, IContext requestContext)
 {
     return handlers[invocation.BindPoint.Controller.ControllerType].GetControllerInstance(invocation, context, requestContext);
 }
        /// <summary>
		/// Gets the controller instance.
		/// </summary>
		/// <param name="info">The info.</param>
		/// <param name="context">The context.</param>
		/// <param name="requestContext">The request context.</param>
		/// <returns></returns>
		public virtual IController GetControllerInstance(ControllerInvocationInfo info, HttpContextBase context, IContext requestContext)
		{
			IController instance = controllerConstructor.Invoke(EmptyParams) as IController;
			instance.Initialize();

			// the order here matters. we may have something that's both a session field
			// and a request field. want to make sure that it gets set in a consistent fashion

			// also, keep checking for presence of values. this way, if something is
			// marked as more than one scope, and is present in one but not the other,
			// it won't get overriden with a null.

			foreach (string field in info.Parameters.Keys)
				// not all path parameters may be present on the controller
				if (info.BindPoint.ParameterFields.ContainsKey(field))
					SetValue(
						instance, 
						info.BindPoint.ParameterFields[field], 
						info.Parameters[field]);

            if (context != null)
            {
                LoadSessionFields(context, instance);
                LoadCookieFields(context, instance);
                LoadFileFields(context, instance);
                LoadFormFields(context, instance);
            }

            LoadRequestFields(requestContext, instance);

            if (mapper != null)
            {
                IMappable mappable = instance as IMappable;
                if (mappable != null)
                    mappable.Mapper = mapper;
            }

			return instance;
		}