/// <summary>
        /// Runs light.exe on the compiled wixobj files to generate the final MSI file.
        /// </summary>
        /// <param name="outputPane">The window to which to output build messages.</param>
        /// <returns><see langword="true"/> if successful; otherwise, <see langword="false"/>.</returns>
        private bool Link(IVsOutputWindowPane outputPane)
        {
            Tracer.VerifyNonNullArgument(outputPane, "outputPane");

            string projectRootDirectory = this.Project.RootDirectory;
            string[] sourceFiles = this.GetSourceFiles();
            string[] objectFiles = this.Candle.GetOutputFiles(sourceFiles);
            string[] localizationFiles = this.GetLocalizationFiles();
            string[] referenceFiles = this.GetReferenceFiles();
            string lightParams = this.Light.ConstructCommandLineParameters(projectRootDirectory, objectFiles, localizationFiles, referenceFiles);
            string toolsPath = WixPackage.Instance.Context.Settings.ToolsDirectory;

            // Do not quote the path here. It will be quoted in the LaunchPad
            string lightExePath = PackageUtility.CanonicalizeFilePath(Path.Combine(toolsPath, "light.exe"));

            // See if light.exe exists.
            if (!File.Exists(lightExePath))
            {
                this.WriteLineToOutputWindow("Error: Cannot find light.exe at '{0}'.", lightExePath);
                this.WriteLineToOutputWindow();
                return false;
            }

            // Create the launch pad used for linking.
            LaunchPad lightLaunchPad = new LaunchPad(lightExePath, lightParams);
            lightLaunchPad.WorkingDirectory = projectRootDirectory;

            // Output the light command line to the build output window.
            Tracer.WriteLineInformation(classType, "Link", "Linking...");
            this.WriteLineToOutputWindow();
            this.WriteLineToOutputWindow("Linking...");
            this.WriteLineToOutputWindow(lightLaunchPad.CommandLine);
            this.WriteLineToOutputWindow();

            // Tick once and see if we should continue.
            if (!this.TickBuild())
            {
                return false;
            }

            // Delete the existing .msi file if it exists.
            this.CleanLinkOutput();

            // Execute light.exe piping the output to the output build window and the task pane.
            bool successful = (lightLaunchPad.ExecuteCommand(outputPane, this) == 0);

            return successful;
        }
        /// <summary>
        /// Runs candle.exe on the source files to generate a list of wixobj intermediate files.
        /// </summary>
        /// <param name="outputPane">The window to which to output build messages.</param>
        /// <returns><see langword="true"/> if successful; otherwise, <see langword="false"/>.</returns>
        private bool Compile(IVsOutputWindowPane outputPane)
        {
            Tracer.VerifyNonNullArgument(outputPane, "outputPane");

            string projectRootDirectory = this.Project.RootDirectory;

            // Get the list of source files that should be built
            string[] sourceFiles = this.GetOutOfDateSourceFiles();

            // If we don't have anything to compile, then just show a message indicating that
            if (sourceFiles.Length == 0)
            {
                this.WriteLineToOutputWindow("Compile targets are up to date.");
                this.WriteLineToOutputWindow();
                return true;
            }

            string[] objectFiles = this.Candle.GetOutputFiles(sourceFiles);
            string candleParams = this.Candle.ConstructCommandLineParameters(projectRootDirectory, sourceFiles);
            string toolsPath = WixPackage.Instance.Context.Settings.ToolsDirectory;

            // Do not quote the path here. It will be quoted in the LaunchPad
            string candleExePath = PackageUtility.CanonicalizeFilePath(Path.Combine(toolsPath, "candle.exe"));

            // See if candle exists
            if (!File.Exists(candleExePath))
            {
                this.WriteLineToOutputWindow("Error: Cannot find candle.exe at '{0}'.", candleExePath);
                this.WriteLineToOutputWindow();
                return false;
            }

            // Create the launch pad used for compilation.
            LaunchPad candleLaunchPad = new LaunchPad(candleExePath, candleParams);
            candleLaunchPad.WorkingDirectory = projectRootDirectory;

            // Output the candle command line to the build output window.
            Tracer.WriteLineInformation(classType, "Compile", "Performing main compilation...");
            this.WriteLineToOutputWindow("Performing main compilation...");
            this.WriteLineToOutputWindow(candleLaunchPad.CommandLine);
            this.WriteLineToOutputWindow();

            // Tick once and see if we should continue.
            if (!this.TickBuild())
            {
                return false;
            }

            // Make sure the output directory exists.
            string outputDir = this.Candle.AbsoluteOutputDirectory;
            if (!Directory.Exists(outputDir))
            {
                Directory.CreateDirectory(outputDir);
            }

            // Delete the existing .wixobj files if they exist.
            this.CleanCompileOutput(sourceFiles);

            // Execute candle.exe piping the output to the output build window and the task pane.
            bool successful = (candleLaunchPad.ExecuteCommand(outputPane, this) == 0);

            // Clean up the temporary candle files after the compile has completed.
            this.Candle.CleanTemporaryFiles();

            return successful;
        }