/// <summary>
        /// Returns the candidate callees after resolving the specified invocation.
        /// </summary>
        /// <param name="invocation">InvocationExpressionSyntax</param>
        /// <param name="node">IDataFlowNode</param>
        /// <returns>Set of candidate callees</returns>
        private static HashSet <MethodDeclarationSyntax> ResolveCandidateMethodsAtCallSite(
            InvocationExpressionSyntax invocation, IDataFlowNode node)
        {
            var candidateCallees           = new HashSet <MethodDeclarationSyntax>();
            var candidateMethodDeclaration = MethodSummaryResolver.ResolveMethodDeclaration(
                invocation, node) as MethodDeclarationSyntax;

            if (candidateMethodDeclaration == null)
            {
                return(candidateCallees);
            }

            if (candidateMethodDeclaration.Modifiers.Any(SyntaxKind.AbstractKeyword) ||
                candidateMethodDeclaration.Modifiers.Any(SyntaxKind.VirtualKeyword) ||
                candidateMethodDeclaration.Modifiers.Any(SyntaxKind.OverrideKeyword))
            {
                HashSet <MethodDeclarationSyntax> overriders = null;
                if (!MethodSummaryResolver.TryGetCandidateMethodOverriders(out overriders,
                                                                           invocation, node))
                {
                    return(candidateCallees);
                }

                candidateCallees.UnionWith(overriders);
            }

            if (candidateCallees.Count == 0)
            {
                candidateCallees.Add(candidateMethodDeclaration);
            }

            return(candidateCallees);
        }