/// <summary>
        /// Replaces the match with the appropriate email token.
        /// </summary>
        /// <param name="match">The matched token.</param>
        /// <param name="application">The application.</param>
        /// <param name="pageList">The page list.</param>
        /// <param name="thisPath">The this path.</param>
        /// <param name="defaultReplaceValue">The default replace value.</param>
        /// <returns>
        /// The replaced email token.
        /// </returns>
        private string ReplaceTokens(Match match, Application application, PageList pageList, ApplicationDataPath thisPath, string defaultReplaceValue)
        {
            SummaryControl summary = null;
            string token = match.Groups[2].Value;

            List<Page> pagesToOutput = new List<Page>();
            foreach (Page page in pageList)
            {
                summary = page.Controls.FindRecursive<SummaryControl>(c => c.Type == ControlType.Summary && c.Name == token);
                if (summary == null)
                {
                    pagesToOutput.Add(page);
                }
                else
                {
                    break;
                }
            }

            if (summary == null)
            {
                return match.Value;
            }

            if (!summary.IncludedControls.All)
            {
                pagesToOutput = pageList.Where(p => p.Controls.Any(c => summary.IncludedControls.Controls.Contains(c.Name))).ToList();
            }

            StringBuilder sb = new StringBuilder();
            sb.AppendLine(string.Format("<table style='{0}'>", FormatterResources.TableStyles));

            foreach (var page in pagesToOutput)
            {
                this.WriteHeaderRow(sb, page.PageTitle, FormatterResources.PageStyles);

                ControlList controlsToOutput = summary.IncludedControls.All ?
                                                    page.Controls :
                                                    new ControlList(page.Controls.FindAllRecursive(c => summary.IncludedControls.Controls.Contains(c.Name) && (c is ValueControl || c is RepeaterControl)));

                foreach (var control in controlsToOutput)
                {
                    if (control is RepeaterControl)
                    {
                        this.WriteRepeater(sb, control as RepeaterControl, summary.IncludedControls, application.ApplicationData);
                    }
                    else if (control is LikertControl)
                    {
                        this.WriteLikert(sb, control as LikertControl, application.ApplicationData);
                    }
                    else if (control is IControlWithOptions)
                    {
                        this.WriteOptionValue(sb, control as ControlWithOptions, application.ApplicationData);
                    }
                    else if (control is CalculationControl)
                    {
                        var controlWithLabel = control as IControlWithLabel;
                        this.WriteRow(sb, controlWithLabel.Label, this.GetValueToWrite(control, application.ApplicationData.GetValue<string>(control.Name)));
                    }
                    else
                    {
                        var valueControl = control as ValueControl;
                        if (valueControl != null && controlsToOutput.All(c => c.Id != control.ParentId))
                        {
                            this.WriteRow(sb, valueControl.Label, this.GetValueToWrite(control, application.ApplicationData.GetValue<string>(control.Name)));
                        }
                    }
                }
            }

            sb.AppendLine("</table>");

            return sb.ToString();
        }