/// <summary>
        /// Returns the markup from the search
        /// of a file given its tilde path.
        ///
        /// Preconditions: The page that calls this method must:
        ///
        ///   1. Have executed the call
        ///
        ///        SourceTools.LoadCSSandJavascript(this);
        ///
        ///      during the initial call to PageLoad.
        ///
        ///   2. Be able to guarantee that the file is OK to serve
        ///      in context.
        /// </summary>
        /// <param name="page">
        ///     The page calling this method</param>
        /// <param name="tildeFilePath">
        ///     The file to search</param>
        /// <param name="pattern">
        ///     The search pattern</param>
        /// <param name="isRegex">
        ///     Is the pattern a regular expression?</param>
        /// <param name="ignoreCase">
        ///     Ignore case in the search?</param>
        /// <param name="statistics">
        ///     Include file statistics markup?</param>
        /// <param name="download">
        ///     Include download button markup?</param>
        /// <param name="showAllLines">
        ///     Show all lines in the file?</param>
        /// <param name="onlyPublic">
        ///     Whether or not to restrict to public directories</param>
        public static string SearchFileMarkup
            (Page page,
            string tildeFilePath,
            string pattern,
            bool isRegex,
            bool ignoreCase,
            bool statistics,
            bool download,
            bool showAllLines,
            bool onlyPublic)
        {
            string content = null;

            List <Range> nameMatches =
                SearchFileName(tildeFilePath, pattern, isRegex, ignoreCase);

            List <Range> contentMatches =
                SearchFileContent
                    (page, tildeFilePath, pattern,
                    isRegex, ignoreCase, out content);

            bool matchName = !StringTools.IsTrivial(nameMatches);

            bool matchContent = !StringTools.IsTrivial(contentMatches);

            if (!(matchName || matchContent))
            {
                return("");
            }

            StringBuilder builder = new StringBuilder();

            // markup for highlighted tilde file path
            // with possible file view link

            string markupText =
                matchName
                    ? StringTools.HighlightMarkup(tildeFilePath, nameMatches, 4, false, true)
                    : tildeFilePath;

            long     bytes;
            DateTime?created;
            DateTime?modified;

            builder.Append
                (SourceTools.StatisticsMarkup
                    (page, tildeFilePath, markupText, onlyPublic,
                    true, true, statistics, download, null,
                    out bytes, out created, out modified));

            // markup for highlighted content

            if (matchContent)
            {
                builder.Append(HTML_Tools.open_pre);

                builder.Append
                    (StringTools.HighlightMarkup
                        (content, contentMatches, 4, true, showAllLines));

                builder.Append(HTML_Tools.shut_pre);

                builder.Append("\n");
            }

            return(builder.ToString());
        }