/// <summary>
        /// Initializes a new instance of the <see cref="ControllerDirector"/> class.
        /// </summary>
        /// <param name="controller">Controller to handle.</param>
        public ControllerDirector(Controller controller)
        {
            _controllerPrototype = controller;
            _type = controller.GetType();
            FindControllerName(_type);
            //controller.ControllerUri = _uri;
            //controller.ControllerName = _name;

            Type actionResultType = typeof (IActionResult);
            Type viewDataType = typeof (IViewData);

            MethodInfo indexMethod = null;
            foreach (MethodInfo methodInfo in _type.GetMethods(BindingFlags.Instance | BindingFlags.Public))
            {
                if (methodInfo.IsAbstract)
                    continue;
                if (methodInfo.Name.StartsWith("get_") || methodInfo.Name.StartsWith("set_"))
                    continue;
                if (methodInfo.DeclaringType == typeof (Controller))
                    continue;
                if (methodInfo.GetParameters().Length > 0)
                    continue;

                if (methodInfo.ReturnType == actionResultType)
                    MapMethod(methodInfo);
                if (methodInfo.ReturnType == viewDataType)
                    MapMethod(methodInfo);

                if (methodInfo.Name.ToLower() == "index" && methodInfo.GetParameters().Length == 0 &&
                    (methodInfo.ReturnType == actionResultType || methodInfo.ReturnType == viewDataType))
                    indexMethod = methodInfo;

                CheckIfDefaultMethod(methodInfo);
            }


            // use "Index" method if no other default method have been specified.
            if (_defaultMethod == null && indexMethod != null)
                _defaultMethod = indexMethod;
        }
 /// <summary>
 /// Enqueue a used controller.
 /// </summary>
 /// <param name="controller">Controller to enqueue</param>
 public void Enqueue(Controller controller)
 {
         lock (_createdControllers)
             _createdControllers.Enqueue(controller);
 }
        /// <summary>
        /// Process controller request.
        /// </summary>
        /// <param name="context">Controller context</param>
        /// <param name="controller">Controller used to process request</param>
        /// <returns>Action result.</returns>
        /// <exception cref="NotFoundException"><c>NotFoundException</c>.</exception>
        /// <exception cref="InvalidOperationException">Specified URI is not for this controller.</exception>
        /// <remarks>
        /// Controller is returned as a parameter to let us be able to use it as a variable
        /// in the view. It's VERY important <see cref="Enqueue"/> is called when rendering is complete (or if an exception
        /// is thrown).
        /// </remarks>
        public object Process(IControllerContext context, out Controller controller)
        {
            if (!context.Uri.AbsolutePath.StartsWith(_uri))
                throw new InvalidOperationException("Uri '" + context.Uri + "' is not for controller '" + _type.FullName +
                                                    "'.");
            controller = null;
            MethodInfo method;

            if (context.UriSegments.Length < _uriSegments)
                throw new NotFoundException("No action specified for controller '" + _uri + "'.");

            // using default action
            if (context.UriSegments.Length == _uriSegments)
            {
                if (_defaultMethod == null)
                    return null;
                method = _defaultMethod;
            }
            else
            {
                string actionName = context.UriSegments[_uriSegments];
                method = GetMethod(context.RequestContext.Request.Method, actionName);
                if (method == null)
                    return null;
            }

            context.ControllerUri = _uri;
            context.ControllerName = _name;
            context.ActionName = context.ActionName = method.Name.ToLower();

            // invoke method
            controller = CreateController();
            try
            {
                controller.Clear();
                InvokeEvent(controller, method, context.RequestContext);
                controller.SetContext(context);

                // Before action can filter out stuff.
                var actionResult = controller.InvokeBeforeAction(method);
                if (actionResult != null)
                    return actionResult;

                var result = method.Invoke(controller, null);
                context.Title = controller.Title;
                context.LayoutName = controller.LayoutName;
                controller.InvokeAfterAction((IActionResult)result);
                return result;
            }
            catch (Exception err)
            {
                var result = controller.TriggerOnException(err);
                if (result == null)
                {
                    Enqueue(controller);
                    throw;
                }

                controller.InvokeAfterAction(result);
                return result;
            }
        }
 /// <summary>
 /// Trigger the InvokingAction event.
 /// </summary>
 /// <param name="controller"></param>
 /// <param name="method"></param>
 /// <param name="context"></param>
 /// <remarks>
 /// <para>
 /// We need to capture all exceptions since we have no control
 /// over what the event subscribers do, and we do not want the 
 /// whole server to crash because of an unhandled exception.
 /// </para>
 /// <para>
 /// HttpExceptions are a different story since they are handled
 /// in a lower level in the framework.
 /// </para>
 /// </remarks>
 /// <exception cref="Exception">A HTTP exception has been thrown by an event subscriber.</exception>
 private void InvokeEvent(Controller controller, MethodInfo method, RequestContext context)
 {
     try
     {
         InvokingAction(this, new ControllerEventArgs(controller, method.Name.ToLower(), context));
     }
     catch (Exception err)
     {
         if (err is HttpException)
             throw;
         _logger.Error("Event threw exception: " + err);
     }
 }
 public DirectorContext(ControllerDirector director, Controller controller)
 {
     Director = director;
     Controller = controller;
 }