/// <summary>
        /// Wraps a function that invokes a server-side hub method. Even if a client has not been authorized to connect
        /// to a hub, it will still be authorized to invoke server-side methods on that hub unless it is prevented in
        /// <see cref="IHubPipelineModule.BuildIncoming"/> by not executing the invoke parameter.
        /// </summary>
        /// <param name="invoke">A function that invokes a server-side hub method.</param>
        /// <returns>A wrapped function that invokes a server-side hub method.</returns>
        public virtual Func<IHubIncomingInvokerContext, Task<object>> BuildIncoming(Func<IHubIncomingInvokerContext, Task<object>> invoke)
        {
            return async context =>
            {
                if (OnBeforeIncoming(context))
                {
                    try
                    {
                        var result = await invoke(context).OrEmpty().PreserveCulture();
                        return OnAfterIncoming(result, context);
                    }
                    catch (Exception ex)
                    {
                        var exContext = new ExceptionContext(ex);
                        OnIncomingError(exContext, context);

                        var error = exContext.Error;
                        if (error == ex)
                        {
                            throw;
                        }
                        else if (error != null)
                        {
                            throw error;
                        }
                        else
                        {
                            return exContext.Result;
                        }
                    }
                }

                return null;
            };
        }
        //static readonly ILog logger = LogManager.GetLogger(typeof(HubErrorLoggingPipelineModule));

        protected override void OnIncomingError(ExceptionContext exceptionContext,
            IHubIncomingInvokerContext invokerContext) {
            // Don't log user exceptions...
            var hubEx = exceptionContext.Error as HubException;
            if (hubEx != null) {
                var data = hubEx.ErrorData as UserException;
                if (data != null) {
                    MainLog.Logger.FormattedWarnException(data, "UserException catched in Hub Pipeline");
                    return;
                }

                var ex = hubEx.ErrorData as Exception;
                if (ex != null) {
                    MainLog.Logger.FormattedErrorException(ex,
                        "An error occurred on signalr hub: " + GetInvocationInfo(invokerContext));
                }
                return;
            }

            if (exceptionContext.Error is UserException || exceptionContext.Error.InnerException is UserException)
                return;
            MainLog.Logger.FormattedErrorException(exceptionContext.Error,
                "An error occurred on signalr hub: " + GetInvocationInfo(invokerContext));
        }
        /// <summary>
        /// This is called when an uncaught exception is thrown by a server-side hub method or the incoming component of a
        /// module added later to the <see cref="IHubPipeline"/>. Observing the exception using this method will not prevent
        /// it from bubbling up to other modules.
        /// </summary>
        /// <param name="exceptionContext">
        /// Represents the exception that was thrown during the server-side invocation.
        /// It is possible to change the error or set a result using this context.
        /// </param>
        /// <param name="invokerContext">A description of the server-side hub method invocation.</param>
        protected virtual void OnIncomingError(ExceptionContext exceptionContext, IHubIncomingInvokerContext invokerContext)
        {

        }