/// <summary>
        /// Gets the possible <see cref="Declaration"/> that qualifies an identifier reference in a member access expression.
        /// </summary>
        protected IEnumerable <Declaration> GetQualifierCandidates(IdentifierReference reference, DeclarationFinder finder)
        {
            if (reference.Context.TryGetAncestor <VBAParser.MemberAccessExprContext>(out var memberAccess))
            {
                var parentModule         = Declaration.GetModuleParent(reference.ParentScoping);
                var qualifyingExpression = memberAccess.lExpression();
                if (qualifyingExpression is VBAParser.SimpleNameExprContext simpleName)
                {
                    if (simpleName.GetText().Equals(Tokens.Me, System.StringComparison.InvariantCultureIgnoreCase))
                    {
                        // qualifier is 'Me'
                        return(new[] { parentModule });
                    }

                    // todo get the actual qualifying declaration?
                    return(finder.MatchName(simpleName.GetText())
                           .Where(candidate => !candidate.IdentifierName.Equals(reference.Declaration.IdentifierName, System.StringComparison.InvariantCultureIgnoreCase)));
                }

                if (qualifyingExpression.ChildCount == 1 && qualifyingExpression.GetText().Equals(Tokens.Me, System.StringComparison.InvariantCultureIgnoreCase))
                {
                    // qualifier is 'Me'
                    return(new[] { parentModule });
                }
            }

            if (reference.Context.TryGetAncestor <VBAParser.WithMemberAccessExprContext>(out var dot))
            {
                // qualifier is a With block
                var withBlock = dot.GetAncestor <VBAParser.WithStmtContext>();
                return(finder.ContainedIdentifierReferences(new QualifiedSelection(reference.QualifiedModuleName, withBlock.GetSelection()))
                       .Select(r => r.Declaration).Distinct()
                       .Where(candidate => !candidate.Equals(reference.Declaration)));
            }

            if (reference.Context.TryGetAncestor <VBAParser.CallStmtContext>(out var callStmt))
            {
                if (reference.Context.TryGetAncestor <VBAParser.LExpressionContext>(out var lExpression))
                {
                    // reference is in lexpression of a call statement

                    if (lExpression is VBAParser.MemberAccessExprContext member)
                    {
                        if (member.lExpression() is VBAParser.SimpleNameExprContext name)
                        {
                            if (reference.IdentifierName.Equals(name.identifier().GetText(), System.StringComparison.InvariantCultureIgnoreCase))
                            {
                                // unqualified
                                return(Enumerable.Empty <Declaration>());
                            }

                            return(finder.MatchName(name.identifier().GetText())
                                   .Where(candidate => !candidate.Equals(reference.Declaration)));
                        }

                        // todo get the actual qualifying declaration?
                        return(finder.MatchName(member.lExpression().children.First().GetText())
                               .Where(candidate => !candidate.Equals(reference.Declaration)));
                    }
                }
            }

            return(Enumerable.Empty <Declaration>());
        }