/// <summary>
        /// Start MSBuild build submission
        /// </summary>
        /// If buildKind is ASYNC, this method starts the submission ane returns. uiThreadCallback will be called on UI thread once submissions completes.
        /// if buildKind is SYNC, this method executes the submission and runs uiThreadCallback
        /// <param name="buildKind">Is it a SYNC or ASYNC build</param>
        /// <param name="target">target to build</param>
        /// <param name="projectInstance">project instance to build; if null, this.BuildProject.CreateProjectInstance() is used to populate</param>
        /// <param name="uiThreadCallback">callback to be run UI thread </param>
        /// <returns></returns>
        internal virtual BuildSubmission DoMSBuildSubmission(BuildKind buildKind, string target, ref ProjectInstance projectInstance, MSBuildCoda uiThreadCallback)
        {
            UIThread.MustBeCalledFromUIThread();
            bool designTime = BuildKind.SYNC == buildKind;
            //projectInstance = null;

            var accessor = (IVsBuildManagerAccessor)this.Site.GetService(typeof(SVsBuildManagerAccessor));
            if (!TryBeginBuild(designTime))
            {
                if (null != uiThreadCallback)
                {
                    uiThreadCallback(MSBuildResult.Failed, projectInstance);
                }

                return null;
            }

            string[] targetsToBuild = new string[target != null ? 1 : 0];
            if (target != null)
            {
                targetsToBuild[0] = target;
            }

            if (null == projectInstance)
            {
                projectInstance = BuildProject.CreateProjectInstance();
            }

            projectInstance.SetProperty(GlobalProperty.VisualStudioStyleErrors.ToString(), "true");
            projectInstance.SetProperty("UTFOutput", "true");
            projectInstance.SetProperty(GlobalProperty.BuildingInsideVisualStudio.ToString(), "true");

            this.BuildProject.ProjectCollection.HostServices.SetNodeAffinity(projectInstance.FullPath, NodeAffinity.InProc);
            BuildRequestData requestData = new BuildRequestData(projectInstance, targetsToBuild, this.BuildProject.ProjectCollection.HostServices, BuildRequestDataFlags.ReplaceExistingProjectInstance);
            BuildSubmission submission = BuildManager.DefaultBuildManager.PendBuildRequest(requestData);
            try
            {
                if (useProvidedLogger && buildLogger != null)
                {
                    ErrorHandler.ThrowOnFailure(accessor.RegisterLogger(submission.SubmissionId, buildLogger));
                }

                if (buildKind == BuildKind.ASYNC)
                {
                    ProjectInstance projectInstanceCopy = projectInstance;
                    submission.ExecuteAsync(sub =>
                    {
                        UIThread.Run(() =>
                        {
                            this.FlushBuildLoggerContent();
                            EndBuild(sub, designTime);
                            uiThreadCallback((sub.BuildResult.OverallResult == BuildResultCode.Success) ? MSBuildResult.Successful : MSBuildResult.Failed, projectInstanceCopy);
                        });
                    }, null);
                }
                else
                {
                    submission.Execute();
                    EndBuild(submission, designTime);
                    MSBuildResult msbuildResult = (submission.BuildResult.OverallResult == BuildResultCode.Success) ? MSBuildResult.Successful : MSBuildResult.Failed;
                    if (uiThreadCallback != null)
                    {
                        uiThreadCallback(msbuildResult, projectInstance);
                    }
                }
            }
            catch (Exception e)
            {
                Debug.Fail(e.ToString());
                EndBuild(submission, designTime);
                if (uiThreadCallback != null)
                {
                    uiThreadCallback(MSBuildResult.Failed, projectInstance);
                }

                throw;
            }

            return submission;
        }
 /// <summary>
 /// Do the build asynchronously.
 /// </summary>
 /// <param name="vsopts"></param>
 /// <param name="configCanonicalName"></param>
 /// <param name="output"></param>
 /// <param name="target"></param>
 /// <param name="coda"></param>
 internal virtual void BuildAsync(uint vsopts, ConfigCanonicalName configCanonicalName, IVsOutputWindowPane output, string target, MSBuildCoda coda)
 {
     bool engineLogOnlyCritical = BuildPrelude(output);
     MSBuildCoda fullCoda = (res, instance) =>
     {
         coda(res, instance);
     };
     try
     {
         this.SetBuildConfigurationProperties(configCanonicalName);
         ProjectInstance ignoreMeToo = null;
         this.DoMSBuildSubmission(BuildKind.ASYNC, target, ref ignoreMeToo, fullCoda);
     }
     catch (Exception)
     {
         fullCoda(MSBuildResult.Failed, null);
         throw;
     }
 }