void AddTransition(Transition transition) {

            //==============================
            // Source Errors
            //==============================
            if(transition.Source != null) {

                if(transition.Source.Declaration == null) {
                    _diagnostics.Add(new Diagnostic(
                        transition.Source.Location, 
                        DiagnosticDescriptors.Semantic.Nav0011CannotResolveNode0, 
                        transition.Source.Name));

                } else if(transition.Source.Declaration is TaskNodeSymbol) {
                    _diagnostics.Add(new Diagnostic(
                        transition.Source.Location, 
                        DiagnosticDescriptors.Semantic.Nav0100TaskNode0MustNotContainLeavingEdges, 
                        transition.Source.Name));

                } else if(transition.Source.Declaration is ExitNodeSymbol) {
                    _diagnostics.Add(new Diagnostic(
                        transition.Source.Location, 
                        DiagnosticDescriptors.Semantic.Nav0101ExitNodeMustNotContainLeavingEdges));

                } else if(transition.Source.Declaration is EndNodeSymbol) {
                    _diagnostics.Add(new Diagnostic(
                        transition.Source.Location, 
                        DiagnosticDescriptors.Semantic.Nav0102EndNodeMustNotContainLeavingEdges) );

                } else if(transition.Source.Declaration is InitNodeSymbol) {
                    var node = (InitNodeSymbol) transition.Source.Declaration;
                    node.Outgoings.Add(transition);
                    node.References.Add(transition.Source);

                } else if(transition.Source.Declaration is DialogNodeSymbol) {
                    var node = (DialogNodeSymbol) transition.Source.Declaration;
                    node.Outgoings.Add(transition);
                    node.References.Add(transition.Source);

                } else if(transition.Source.Declaration is ViewNodeSymbol) {
                    var node = (ViewNodeSymbol) transition.Source.Declaration;
                    node.Outgoings.Add(transition);
                    node.References.Add(transition.Source);

                } else if(transition.Source.Declaration is ChoiceNodeSymbol) {                   
                    var node = (ChoiceNodeSymbol) transition.Source.Declaration;
                    node.Outgoings.Add(transition);
                    node.References.Add(transition.Source);
                }
            }

            //==============================
            // Target Errors
            //==============================
            if (transition.Target != null) {

                if (transition.Target.Declaration == null) {
                    _diagnostics.Add(new Diagnostic(
                        transition.Target.Location, 
                        DiagnosticDescriptors.Semantic.Nav0011CannotResolveNode0, 
                        transition.Target.Name));

                } else if (transition.Target.Declaration is InitNodeSymbol) {
                    _diagnostics.Add(new Diagnostic(
                        transition.Target.Location,
                        DiagnosticDescriptors.Semantic.Nav0103InitNodeMustNotContainIncomingEdges));

                } else if (transition.Target.Declaration is EndNodeSymbol) {
                    var node = (EndNodeSymbol)transition.Target.Declaration;
                    node.Incomings.Add(transition);
                    node.References.Add(transition.Target);

                } else if (transition.Target.Declaration is ExitNodeSymbol) {
                    var node = (ExitNodeSymbol)transition.Target.Declaration;
                    node.Incomings.Add(transition);
                    node.References.Add(transition.Target);

                } else if (transition.Target.Declaration is DialogNodeSymbol) {
                    var node = (DialogNodeSymbol)transition.Target.Declaration;
                    node.Incomings.Add(transition);
                    node.References.Add(transition.Target);

                } else if (transition.Target.Declaration is ViewNodeSymbol) {
                    var node = (ViewNodeSymbol)transition.Target.Declaration;
                    node.Incomings.Add(transition);
                    node.References.Add(transition.Target);

                } else if (transition.Target.Declaration is ChoiceNodeSymbol) {
                    var node = (ChoiceNodeSymbol)transition.Target.Declaration;
                    node.Incomings.Add(transition);
                    node.References.Add(transition.Target);

                } else if (transition.Target.Declaration is TaskNodeSymbol) {
                    var node = (TaskNodeSymbol)transition.Target.Declaration;
                    node.Incomings.Add(transition);
                    node.References.Add(transition.Target);
                }
            }

            //==============================
            // Edge Errors
            //==============================
            if (transition.EdgeMode !=null) {

                if(transition.EdgeMode.EdgeMode != EdgeMode.Goto) {

                    if(transition.Target?.Declaration is ChoiceNodeSymbol) {
                        _diagnostics.Add(new Diagnostic(
                            transition.EdgeMode.Location,
                            DiagnosticDescriptors.Semantic.Nav0104ChoiceNode0MustOnlyReachedByGoTo,
                            transition.Target.Name));
                    }

                    if(transition.Target?.Declaration is ExitNodeSymbol) {
                        _diagnostics.Add(new Diagnostic(
                            transition.EdgeMode.Location,
                            DiagnosticDescriptors.Semantic.Nav0105ExitNode0MustOnlyReachedByGoTo,
                            transition.Target.Name) );
                    }

                    if(transition.Target?.Declaration is EndNodeSymbol) {
                        _diagnostics.Add(new Diagnostic(
                            transition.EdgeMode.Location,
                            DiagnosticDescriptors.Semantic.Nav0106EndNode0MustOnlyReachedByGoTo,
                            transition.Target.Name) );
                    }
                }
            }

            //==============================
            // Trigger Errors
            //==============================
            if (transition.Triggers.Any()) {

                foreach(var trigger in transition.Triggers.Where(t=>t.IsSpontaneousTrigger)) {

                    if(!(transition.Source?.Declaration is DialogNodeSymbol ||
                         transition.Source?.Declaration is ViewNodeSymbol ||
                         transition.Source?.Declaration is InitNodeSymbol)) {

                        _diagnostics.Add(new Diagnostic(
                            trigger.Location,
                            DiagnosticDescriptors.Semantic.Nav0202SpontaneousOnlyAllowedAfterViewAndInitNodes));
                    }
                }

                foreach (var trigger in transition.Triggers.Where(t => t.IsSignalTrigger)) {

                    if (transition.Source?.Declaration is InitNodeSymbol) {
                        _diagnostics.Add(new Diagnostic(
                            trigger.Location, 
                            DiagnosticDescriptors.Semantic.Nav0200SignalTriggerNotAllowedAfterInit));
                    }

                    if (transition.Source?.Declaration is ChoiceNodeSymbol) {
                        _diagnostics.Add(new Diagnostic(
                                trigger.Location,
                                DiagnosticDescriptors.Semantic.Nav0203TriggerNotAllowedAfterChoice));
                    }

                    // TODO Keyword in eigene Klasse
                    if (trigger.Name == "spontaneous" || trigger.Name == "spont") {
                        _diagnostics.Add(new Diagnostic(
                            trigger.Location,
                            DiagnosticDescriptors.Semantic.Nav0201SpontaneousNotAllowedInSignalTrigger));
                    }
                }
            }

            //==============================
            // Condition Clause Errors
            //==============================
            if (transition.Syntax.ConditionClause != null) {

                if(transition.Source != null && ! (
                    transition.Source?.Declaration is InitNodeSymbol ||
                    transition.Source?.Declaration is ChoiceNodeSymbol)){

                    _diagnostics.Add(new Diagnostic(
                            transition.Syntax.ConditionClause.GetLocation(),
                            DiagnosticDescriptors.Semantic.Nav0220ConditionsAreOnlySupportedAfterInitAndChoiceNodes));

                }
            }

            _taskDefinition.Transitions.Add(transition);
        }
        public override void VisitTransitionDefinition(TransitionDefinitionSyntax transitionDefinitionSyntax) {
            
            // Source
            NodeReferenceSymbol sourceNodeReference = null;
            var sourceNodeSyntax = transitionDefinitionSyntax.SourceNode;
            if (sourceNodeSyntax != null) {

                var sourceNode = _taskDefinition.NodeDeclarations.TryFindSymbol(sourceNodeSyntax.Name);

                // Special case "init": Hier ist implizit auch Großschreibung erlaubt
                // TODO Keyword in eigene Klasse
                if (sourceNode == null && sourceNodeSyntax.Name=="init") {
                    sourceNode = _taskDefinition.NodeDeclarations.TryFindSymbol("Init");
                }

                var location   = sourceNodeSyntax.GetLocation();
                if(location != null) {
                    sourceNodeReference = new NodeReferenceSymbol(sourceNodeSyntax.Name, location, sourceNode);
                }
            }

            // Target
            NodeReferenceSymbol targetNodeReference = null;
            var targetNodeSyntax = transitionDefinitionSyntax.TargetNode;
            if (targetNodeSyntax != null) {

                var targetNode = _taskDefinition.NodeDeclarations.TryFindSymbol(targetNodeSyntax.Name);
                var location = targetNodeSyntax.GetLocation();
                if (location != null) {
                    targetNodeReference = new NodeReferenceSymbol(targetNodeSyntax.Name, location, targetNode);                
                }
            }
            
            // Edge
            EdgeModeSymbol edgeMode=null;
            var edgeSyntax = transitionDefinitionSyntax.Edge;
            if (edgeSyntax != null) {

                var location = edgeSyntax.GetLocation();
                if(location != null) {
                    edgeMode = new EdgeModeSymbol(edgeSyntax.ToString(), location, edgeSyntax.Mode);
                }
            }

            // Triggers
            var triggers = GetTriggers(transitionDefinitionSyntax);

            var transition = new Transition(_taskDefinition, transitionDefinitionSyntax, sourceNodeReference, edgeMode, targetNodeReference, triggers);
            
            AddTransition(transition);
        }