/// <summary>
        /// Traverse the statement and look of resulting interactions that are relevant for the sequence diagram.
        /// </summary>
        /// <remarks>
        /// Tracks flow over services, even if the same service becomes part of a different resulting event.
        /// </remarks>
        private Interactions TraverseBody(List <string> services, TypeDescription handler, string serviceName, Statement statement, string inAlternativeFlow)
        {
            switch (statement)
            {
            case InvocationDescription invocation when IsMessageCreation(invocation):

                var message = Program.Types.First(invocation.Arguments.Skip(invocation.Name == "RaiseEvent" ? 0 : 1).First().Type);

                return(ExtractConcequences(message, services, Service(handler), inAlternativeFlow, invocation.Arguments));

            case InvocationDescription invocation:
            {
                var result       = new Interactions();
                var consequences = Program.Types.GetInvocationConsequenceStatements2(invocation).Where(s => s != invocation);

                foreach (var consequence in consequences)
                {
                    var invocationInteractions = TraverseBody(services, handler, serviceName, consequence, inAlternativeFlow);
                    if (invocationInteractions.Fragments.Count > 0)
                    {
                        result.AddFragments(invocationInteractions.Fragments);
                    }
                }

                return(result);
            }

            case ForEach forEachStatement:
            {
                var result       = new Interactions();
                var interactions = new List <InteractionFragment>();

                foreach (var invocation in forEachStatement.Statements)
                {
                    var invocationInteractions = TraverseBody(services, handler, serviceName, invocation, inAlternativeFlow);
                    if (invocationInteractions.Fragments.Count > 0)
                    {
                        interactions.AddRange(invocationInteractions.Fragments);
                    }
                }

                if (interactions.Count > 0)
                {
                    var alt = new Alt();

                    var altSection = new AltSection();
                    altSection.AddFragments(interactions);
                    altSection.GroupType = "forEach";
                    altSection.Label     = forEachStatement.Expression;

                    alt.AddSection(altSection);

                    result.AddFragment(alt);
                }

                return(result);
            }

            case Switch switchStatement:
            {
                var result = new Interactions();

                var alt = new Alt();

                foreach (var section in switchStatement.Sections)
                {
                    var interactions = new List <InteractionFragment>();

                    foreach (var invocation in section.Statements)
                    {
                        var invocationInteractions = TraverseBody(services, handler, serviceName, invocation, inAlternativeFlow);
                        if (invocationInteractions.Fragments.Count > 0)
                        {
                            interactions.AddRange(invocationInteractions.Fragments);
                        }
                    }

                    if (interactions.Count > 0)
                    {
                        var altSection = new AltSection();
                        if (alt.Sections.Count == 0)
                        {
                            altSection.GroupType = "case";
                        }
                        ;
                        altSection.AddFragments(interactions);
                        altSection.Label = section.Labels.Aggregate(string.Empty, (s1, s2) => s1 + s2);
                        alt.AddSection(altSection);
                    }
                }

                if (alt.Sections.Count > 0)
                {
                    result.AddFragment(alt);
                }

                return(result);
            }

            case If ifStatement:
            {
                var result = new Interactions();

                var alt = new Alt();

                foreach (var section in ifStatement.Sections)
                {
                    var interactions = new List <InteractionFragment>();

                    foreach (var invocation in section.Statements)
                    {
                        var invocationInteractions = TraverseBody(services, handler, serviceName, invocation, inAlternativeFlow);
                        if (invocationInteractions.Fragments.Count > 0)
                        {
                            interactions.AddRange(invocationInteractions.Fragments);
                        }
                    }

                    if (interactions.Count > 0)
                    {
                        var altSection = new AltSection();
                        if (alt.Sections.Count == 0)
                        {
                            altSection.GroupType = "if";
                        }
                        ;
                        altSection.AddFragments(interactions);
                        altSection.Label = section.Condition;
                        alt.AddSection(altSection);
                    }
                }

                if (alt.Sections.Count > 0)
                {
                    result.AddFragment(alt);
                }

                return(result);
            }
            }

            return(new Interactions());
        }