/// <summary>
        /// Initializes the singleton instance of the command.
        /// </summary>
        /// <param name="package">Owner package, not null.</param>
        /// <returns>An awaitable task.</returns>
        public static async Task InitializeAsync(AsyncPackage package)
        {
            // Execute this method on the UI thread.
            await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

            // Instantiate the command.
            OleMenuCommandService commandService = await package.GetServiceAsync(typeof(IMenuCommandService)) as OleMenuCommandService;

            SetModuleHeaderCommand.instance = new SetModuleHeaderCommand(package, commandService);
        }
        /// <summary>
        /// This function is the callback used to execute the command when the menu item is clicked.
        /// See the constructor to see how the menu item is associated with this function using
        /// OleMenuCommandService service and MenuCommand class.
        /// </summary>
        /// <param name="sender">Event sender.</param>
        /// <param name="e">Event args.</param>
        private void Execute(object sender, EventArgs e)
        {
            // Verify the current thread is the UI thread.
            ThreadHelper.ThrowIfNotOnUIThread();

            // Make sure that the user has set the (or accepted the default) value for a wrap margin.
            if (!Settings.Default.IsHeadingSet)
            {
                SetModuleHeaderCommand.SetHeader();
            }

            // We can only execute this command when an active document is present.
            if (InsertModuleHeaderCommand.environment.ActiveDocument != null)
            {
                // Get the selected text from the environment.
                TextSelection selection = InsertModuleHeaderCommand.environment.ActiveDocument.Selection as TextSelection;

                // This command will place a copyright notice in the first block of comments it finds.  This is generally the block that describes
                // the class found in the file.  The general idea here is to move the cursor to the start of the file and then search for the first
                // set of block comments.  Once that is found, we'll continue to read until there are no more comments in the block and place the
                // copyright notice there.  This is likely a 95% solution.  The alternative was to place the copyright notice on the same line as the
                // cursor, but that would involve guessing at the indentation and the exact format of the comment prefix.
                EditPoint startPoint = selection.AnchorPoint.CreateEditPoint();
                startPoint.StartOfDocument();

                // The active document's full name is normalized to lower case (so why does StyleCop force us to normalize in upper case?).  So we'd
                // have a problem if we tried to use the name of the module found in this structure: since the analyzers check the case-sensitive
                // name of the file against the name of the module in the header, a name that is normalized to lower case will fail.  So we need to
                // go the long way around to find a function that returns the non-normalized name of the file.
                string   directoryPath = Path.GetDirectoryName(InsertModuleHeaderCommand.environment.ActiveDocument.FullName);
                string[] files         = Directory.GetFiles(directoryPath, Path.GetFileName(InsertModuleHeaderCommand.environment.ActiveDocument.Name));
                string   moduleName    = Path.GetFileName(files[0]);

                // This inserts the boilerplate header at the start of the module.
                startPoint.Insert(
                    string.Format(
                        CultureInfo.InvariantCulture,
                        Resources.ModuleHeaderTemplate,
                        "// ",
                        moduleName,
                        Settings.Default.Company,
                        Settings.Default.CopyrightNotice,
                        Settings.Default.Author));
            }
        }
        /// <summary>
        /// Initialization of the package; this method is called right after the package is sited, so this is the place
        /// where you can put all the initialization code that rely on services provided by VisualStudio.
        /// </summary>
        /// <param name="cancellationToken">A cancellation token to monitor for initialization cancellation, which can occur when VS is shutting down.</param>
        /// <param name="progress">A provider for progress updates.</param>
        /// <returns>A task representing the async work of package initialization, or an already completed task if there is none. Do not return null from this method.</returns>
        protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress <ServiceProgressData> progress)
        {
            // When initialized asynchronously, the current thread may be a background thread at this point.
            // Do any initialization that requires the UI thread after switching to the UI thread.
            await this.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

            await FormatCommentCommand.InitializeAsync(this);

            await FormatXmlCommand.InitializeAsync(this);

            await InsertModuleHeaderCommand.InitializeAsync(this);

            await InsertConstructorHeaderCommand.InitializeAsync(this);

            await SetModuleHeaderCommand.InitializeAsync(this);

            await SetWrapMarginCommand.InitializeAsync(this);

            await ScrubXsdCommand.InitializeAsync(this);
        }
 /// <summary>
 /// This function is the callback used to execute the command when the menu item is clicked.
 /// See the constructor to see how the menu item is associated with this function using
 /// OleMenuCommandService service and MenuCommand class.
 /// </summary>
 /// <param name="sender">Event sender.</param>
 /// <param name="e">Event args.</param>
 private void Execute(object sender, EventArgs e)
 {
     // This does the actal work of prompting the user for the header values.
     SetModuleHeaderCommand.SetHeader();
 }