/// <summary>
        /// Update
        /// </summary>
        /// <param name="customInfoBarMessage">Optional. If provided than this will be the message that will appear in info bar, otherwise a standard one will appear instead</param>
        private void UpdateRequired(string customInfoBarMessage = null)
        {
            this.AssertOnUIThread();
            IInfoBarManager manager = this.host.GetMefService <IInfoBarManager>();

            if (manager == null)
            {
                Debug.Fail("Cannot find IInfoBarManager");
                return;
            }

            this.currentErrorWindowInfoBar = manager.AttachInfoBarWithButton(
                ErrorListToolWindowGuid,
                customInfoBarMessage ?? Strings.SonarLintInfoBarUnboundProjectsMessage,
                Strings.SonarLintInfoBarUpdateCommandText,
                new SonarLintImageMoniker(KnownMonikers.RuleWarning.Guid, KnownMonikers.RuleWarning.Id));

            if (this.currentErrorWindowInfoBar == null)
            {
                this.OutputMessage(Strings.SonarLintFailedToAttachInfoBarToErrorList);
                Debug.Fail("Failed to add an info bar to the error list tool window");
            }
            else
            {
                this.currentErrorWindowInfoBar.Closed      += this.CurrentErrorWindowInfoBar_Closed;
                this.currentErrorWindowInfoBar.ButtonClick += this.CurrentErrorWindowInfoBar_ButtonClick;

                // Need to capture the current binding information since the user can change the binding
                // and running the Update should just no-op in that case.
                this.infoBarBinding = configProvider.GetConfiguration().Project;
            }
        }
        public ActiveSolutionBoundTracker(IHost host, IActiveSolutionTracker activeSolutionTracker, ILogger logger)
        {
            extensionHost   = host ?? throw new ArgumentNullException(nameof(host));
            solutionTracker = activeSolutionTracker ?? throw new ArgumentNullException(nameof(activeSolutionTracker));
            this.logger     = logger ?? throw new ArgumentNullException(nameof(logger));

            vsMonitorSelection = host.GetService <SVsShellMonitorSelection, IVsMonitorSelection>();
            vsMonitorSelection.GetCmdUIContextCookie(ref BoundSolutionUIContext.Guid, out boundSolutionContextCookie);

            configurationProvider = extensionHost.GetService <IConfigurationProviderService>();
            configurationProvider.AssertLocalServiceIsNotNull();

            errorListInfoBarController = extensionHost.GetService <IErrorListInfoBarController>();
            errorListInfoBarController.AssertLocalServiceIsNotNull();

            // The user changed the binding through the Team Explorer
            extensionHost.VisualStateManager.BindingStateChanged += OnBindingStateChanged;

            // The solution changed inside the IDE
            solutionTracker.ActiveSolutionChanged += OnActiveSolutionChanged;

            CurrentConfiguration = configurationProvider.GetConfiguration();

            SetBoundSolutionUIContext();
        }
        private void RaiseAnalyzersChangedIfBindingChanged(bool?isBindingCleared = null)
        {
            var newBindingConfiguration = configurationProvider.GetConfiguration();

            if (!CurrentConfiguration.Equals(newBindingConfiguration))
            {
                CurrentConfiguration = newBindingConfiguration;
                SolutionBindingChanged?.Invoke(this, new ActiveSolutionBindingEventArgs(newBindingConfiguration));
            }
            else if (isBindingCleared == false)
            {
                SolutionBindingUpdated?.Invoke(this, EventArgs.Empty);
            }

            SetBoundSolutionUIContext();
        }