private void EmitInterface(TransportModelInterface model, ICodeStream output)
        {
            var outputFile = (CodeFileCSharp)output.CreateCodeFile($"{CsEmitterHelper.GetCSharpModelShortName(model, ModelType.Transport)}.cs");

            var unit = CompilationUnit();

            unit = unit.AddUsings(
                UsingDirective(ParseName(nameof(System))));

            var entityInterface = InterfaceDeclaration(CsEmitterHelper.GetCSharpModelShortName(model, ModelType.Transport));

            entityInterface = entityInterface.AddModifiers(Token(SyntaxKind.PublicKeyword));

            if (model.GenericParameters.Count > 0)
            {
                entityInterface = entityInterface.WithTypeParameterList(TypeParameterList(SeparatedList <TypeParameterSyntax>(model.GenericParameters.Select(p => TypeParameter(p.Key)))));

                entityInterface = entityInterface.WithConstraintClauses(List <TypeParameterConstraintClauseSyntax>(
                                                                            model.GenericParameters.Select(p =>
                                                                                                           TypeParameterConstraintClause(
                                                                                                               IdentifierName(p.Key),
                                                                                                               SeparatedList <TypeParameterConstraintSyntax>(new[] { TypeConstraint(ParseTypeName(CsEmitterHelper.GetModelGenericParameterConstraintTypeName(p.Value, ModelType.Transport))) })))));
            }

            List <string> baseTypes = new List <string>();

            foreach (var interfaceModel in model.Interfaces)
            {
                baseTypes.Add(CsEmitterHelper.GetCSharpModelFullyQualifiedName(interfaceModel, this.settings, ModelType.Transport));
            }

            if (baseTypes.Count > 0)
            {
                entityInterface = entityInterface.WithBaseList(BaseList(SeparatedList <BaseTypeSyntax>(baseTypes.Select(t => SimpleBaseType(ParseTypeName(t))))));
            }

            entityInterface = entityInterface.WithMembers(List <MemberDeclarationSyntax>(model.Members.Select(m =>
                                                                                                              PropertyDeclaration(ParseTypeName(CsEmitterHelper.GetPropertyTypeName(m.Value, this.settings, ModelType.Transport)), NameHelper.GetSafeVariableName(m.Value.Name))
                                                                                                              .WithAccessorList(
                                                                                                                  SyntaxFactory.AccessorList(
                                                                                                                      SyntaxFactory.List <AccessorDeclarationSyntax>(new AccessorDeclarationSyntax[]
            {
                SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
                .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)),
                SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
                .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
            })))
                                                                                                              )));

            var nsContainer = NamespaceDeclaration(ParseName(this.settings.CsTransportModelNamespace));

            nsContainer           = nsContainer.AddMembers(entityInterface);
            unit                  = unit.AddMembers(nsContainer);
            outputFile.SyntaxTree = unit.SyntaxTree;
        }
        private MethodDeclarationSyntax EmitCollectionConversionMethod(TransportModelInterface baseNodeInterface)
        {
            var resultVarName = "result";

            var astNodeCollection = $"{this.settings.CsTransportModelCollectionType}<T>";

            var ienumerableTypeName = typeof(IEnumerable <>).FullName.Substring(0, typeof(IEnumerable <>).FullName.IndexOf('`'));
            var baseNodeIEnumerable = $"{ienumerableTypeName}<{CsEmitterHelper.GetCSharpModelFullyQualifiedName(baseNodeInterface, this.settings, ModelType.Transport)}>";

            var conversionMethod = MethodDeclaration(ParseTypeName(astNodeCollection), this.convertFromNodeCollectionMethodName)
                                   .AddModifiers(Token(SyntaxKind.PublicKeyword))
                                   .WithParameterList(ParameterList(SeparatedList <ParameterSyntax>(new[] { Parameter(Identifier(this.nodesParameterName)).WithType(ParseTypeName(baseNodeIEnumerable)) })))
                                   .WithTypeParameterList(TypeParameterList(SeparatedList <TypeParameterSyntax>(new[] { TypeParameter("T") })))
                                   .WithConstraintClauses(List <TypeParameterConstraintClauseSyntax>(new[]
            {
                TypeParameterConstraintClause(
                    IdentifierName("T"),
                    SeparatedList <TypeParameterConstraintSyntax>(new [] { TypeConstraint(ParseTypeName(CsEmitterHelper.GetCSharpModelFullyQualifiedName(baseNodeInterface, this.settings, ModelType.Ast))) }))
            }))
                                   .WithBody(Block());

            conversionMethod = conversionMethod.AddBodyStatements(
                IfStatement(
                    BinaryExpression(SyntaxKind.EqualsExpression, IdentifierName(this.nodesParameterName), IdentifierName("null")),
                    ReturnStatement(IdentifierName("null")))
                );

            conversionMethod = conversionMethod.AddBodyStatements(
                LocalDeclarationStatement(
                    VariableDeclaration(
                        ParseTypeName(astNodeCollection),
                        SeparatedList <VariableDeclaratorSyntax>(
                            new[]
            {
                VariableDeclarator(resultVarName)
                .WithInitializer(
                    EqualsValueClause(ObjectCreationExpression(ParseTypeName(astNodeCollection)).WithArgumentList(ArgumentList())))
            })
                        ))
                );

            var iteratorVarName = "node";

            conversionMethod = conversionMethod.AddBodyStatements(
                ForEachStatement(
                    ParseTypeName("var"),
                    iteratorVarName,
                    IdentifierName(this.nodesParameterName),
                    Block().AddStatements(
                        ExpressionStatement(
                            InvocationExpression(
                                MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, IdentifierName(resultVarName), IdentifierName("Add")),
                                ArgumentList(SeparatedList <ArgumentSyntax>(
                                                 new []
            {
                Argument(
                    CastExpression(
                        ParseTypeName("T"),
                        InvocationExpression(
                            MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, ThisExpression(), IdentifierName(this.convertFromNodeMethodName)),
                            ArgumentList(SeparatedList <ArgumentSyntax>(new [] { Argument(IdentifierName(iteratorVarName)) }))
                            )))
            })))
                            )
                        )));

            conversionMethod = conversionMethod.AddBodyStatements(ReturnStatement(IdentifierName(resultVarName)));

            return(conversionMethod);
        }