public string GetTooltip(MarkerContext ctx)
        {
            // A MarkerContext object contains state describing a text editor instance of a link definition.

            // GetTooltip gets called when the mouse cursor hovers over plugin-associated link text.
            // It is possible that any member of ctx may be null, string.Empty or 0.

            // The returned string can be either plane text or XAML.
            // XAML text must be valid in the context of the VASourceLinks.dll assembly, thus all
            // resources must be defined in a way which the XAML parser may resolve.

            // Return null or String.Empty if you don't need to provide tooltip text from your plugin.

            Debug.WriteLine("Source Links calling GetTooltip(MarkerContext)");

            // We can determine the link definition behavior from the MarkerContext.
            // When Exe != null, then behavior is set to ShellExecute.
            // When Url != null, then behavior is set to open URL in Browser.
            // The Url, Exe and ExeArgs members of the MarkerContext contain information
            // from the link definition; if your plugin overrides URL or Execute, the values
            // may be irrelevant.

            // Note: In this example, GetUrl is always called because Flags include
            // OverrideUrl; user can't select ShellExecute behavior with the default
            // implementation of the example plugin.

            string actionText  = string.Empty;
            string actionLabel = string.Empty;

            if (Flags.HasFlag(PluginFlags.OverrideExecute))
            {
                actionLabel = "Execute:";
                actionText  = "Overridden by plugin";
            }
            else if (Flags.HasFlag(PluginFlags.OverrideUrl))
            {
                actionLabel = "Open URL:";
                actionText  = GetUrl(ctx);
            }
            else
            {
                if (ctx.Url != null)                        // Open URL in Browser
                {
                    actionLabel = "Open URL:";
                    actionText  = ctx.Url;
                }
                else if (ctx.Exe != null)                   // ShellExecute
                {
                    actionLabel = "ShellExecute:";
                    actionText  = ctx.Exe;
                    if (!string.IsNullOrEmpty(ctx.ExeArgs))
                    {
                        actionText += " " + ctx.ExeArgs;
                    }
                }
            }

            // The return string can be either plain text or valid XAML.
            // This example demonstrates how to turn simple markup into valid XAML.
            // The returned XAML defines a TextBlock.
            string tooltip = string.Format(

                // We can use formatted markup text for FlowDocument.
                // See: https://msdn.microsoft.com/en-us/library/aa970909(v=vs.110).aspx and
                // https://docs.microsoft.com/en-us/dotnet/articles/framework/wpf/advanced/flow-document-overview

                "<Bold>File name:</Bold> {0}<LineBreak/>" +
                "<Bold>Project file name:</Bold> {1}<LineBreak/>" +
                "<Bold>Solution file name:</Bold> {2}<LineBreak/>" +
                "<Bold>Line:</Bold> {3}<LineBreak/>" +
                "<Bold>Column:</Bold> {4}<LineBreak/>" +
                "<Bold>Line text:</Bold> {5}<LineBreak/>" +
                "<Bold>Marker text:</Bold> {6}<LineBreak/>" +

                // Or we can use some HTML inline tags: H1-H6, B, STRONG, I, EM, U, DEL, INS, S, BR
                // Those tags are replaced with appropriate XAML tags by calling PluginUtils.WrapMarkupInXAML.
                // HTML attributes are not supported.
                "<b>Keyword text:</b> {7}<br/>" +
                "<b>Value text:</b> {8}<br/>" +
                "<b>" + actionLabel + "</b> {9}",

                // Images are supported:
                // "<Image Source=\"path\\to\\image.jpg\"/>"

                // Use PluginUtils.EncodeXML in places where text could contain special XML characters.
                PluginUtils.EncodeXML(System.IO.Path.GetFileName(ctx.FileName)),     // 0
                PluginUtils.EncodeXML(System.IO.Path.GetFileName(ctx.ProjectName)),  // 1
                PluginUtils.EncodeXML(System.IO.Path.GetFileName(ctx.SolutionName)), // 2
                ctx.Line,                                                            // 3
                ctx.Column,                                                          // 4
                PluginUtils.EncodeXML(ctx.LineText),                                 // 5
                PluginUtils.EncodeXML(ctx.MarkerText),                               // 6
                PluginUtils.EncodeXML(ctx.KeywordText),                              // 7
                PluginUtils.EncodeXML(ctx.ValueText),                                // 8
                PluginUtils.EncodeXML(actionText));                                  // 9

            // PluginUtils.WrapMarkupInXAML replaces selected HTML formatting tags
            // with appropriate XAML tags (<b> becomes <Bold> and <br> becomes
            // <LineBreak>) and wraps the result into a TextBlock.

            // Note: Because WrapMarkupInXAML wraps your input into a TextBlock, it
            // can contain ONLY tags derived from Inline. If your tooltip must contain
            // Block, then don't use this method; format the whole XAML directly,
            // including required namespaces.
            return(PluginUtils.WrapMarkupInXAML(tooltip));
        }