/// <summary>
        /// Sends the specified notice to Airbrake.
        /// </summary>
        /// <param name="notice">The notice.</param>
        public virtual void Send(AirbrakeNotice notice)
        {
            "{0}.Send({1})".TraceDebug(GetType(), notice);

            try
            {
                // If no API key, get it from the appSettings
                if (String.IsNullOrEmpty(notice.ApiKey))
                {
                    // If none is set, just return... throwing an exception is pointless, since one was already thrown!
                    if (String.IsNullOrEmpty(ConfigurationManager.AppSettings["Airbrake.ApiKey"]))
                    {
                        "No 'Airbrake.ApiKey' found. Please define one in AppSettings.".TraceError();
                        return;
                    }

                    notice.ApiKey = this.builder.Configuration.ApiKey;
                }

                // Create the web request
                var request = WebRequest.Create(airbrakeUri) as HttpWebRequest;

                if (request == null)
                {
                    "Couldn't create a request to '{0}'.".TraceError(airbrakeUri);
                    return;
                }

                // Set the basic headers
                request.ContentType = "text/xml";
                request.Accept = "text/xml";
                request.KeepAlive = false;

                // It is important to set the method late... .NET quirk, it will interfere with headers set after
                request.Method = "POST";

                // Go populate the body
                SetRequestBody(request, notice);

                // Begin the request, yay async
                request.BeginGetResponse(RequestCallback, request);
            }
            catch (Exception exception)
            {
                "An error occurred while trying to send to Airbrake.\r\n{0}".TraceError(exception);
            }
        }
        /// <summary>
        /// Creates a <see cref="AirbrakeNotice"/> from the the specified error.
        /// </summary>
        /// <param name="error">The error.</param>
        /// <param name="extraParams"> Extra data for logging in params </param>
        /// <param name="component">Component where the error occured</param>
        /// <returns></returns>
        public AirbrakeNotice Notice(AirbrakeError error, IEnumerable<KeyValuePair<string,string>> extraParams = null, string component = null)
        {
            "{0}.Notice({1})\r\n{2}".TraceDebug(GetType(), component, error);

            var notice = new AirbrakeNotice
            {
                ApiKey = Configuration.ApiKey,
                Error = error,
                Notifier = Notifier,
                ServerEnvironment = ServerEnvironment,
            };

            if (HttpContext.Current != null)
            {

                var context = new HttpContextWrapper(HttpContext.Current);
                string action = null;

                notice.Request = new AirbrakeRequest(context.Request.Url, component ?? Assembly.GetEntryAssembly().CodeBase)
                {
                    Params = BuildParams(context.Request, extraParams).ToArray(),
                    Session = BuildSession(context.Session).ToArray(),
                    CgiData = BuildCgiData(context.Request).ToArray(),
                };
            }

            return notice;
        }
 public override void Send(AirbrakeNotice notice)
 {
     SentNotices.Add(notice);
 }
        private void SetRequestBody(WebRequest request, AirbrakeNotice notice)
        {
            var serializer = new CleanXmlSerializer<AirbrakeNotice>();
            string xml = serializer.ToXml(notice);

            //string validationErrors;

            //if(!AirbrakeValidator.IsValidXml(xml,out validationErrors))
            //    this.log.Debug(f => f("Schema validation errors '{0}':\n{1}\n:{2}", request.RequestUri, xml, validationErrors));

            "Sending the following to '{0}':\n{1}".TraceDebug(request.RequestUri, xml);

            byte[] payload = Encoding.UTF8.GetBytes(xml);
            request.ContentLength = payload.Length;

            using (Stream stream = request.GetRequestStream())
            {
                stream.Write(payload, 0, payload.Length);
            }
        }