private MemberDeclarationSyntax CreatePropertyDeclaration(TransportModelEntityMember member)
        {
            if (CsEmitterHelper.IsNode(member.Type))
            {
                if (member.Type.IsCollection)
                {
                    return(PropertyDeclaration(ParseTypeName(CsEmitterHelper.GetAstModelPropertyTypeName(member, this.settings)), NameHelper.GetSafeVariableName(member.Name))
                           .WithAccessorList(
                               SyntaxFactory.AccessorList(
                                   SyntaxFactory.List <AccessorDeclarationSyntax>(new AccessorDeclarationSyntax[]
                    {
                        SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
                        .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)),
                        SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
                        .WithModifiers(TokenList(CsEmitterHelper.IsNodeCollection(member.Type) ? new [] { Token(SyntaxKind.PrivateKeyword) } : new SyntaxToken[0]))
                        .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
                    })))
                           .AddModifiers(Token(SyntaxKind.PublicKeyword)));
                }
                else
                {
                    return(PropertyDeclaration(ParseTypeName(CsEmitterHelper.GetAstModelPropertyTypeName(member, this.settings)), NameHelper.GetSafeVariableName(member.Name))
                           .WithAccessorList(
                               SyntaxFactory.AccessorList(
                                   SyntaxFactory.List <AccessorDeclarationSyntax>(new AccessorDeclarationSyntax[]
                    {
                        SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
                        .WithBody(Block(List <StatementSyntax>(new [] { ReturnStatement(MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, ThisExpression(), IdentifierName(this.GetFieldName(member.Name)))) }))),
                        SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
                        .WithBody(
                            Block(
                                List <StatementSyntax>(new []
                        {
                            ExpressionStatement(
                                InvocationExpression(
                                    MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, ThisExpression(), IdentifierName("SetAsParentFor")),
                                    ArgumentList(SeparatedList <ArgumentSyntax>(new []
                            {
                                Argument(MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, ThisExpression(), IdentifierName(this.GetFieldName(member.Name)))),
                                Argument(IdentifierName("value"))
                            })))),
                            ExpressionStatement(
                                AssignmentExpression(
                                    SyntaxKind.SimpleAssignmentExpression,
                                    MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, ThisExpression(), IdentifierName(this.GetFieldName(member.Name))),
                                    IdentifierName("value")))
                        })))
                    })))
                           .AddModifiers(Token(SyntaxKind.PublicKeyword)));
                }
            }
            else
            {
                if (member.Type.IsCollection)
                {
                    throw new InvalidOperationException("Non-node collections are not supported yet.");
                }

                return(PropertyDeclaration(ParseTypeName(CsEmitterHelper.GetAstModelPropertyTypeName(member, this.settings)), NameHelper.GetSafeVariableName(member.Name))
                       .WithAccessorList(
                           SyntaxFactory.AccessorList(
                               SyntaxFactory.List <AccessorDeclarationSyntax>(new AccessorDeclarationSyntax[]
                {
                    SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
                    .WithBody(Block(List <StatementSyntax>(new [] { ReturnStatement(MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, ThisExpression(), IdentifierName(this.GetFieldName(member.Name)))) }))),
                    SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
                    .WithBody(
                        Block(
                            List <StatementSyntax>(new []
                    {
                        ExpressionStatement(
                            InvocationExpression(
                                MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, ThisExpression(), IdentifierName("EnsureIsEditable")),
                                ArgumentList(SeparatedList <ArgumentSyntax>()))),
                        ExpressionStatement(
                            AssignmentExpression(
                                SyntaxKind.SimpleAssignmentExpression,
                                MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, ThisExpression(), IdentifierName(this.GetFieldName(member.Name))),
                                IdentifierName("value")))
                    })))
                })))
                       .AddModifiers(Token(SyntaxKind.PublicKeyword)));
            }
        }
        public StatementSyntax EmitForEntity(TransportModelEntity entity, TransportModelEnum syntaxKindEnum)
        {
            var discriminant = entity.TsDiscriminant as TransportModelEntityTsDiscriminantSyntaxKind;

            var recognizedNodeVarName = "concreteNode";

            var block = Block();
            List <ArgumentSyntax> constructorArguments = new List <ArgumentSyntax>();

            block = block.AddStatements(
                LocalDeclarationStatement(
                    VariableDeclaration(
                        ParseTypeName("var"),
                        SeparatedList <VariableDeclaratorSyntax>(new[]
            {
                VariableDeclarator(recognizedNodeVarName)
                .WithInitializer(EqualsValueClause(CastExpression(ParseTypeName(CsEmitterHelper.GetCSharpModelFullyQualifiedName(entity, this.settings, ModelType.Transport)), IdentifierName(this.nodeParameterName))))
            })))
                );

            foreach (var member in CsEmitterHelper.GetMembers(entity))
            {
                if (member.Key != "kind")
                {
                    if (CsEmitterHelper.IsNode(member.Value.Type))
                    {
                        if (member.Value.Type.IsCollection)
                        {
                            constructorArguments.Add(
                                Argument(
                                    InvocationExpression(
                                        MemberAccessExpression(
                                            SyntaxKind.SimpleMemberAccessExpression,
                                            ThisExpression(),
                                            GenericName(
                                                Identifier(this.convertFromNodeCollectionMethodName),
                                                TypeArgumentList(SeparatedList <TypeSyntax>(new[]
                            {
                                ParseTypeName(CsEmitterHelper.GetCSharpModelFullyQualifiedName(((ITransportModelTypeReferenceTransportModelItem <TransportModelItem>)member.Value.Type).TransportModelItem, this.settings, ModelType.Ast))
                            })))),
                                        ArgumentList(SeparatedList <ArgumentSyntax>(new[]
                            {
                                Argument(
                                    MemberAccessExpression(
                                        SyntaxKind.SimpleMemberAccessExpression,
                                        IdentifierName(recognizedNodeVarName),
                                        IdentifierName(NameHelper.GetSafeVariableName(member.Key))))
                            })))
                                    ));
                        }
                        else
                        {
                            constructorArguments.Add(
                                Argument(
                                    CastExpression(
                                        ParseTypeName(CsEmitterHelper.GetAstModelPropertyTypeName(member.Value, this.settings, true)),
                                        InvocationExpression(
                                            MemberAccessExpression(
                                                SyntaxKind.SimpleMemberAccessExpression,
                                                ThisExpression(),
                                                IdentifierName(this.convertFromNodeMethodName)),
                                            ArgumentList(SeparatedList <ArgumentSyntax>(new[]
                            {
                                Argument(
                                    MemberAccessExpression(
                                        SyntaxKind.SimpleMemberAccessExpression,
                                        IdentifierName(recognizedNodeVarName),
                                        IdentifierName(NameHelper.GetSafeVariableName(member.Key))))
                            })))
                                        )
                                    ));
                        }
                    }
                    else
                    {
                        constructorArguments.Add(
                            Argument(
                                CastExpression(
                                    ParseTypeName(CsEmitterHelper.GetAstModelPropertyTypeName(member.Value, this.settings, true)),
                                    MemberAccessExpression(
                                        SyntaxKind.SimpleMemberAccessExpression,
                                        IdentifierName(recognizedNodeVarName),
                                        IdentifierName(NameHelper.GetSafeVariableName(member.Key))))));
                    }
                }
            }

            block = block.AddStatements(
                LocalDeclarationStatement(
                    VariableDeclaration(
                        ParseTypeName("var"),
                        SeparatedList <VariableDeclaratorSyntax>(new[]
            {
                VariableDeclarator("result")
                .WithInitializer(
                    EqualsValueClause(
                        ObjectCreationExpression(ParseTypeName(CsEmitterHelper.GetCSharpModelFullyQualifiedName(entity, this.settings, ModelType.Ast)))
                        .WithArgumentList(ArgumentList(SeparatedList <ArgumentSyntax>(constructorArguments)))))
            }))
                    ));

            block = block.AddStatements(ReturnStatement(IdentifierName("result")));

            var result = IfStatement(
                BinaryExpression(
                    SyntaxKind.EqualsExpression,
                    MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, IdentifierName(this.nodeParameterName), IdentifierName("kind")),
                    MemberAccessExpression(
                        SyntaxKind.SimpleMemberAccessExpression,
                        IdentifierName(CsEmitterHelper.GetCSharpModelFullyQualifiedName(syntaxKindEnum, this.settings, ModelType.Transport)),
                        IdentifierName(discriminant.SyntaxKindValueName))),
                block);

            return(result);
        }