internal Transition(ITaskDefinitionSymbol containingTask, 
                            TransitionDefinitionSyntax syntax, 
                            NodeReferenceSymbol source, 
                            EdgeModeSymbol edgeMode, 
                            NodeReferenceSymbol target, 
                            SymbolCollection<TriggerSymbol> triggers)  {

            if (containingTask == null) {
                throw new ArgumentNullException(nameof(containingTask));
            }

            if (syntax == null) {
                throw new ArgumentNullException(nameof(syntax));
            }

            ContainingTask = containingTask;
            Syntax   = syntax;
            Source   = source;
            EdgeMode = edgeMode;
            Target   = target;
            Triggers = triggers??new SymbolCollection<TriggerSymbol>();

            foreach (var trigger in Triggers) {
                trigger.Transition = this;
            }
        }
        internal Transition(TransitionDefinitionSyntax syntax, 
                            NodeReferenceSymbol source, 
                            EdgeModeSymbol edgeMode, 
                            NodeReferenceSymbol target, 
                            SymbolCollection<TriggerSymbol> triggers)  {

            if (syntax == null) {
                throw new ArgumentNullException(nameof(syntax));
            }

            Syntax   = syntax;
            Source   = source;
            EdgeMode = edgeMode;
            Target   = target;
            Triggers = triggers??new SymbolCollection<TriggerSymbol>();
        }
        SymbolCollection<TriggerSymbol> GetTriggers(TransitionDefinitionSyntax transitionDefinitionSyntax) {

            var triggers = new List<TriggerSymbol>();
            
            if (transitionDefinitionSyntax.Trigger != null) {
                _triggers = triggers;
                Visit(transitionDefinitionSyntax.Trigger);
                _triggers = null;
            }
            
            var result = new SymbolCollection<TriggerSymbol>();
            foreach(var trigger in triggers) {
                var existing = result.TryFindSymbol(trigger.Name);
                if(existing != null) {

                    _diagnostics.Add(new Diagnostic(
                        existing.Location, 
                        DiagnosticDescriptors.Semantic.Nav0026TriggerWithName0AlreadyDeclared, 
                        existing.Name));

                    _diagnostics.Add(new Diagnostic(trigger.Location,
                        DiagnosticDescriptors.Semantic.Nav0026TriggerWithName0AlreadyDeclared,
                        trigger.Name));

                } else {
                    result.Add(trigger);
                }
            }

            return result;
        }
        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);
        }
		public override void PostWalkTransitionDefinition(TransitionDefinitionSyntax transitionDefinitionSyntax) { 
			MethodsCalled["PostWalkTransitionDefinition"]=true;
		}
		// TransitionDefinitionSyntax
		public override bool WalkTransitionDefinition(TransitionDefinitionSyntax transitionDefinitionSyntax) { 
			MethodsCalled["WalkTransitionDefinition"]=true;
			return true; 
		}