private static bool TryGetInputNodeFromCallActivityInvocation(SemanticModel semanticModel, InvocationExpressionSyntax invocationExpression, out SyntaxNode inputNode)
        {
            // If method invocation is a custom CallActivity extension method defined in user code
            if (SyntaxNodeUtils.TryGetDeclaredSyntaxNode(semanticModel, invocationExpression, out SyntaxNode declaration))
            {
                if (TryGetSpecificParameterIndex(declaration, "object input", out int inputParameterIndex))
                {
                    if (TryGetInvocationArguments(invocationExpression, out IEnumerable <ArgumentSyntax> arguments))
                    {
                        var argumentNode = arguments.ElementAt(inputParameterIndex);
                        inputNode = argumentNode.ChildNodes().First();
                        return(true);
                    }
                }
            }
            // else assume CallActivity is a DurableFunctions method
            else
            {
                if (TryGetInvocationArguments(invocationExpression, out IEnumerable <ArgumentSyntax> arguments))
                {
                    // Input node is currently the last argument on CallActivity* methods. If this is changed, this will not be sufficient to
                    // determine which argument is meant to represent the input.
                    var argumentNode = arguments.Last();
                    inputNode = argumentNode.ChildNodes().First();
                    return(true);
                }
            }

            inputNode = null;
            return(false);
        }
        private bool TryFindEntityInterface(SyntaxNodeAnalysisContext context, SyntaxNode identifierName, out EntityInterface entityInterface)
        {
            if (SyntaxNodeUtils.TryGetDeclaredSyntaxNode(context.SemanticModel, identifierName, out SyntaxNode declaration))
            {
                if (IsInterface(declaration))
                {
                    entityInterface = new EntityInterface {
                        Name = identifierName.ToString(), InterfaceDeclaration = declaration
                    };
                    return(true);
                }
            }

            entityInterface = null;
            return(false);
        }
        private void FindInvokedMethods(SemanticModel semanticModel, MethodInformation parentMethodInformation)
        {
            var parentDeclaration     = parentMethodInformation.Declaration;
            var invocationExpressions = parentDeclaration.DescendantNodes().OfType <InvocationExpressionSyntax>();

            foreach (var invocation in invocationExpressions)
            {
                if (SyntaxNodeUtils.TryGetDeclaredSyntaxNode(semanticModel, invocation, out SyntaxNode invokedMethodDeclaration) &&
                    invokedMethodDeclaration is MethodDeclarationSyntax &&
                    SyntaxNodeUtils.TryGetISymbol(semanticModel, invocation, out ISymbol invokedSymbol))
                {
                    if (this.orchestratorMethodDeclarations.TryGetValue(invokedSymbol, out MethodInformation existingMethodInformation))
                    {
                        existingMethodInformation.Invocations.Add(invocation);
                        if (!existingMethodInformation.Equals(parentMethodInformation))
                        {
                            existingMethodInformation.Parents.Add(parentMethodInformation);
                        }
                    }
                    else
                    {
                        var invokedMethodInformation = new MethodInformation()
                        {
                            SemanticModel     = semanticModel,
                            Declaration       = invokedMethodDeclaration,
                            DeclarationSymbol = invokedSymbol,
                            Invocations       = new List <InvocationExpressionSyntax>()
                            {
                                invocation
                            },
                            Parents = new HashSet <MethodInformation>(new List <MethodInformation>()
                            {
                                parentMethodInformation
                            }),
                        };

                        this.orchestratorMethodDeclarations.Add(invokedSymbol, invokedMethodInformation);

                        FindInvokedMethods(semanticModel, invokedMethodInformation);
                    }
                }
            }
        }