/// <summary>
        /// Tries to parse and return the state transitions for the given machine.
        /// </summary>
        /// <param name="stateTransitions">State transitions</param>
        /// <param name="machine">Machine</param>
        /// <param name="model">SemanticModel</param>
        /// <returns>Boolean value</returns>
        private static bool TryParseStateTransitions(out Dictionary <ClassDeclarationSyntax,
                                                                     HashSet <ClassDeclarationSyntax> > stateTransitions, ClassDeclarationSyntax machine,
                                                     SemanticModel model)
        {
            stateTransitions = new Dictionary <ClassDeclarationSyntax, HashSet <ClassDeclarationSyntax> >();

            var defineGotoStateTransitionsMethod = machine.ChildNodes().
                                                   OfType <MethodDeclarationSyntax>().FirstOrDefault(v
                                                                                                     => v.Identifier.ValueText.Equals("DefineGotoStateTransitions") &&
                                                                                                     v.Modifiers.Any(SyntaxKind.OverrideKeyword) && v.ReturnType.ToString().
                                                                                                     Equals("System.Collections.Generic.Dictionary<Type, GotoStateTransitions>"));

            if (defineGotoStateTransitionsMethod == null)
            {
                return(false);
            }

            var returnStmt = defineGotoStateTransitionsMethod.DescendantNodes().
                             OfType <ReturnStatementSyntax>().First();
            var returnSymbol = model.GetSymbolInfo(returnStmt.Expression).Symbol;
            Dictionary <ClassDeclarationSyntax, IdentifierNameSyntax> stateMap = null;

            if (!StateTransitionAnalysis.TryParseStateMap(out stateMap, returnSymbol,
                                                          defineGotoStateTransitionsMethod, model))
            {
                return(false);
            }

            foreach (var state in stateMap)
            {
                if (state.Value == null)
                {
                    continue;
                }

                var dictionarySymbol      = model.GetSymbolInfo(state.Value).Symbol;
                var dictionaryInvocations = StateTransitionAnalysis.GetInvocationsFromSymbol(
                    dictionarySymbol, defineGotoStateTransitionsMethod);

                var transitions = ParseTransitions(dictionarySymbol,
                                                   defineGotoStateTransitionsMethod, model);
                if (transitions.Count == 0)
                {
                    continue;
                }

                stateTransitions.Add(state.Key, transitions);
            }

            return(true);
        }
        /// <summary>
        /// Parses and returns the state map from the given symbol.
        /// </summary>
        /// <param name="stateMap">State map</param>
        /// <param name="symbol">Symbol</param>
        /// <param name="method">Method</param>
        /// <param name="model">SemanticModel</param>
        /// <returns>Boolean value</returns>
        private static bool TryParseStateMap(out Dictionary <ClassDeclarationSyntax, IdentifierNameSyntax> stateMap,
                                             ISymbol symbol, MethodDeclarationSyntax method, SemanticModel model)
        {
            stateMap = new Dictionary <ClassDeclarationSyntax, IdentifierNameSyntax>();

            var invocations = StateTransitionAnalysis.GetInvocationsFromSymbol(symbol, method);

            foreach (var inv in invocations)
            {
                if (!(inv.Expression is MemberAccessExpressionSyntax))
                {
                    continue;
                }

                var expr = inv.Expression as MemberAccessExpressionSyntax;
                if (!expr.Name.ToString().Equals("Add"))
                {
                    continue;
                }

                var stateType = (inv.ArgumentList.Arguments[0].Expression
                                 as TypeOfExpressionSyntax).Type as IdentifierNameSyntax;
                var dictionary = inv.ArgumentList.Arguments[1].Expression
                                 as IdentifierNameSyntax;
                var stateSymbol     = model.GetTypeInfo(stateType).Type;
                var stateDefinition = SymbolFinder.FindSourceDefinitionAsync(stateSymbol,
                                                                             ProgramInfo.Solution).Result;
                if (stateDefinition == null)
                {
                    return(false);
                }

                var state = stateDefinition.DeclaringSyntaxReferences.First().GetSyntax()
                            as ClassDeclarationSyntax;
                stateMap.Add(state, dictionary);
            }

            return(true);
        }
        /// <summary>
        /// Parses and returns the list of actions from the given symbol.
        /// </summary>
        /// <param name="actions">List of actions</param>
        /// <param name="symbol">Symbol</param>
        /// <param name="method">Method</param>
        /// <param name="model">SemanticModel</param>
        /// <returns>Set of actions</returns>
        private static HashSet <MethodDeclarationSyntax> ParseActions(ISymbol symbol,
                                                                      MethodDeclarationSyntax method, SemanticModel model)
        {
            var actions = new HashSet <MethodDeclarationSyntax>();

            var invocations = StateTransitionAnalysis.GetInvocationsFromSymbol(symbol, method);

            foreach (var inv in invocations)
            {
                if (!(inv.Expression is MemberAccessExpressionSyntax))
                {
                    continue;
                }

                var expr = inv.Expression as MemberAccessExpressionSyntax;
                if (!expr.Name.ToString().Equals("Add"))
                {
                    continue;
                }

                var actionType = (inv.ArgumentList.Arguments[1].Expression
                                  as ObjectCreationExpressionSyntax).ArgumentList.Arguments[0].
                                 Expression as IdentifierNameSyntax;
                var actionSymbol     = model.GetSymbolInfo(actionType).Symbol;
                var actionDefinition = SymbolFinder.FindSourceDefinitionAsync(actionSymbol,
                                                                              ProgramInfo.Solution).Result;
                if (actionDefinition == null)
                {
                    continue;
                }

                var action = actionDefinition.DeclaringSyntaxReferences.First().GetSyntax()
                             as MethodDeclarationSyntax;
                actions.Add(action);
            }

            return(actions);
        }