public void SetModuleState(QualifiedModuleName module, ParserState state, SyntaxErrorException parserError = null, bool evaluateOverallState = true)
        {
            if (AllUserDeclarations.Any())
            {
                var        projectId = module.ProjectId;
                IVBProject project   = GetProject(projectId);

                if (project == null)
                {
                    // ghost component shouldn't even exist
                    ClearStateCache(module);
                    EvaluateParserState();
                    return;
                }
            }

            var oldState = GetModuleState(module);

            _moduleStates.AddOrUpdate(module, new ModuleState(state), (c, e) => e.SetState(state));
            _moduleStates.AddOrUpdate(module, new ModuleState(parserError), (c, e) => e.SetModuleException(parserError));
            Logger.Debug("Module '{0}' state is changing to '{1}' (thread {2})", module.ComponentName, state, Thread.CurrentThread.ManagedThreadId);
            OnModuleStateChanged(module, state, oldState);
            if (evaluateOverallState)
            {
                EvaluateParserState();
            }
        }
        public Declaration FindSelectedDeclaration(CodePane activeCodePane, bool procedureLevelOnly = false)
        {
            var selection = activeCodePane.GetSelection();

            if (selection.Equals(_lastSelection))
            {
                return(_selectedDeclaration);
            }

            _lastSelection       = selection;
            _selectedDeclaration = null;

            if (!selection.Equals(default(QualifiedSelection)))
            {
                var matches = AllDeclarations
                              .Where(item => item.DeclarationType != DeclarationType.Project &&
                                     item.DeclarationType != DeclarationType.ModuleOption &&
                                     item.DeclarationType != DeclarationType.ClassModule &&
                                     item.DeclarationType != DeclarationType.ProceduralModule &&
                                     (IsSelectedDeclaration(selection, item) ||
                                      item.References.Any(reference => IsSelectedReference(selection, reference))))
                              .ToList();
                try
                {
                    if (matches.Count == 1)
                    {
                        _selectedDeclaration = matches.Single();
                    }
                    else
                    {
                        Declaration match = null;
                        if (procedureLevelOnly)
                        {
                            match = matches.SingleOrDefault(item => item.DeclarationType.HasFlag(DeclarationType.Member));
                        }

                        // ambiguous (?), or no match - make the module be the current selection
                        match = match ?? AllUserDeclarations.SingleOrDefault(item =>
                                                                             (item.DeclarationType == DeclarationType.ClassModule || item.DeclarationType == DeclarationType.ProceduralModule) &&
                                                                             item.QualifiedName.QualifiedModuleName.Equals(selection.QualifiedName));

                        _selectedDeclaration = match;
                    }
                }
                catch (InvalidOperationException exception)
                {
                    Debug.WriteLine(exception);
                }
            }

            if (_selectedDeclaration != null)
            {
                Debug.WriteLine("Current selection ({0}) is '{1}' ({2})", selection, _selectedDeclaration.IdentifierName, _selectedDeclaration.DeclarationType);
            }

            return(_selectedDeclaration);
        }
        public void SetModuleState(VBComponent component, ParserState state, SyntaxErrorException parserError = null)
        {
            if (AllUserDeclarations.Any())
            {
                var projectId = component.Collection.Parent.HelpFile;
                var project   = AllUserDeclarations.SingleOrDefault(item =>
                                                                    item.DeclarationType == DeclarationType.Project && item.ProjectId == projectId);

                if (project == null)
                {
                    // ghost component shouldn't even exist
                    ClearStateCache(component);
                    Status = EvaluateParserState();
                    return;
                }
            }
            var key = new QualifiedModuleName(component);

            _moduleStates.AddOrUpdate(key, state, (c, s) => state);
            _moduleExceptions.AddOrUpdate(key, parserError, (c, e) => parserError);
            Debug.WriteLine("Module '{0}' state is changing to '{1}' (thread {2})", key.ComponentName, state, Thread.CurrentThread.ManagedThreadId);
            OnModuleStateChanged(component, state);
            Status = EvaluateParserState();
        }