/// <summary>
        /// Sends form POST as e-mail to specified recipients
        /// </summary>
        /// <param name="settings"></param>
        /// <param name="data"></param>
        private bool SendEmails(FormSettings settings, XmlDocument data)
        {
            string formEmail = TransformToEmail(settings, data);
            _log.Trace(m => m("To: {0}\nBody:\n{1}", settings.Email.To, formEmail));

            try
            {
                return NotificationHelper.SendEmail(settings.Email.To, settings.Email.Subject, formEmail.Replace("&amp;", "&"));	// HACK: to deal w/ encoded URLs
            }
            catch (Exception ex)
            {
                _log.Error(m => m("Failed to e-mail the following form to '{0}'\n{1}-----\nException details:\n-----{2}", settings.Email.To, data.InnerXml, ex));
                UserMessage = "There was an error attempting to send your form.";
            }

            return false;
        }
        /// <summary>
        /// Apply XSLT template for E-mail
        /// </summary>
        /// <param name="settings"></param>
        /// <param name="form"></param>
        /// <returns></returns>
        private string TransformToEmail(FormSettings settings, XmlDocument form)
        {
            if (string.IsNullOrWhiteSpace(settings.Email.TemplateName)) {
                throw new NullReferenceException(string.Format("No Email xslTemplateName is specified for form ID {0}", settings.ID));
            }

            string xsltFilename = Server.MapPath(string.Format("templates\\{0}.xslt", settings.Email.TemplateName));
            XslCompiledTransform xslt = Utility.LoadXslTempate(xsltFilename);

            try
            {
                using (StringWriter output = new StringWriter())
                {
                    xslt.Transform(form.CreateNavigator(), null, output);
                    return output.ToString();
                }
            }
            catch (XmlSchemaValidationException ex)
            {
                _log.Error(m => m("{0}: XSLT is not valid.\n{1}", xsltFilename, ex));
            }
            catch (XsltException ex)
            {
                _log.Error(m => m("{0}: XSLT is not valid.\n{1}", xsltFilename, ex));
            }
            catch (XmlException ex)
            {
                _log.Error(m => m("{0}: XML is not valid.\n{1}", xsltFilename, ex));
            }
            catch (XmlSchemaException ex)
            {
                _log.Error(m => m("{0}: Schema is not valid.\n{1}", xsltFilename, ex));
            }
            catch (ArgumentNullException ex)
            {
                _log.Error(m => m("{0}: XSLT is blank.\n{1}", xsltFilename, ex));
            }

            // TODO: will an empty string throw an exception further up the chain?
            _log.Warn(m => m("XML transform returning an empty string."));
            return string.Empty;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="settings"></param>
        /// <param name="result"></param>
        /// <param name="recordID"></param>
        /// <param name="fields"></param>
        private void DisplayResult(FormSettings settings, ResultActionBase result, Guid recordID, IEnumerable<string> fields = null)
        {
            _log.Debug(m => m("Performing POST result action ({0})...", result.Action.ToString("G")));
            switch (result.Action)
            {
                case ActionOption.Message:
                    UserMessage = fields != null ? Utility.ApplyTemplateSubstitution(result.MessageText, fields) : result.MessageText;
                    _log.Trace(m => m("User message: {0}", UserMessage));

                    if (!string.IsNullOrWhiteSpace(result.Link))
                    {
                        if (result.Link.ToUpper() == "${REFERRER}")
                        {
                            SetReturnLink(CurrentReferrer, settings.Database.ReturnIdToCaller ? recordID : Guid.Empty);
                        }
                        else
                        {
                            SetReturnLink(Encoder.HtmlAttributeEncode(result.Link), settings.Database.ReturnIdToCaller ? recordID : Guid.Empty);
                        }
                    }
                    break;

                case ActionOption.Redirect:
                    if (result.Link == "${REFERRER}")
                    {
                        ForceRedirect((recordID != null && settings.Database.ReturnIdToCaller) ? string.Format("{0}?{1}={2}", CurrentReferrer, DB_ID_PARAMETER, recordID) : CurrentReferrer);
                    }
                    else
                    {
                        // valid URLs should conform to attribute value rules
                        string link = Encoder.HtmlAttributeEncode((recordID != null && settings.Database.ReturnIdToCaller) ? string.Format("{0}?{1}={2}", result.Link, DB_ID_PARAMETER, recordID) : result.Link);

                        if (Utility.IsUrl(link))
                        {
                            ForceRedirect(link);
                        }
                        else
                        {
                            UserMessage = "Your form was submitted, but we are unable to send you to the next page.";
                            _log.Error(m => m("Cannot redirect user. Invalid URL: <{0}>", link));
                            ReturnHttpError(500, endResponse: false);
                        }
                    }
                    break;

                default:
                    throw new ApplicationException("Unrecognized Result Action");
            }
        }