protected NavInvocationAnnotation(NavTaskAnnotation taskAnnotation, 
                                   IdentifierNameSyntax identifier): base(taskAnnotation) {
     if(identifier == null) {
         throw new ArgumentNullException(nameof(identifier));
     }
     Identifier = identifier;
 }
        protected NavMethodAnnotation(NavTaskAnnotation taskAnnotation,
                                      MethodDeclarationSyntax methodDeclarationSyntax) : base(taskAnnotation) {

            if (methodDeclarationSyntax == null) {
                throw new ArgumentNullException(nameof(methodDeclarationSyntax));
            }
            MethodDeclarationSyntax = methodDeclarationSyntax;
        }
        public NavInitCallAnnotation(NavTaskAnnotation taskAnnotation, 
                                        IdentifierNameSyntax identifier, 
                                        string beginItfFullyQualifiedName, 
                                        List<string> parameter)
            : base(taskAnnotation, identifier) {

            BeginItfFullyQualifiedName = beginItfFullyQualifiedName ?? String.Empty;
            Parameter                  = (parameter ?? new List<string>()).ToImmutableList();
        }
        protected NavTaskAnnotation(NavTaskAnnotation other) {

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

            ClassDeclarationSyntax          = other.ClassDeclarationSyntax;
            DeclaringClassDeclarationSyntax = other.DeclaringClassDeclarationSyntax;
            TaskName                        = other.TaskName;
            NavFileName                     = other.NavFileName;
        }
 public NavInitAnnotation(NavTaskAnnotation taskAnnotation,
                          MethodDeclarationSyntax methodDeclaration, 
                          string initName): base(taskAnnotation, methodDeclaration) {
     InitName = initName ?? String.Empty;
 }
        public NavTriggerAnnotation(NavTaskAnnotation taskAnnotation, 
                                    MethodDeclarationSyntax methodDeclaration, 
                                    string triggerName) : base(taskAnnotation, methodDeclaration) {

            TriggerName = triggerName??String.Empty;
        }
 public NavExitAnnotation(NavTaskAnnotation taskAnnotation, 
                          MethodDeclarationSyntax methodDeclaration, 
                          string exitTaskName): base(taskAnnotation, methodDeclaration) {
     ExitTaskName = exitTaskName??String.Empty;
 }
        static IEnumerable<NavInitCallAnnotation> ReadInitCallAnnotation(
                        SemanticModel semanticModel,
                        NavTaskAnnotation navTaskAnnotation,
                        IEnumerable<InvocationExpressionSyntax> invocationExpressions) {

            if (semanticModel == null || navTaskAnnotation == null) {
                yield break;
            }

            foreach (var invocationExpression in invocationExpressions) {

                var identifier = invocationExpression.Expression as IdentifierNameSyntax;
                if (identifier == null) {
                    continue;
                }

                var methodSymbol = semanticModel.GetSymbolInfo(identifier).Symbol as IMethodSymbol;
                if (methodSymbol == null) {
                    continue;
                }

                var declaringMethodNode = methodSymbol.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax();
                var navInitCallTag = ReadNavTags(declaringMethodNode).FirstOrDefault(tag => tag.TagName == AnnotationTagNames.NavInitCall);
                if (navInitCallTag == null) {
                    continue;
                }

                var callAnnotation = new NavInitCallAnnotation(
                    taskAnnotation            : navTaskAnnotation,
                    identifier                : identifier,
                    beginItfFullyQualifiedName: navInitCallTag.Content,
                    parameter                 : ToComparableParameterTypeList(methodSymbol.Parameters));


                yield return callAnnotation;
            }
        }
        static IEnumerable<NavMethodAnnotation> ReadMethodAnnotations(
                            SemanticModel semanticModel, 
                            NavTaskAnnotation navTaskAnnotation, 
                            IEnumerable<MethodDeclarationSyntax> methodDeclarations) {

            foreach (var methodDeclaration in methodDeclarations) {

                var methodSymbol = semanticModel.GetDeclaredSymbol(methodDeclaration);
                if(methodSymbol == null) {
                    continue;
                }

                // Init Annotation
                var initAnnotation = ReadNavInitAnnotation(navTaskAnnotation, methodDeclaration, methodSymbol);
                if(initAnnotation != null) {
                    yield return initAnnotation;
                }

                // Exit Annotation
                var navExitAnnotation = ReadNavExitAnnotation(navTaskAnnotation, methodDeclaration, methodSymbol);
                if (navExitAnnotation != null) {
                    yield return navExitAnnotation;
                }

                // Trigger Annotation
                var triggerAnnotation = ReadNavTriggerAnnotation(navTaskAnnotation, methodDeclaration, methodSymbol);
                if (triggerAnnotation != null) {
                    yield return triggerAnnotation;
                }               
            }
        }
        static NavTaskAnnotation ReadNavTaskAnnotationInternal(
                            [NotNull] ClassDeclarationSyntax classDeclaration,
                            [NotNull] ClassDeclarationSyntax declaringClassDeclaration) {

            var tags = ReadNavTags(declaringClassDeclaration).ToList();

            var navFileTag  = tags.FirstOrDefault(t => t.TagName == AnnotationTagNames.NavFile);
            var navFileName = navFileTag?.Content;

            var navTaskTag  = tags.FirstOrDefault(t => t.TagName == AnnotationTagNames.NavTask);
            var navTaskName = navTaskTag?.Content;

            // Dateiname und Taskname müssen immer paarweise vorhanden sein
            if (String.IsNullOrWhiteSpace(navFileName) || String.IsNullOrWhiteSpace(navTaskName)) {
                return null;
            }

            // Relative Pfadangaben in absolute auflösen
            if (!Path.IsPathRooted(navFileName)) {
                var declaringNodePath = declaringClassDeclaration.GetLocation().GetLineSpan().Path;

                if (String.IsNullOrWhiteSpace(declaringNodePath)) {
                    return null;
                }

                var declaringDir = Path.GetDirectoryName(declaringNodePath);
                if (declaringDir == null) {
                    return null;
                }

                navFileName = Path.GetFullPath(Path.Combine(declaringDir, navFileName));
            }

            var taskAnnotation = new NavTaskAnnotation(
                classDeclarationSyntax         : classDeclaration, 
                declaringClassDeclarationSyntax: declaringClassDeclaration,
                taskName                       : navTaskName, 
                navFileName                    : navFileName); 

            return taskAnnotation;
        }