public StMethodDeclaration EmitNodeCollectionConversionFunction(CodeFileTs output)
        {
            var resultName         = "result";
            var nodesParameterName = "nodes";
            Func <StExpressionWithTypeArguments> arrayOfAnyType = () => { return(new StExpressionWithTypeArguments().WithExpression(new StIdentifier().WithEscapedText("Array")).WithTypeArgument(new StKeywordTypeNodeAnyKeyword())); };

            var convertFunction = new StMethodDeclaration()
                                  .WithName(new StIdentifier().WithEscapedText(convertNodesMethodName))
                                  .WithModifier(new StPublicKeywordToken())
                                  .WithType(arrayOfAnyType())
                                  .WithParameter(p =>
                                                 p
                                                 .WithName(new StIdentifier().WithEscapedText(nodesParameterName))
                                                 .WithType(arrayOfAnyType()))
                                  .WithBody(b =>
                                            b.WithStatement(
                                                new StIfStatement()
                                                .WithExpression(
                                                    new StBinaryExpression()
                                                    .WithLeft(new StIdentifier().WithEscapedText(nodesParameterName))
                                                    .WithOperatorToken(new StEqualsEqualsTokenToken())
                                                    .WithRight(new StIdentifier().WithEscapedText("null")))
                                                .WithThenStatement(new StBlock().WithStatement(new StReturnStatement().WithExpression(new StIdentifier().WithEscapedText("undefined")))))
                                            .WithStatement(
                                                new StVariableStatement()
                                                .WithDeclarationList(
                                                    vdl => vdl
                                                    .WithDeclaration(vd =>
                                                                     vd
                                                                     .WithName(new StIdentifier().WithEscapedText(resultName))
                                                                     .WithType(arrayOfAnyType())
                                                                     .WithInitializer(new StNewExpression().WithExpression(new StIdentifier().WithEscapedText("Array")).WithTypeArgument(new StKeywordTypeNodeAnyKeyword())))))
                                            .WithStatement(
                                                new StForStatement()
                                                .WithInitializer(
                                                    new StVariableDeclarationList()
                                                    .WithDeclaration(vd =>
                                                                     vd.WithName(new StIdentifier().WithEscapedText("i"))
                                                                     .WithType(new StKeywordTypeNodeNumberKeyword())
                                                                     .WithInitializer(new StNumericLiteral().WithText("0"))))
                                                .WithCondition(
                                                    new StBinaryExpression()
                                                    .WithLeft(new StIdentifier().WithEscapedText("i"))
                                                    .WithOperatorToken(new StLessThanTokenToken())
                                                    .WithRight(new StPropertyAccessExpression().WithExpression(new StIdentifier().WithEscapedText(nodesParameterName)).WithName(new StIdentifier().WithEscapedText("length"))))
                                                .WithIncrementor(new StPostfixUnaryExpression().WithOperand(new StIdentifier().WithEscapedText("i")).WithOperator(SyntaxKind.PlusPlusToken))
                                                .WithStatement(
                                                    new StExpressionStatement()
                                                    .WithExpression(
                                                        new StCallExpression()
                                                        .WithExpression(new StPropertyAccessExpression().WithExpression(new StIdentifier().WithEscapedText(resultName)).WithName(new StIdentifier().WithEscapedText("push")))
                                                        .WithArgument(
                                                            new StCallExpression()
                                                            .WithExpression(
                                                                new StPropertyAccessExpression()
                                                                .WithExpression(new StThisExpression())
                                                                .WithName(new StIdentifier().WithEscapedText(this.convertNodeMethodName)))
                                                            .WithArgument(
                                                                new StElementAccessExpression()
                                                                .WithExpression(new StIdentifier().WithEscapedText(nodesParameterName))
                                                                .WithArgumentExpression(new StIdentifier().WithEscapedText("i"))
                                                                )))))
                                            .WithStatement(
                                                new StReturnStatement().WithExpression(new StIdentifier().WithEscapedText(resultName))
                                                ));

            return(convertFunction);
        }
        private StMethodDeclaration EmitNodeConversionFunction(Parameters parameters, CodeFileTs output)
        {
            var nodeParameterName = "node";

            var convertFunction = new StMethodDeclaration()
                                  .WithName(new StIdentifier().WithEscapedText(this.convertNodeMethodName))
                                  .WithModifier(new StPublicKeywordToken())
                                  .WithType(new StKeywordTypeNodeAnyKeyword())
                                  .WithBody(b => b)
                                  .WithParameter(p =>
                                                 p
                                                 .WithName(new StIdentifier().WithEscapedText(nodeParameterName))
                                                 .WithType(new StKeywordTypeNodeAnyKeyword()));

            convertFunction.body.WithStatement(
                new StIfStatement()
                .WithExpression(
                    new StBinaryExpression()
                    .WithLeft(new StIdentifier().WithEscapedText(nodeParameterName))
                    .WithOperatorToken(new StEqualsEqualsTokenToken())
                    .WithRight(new StIdentifier().WithEscapedText("null")))
                .WithThenStatement(new StBlock().WithStatement(new StReturnStatement().WithExpression(new StIdentifier().WithEscapedText("undefined")))));

            foreach (var entity in parameters.TransportModel.TransportModelEntities.Where(e => e.Value.TsCreationFunctionBinding != null && !(e.Value.TsCreationFunctionBinding is TransportModelFunctionBindingSkipped)))
            {
                if (entity.Value.TsDiscriminant is null)
                {
                    throw new InvalidOperationException($"Entity {entity.Key} whould have {nameof(entity.Value.TsDiscriminant)} in order to have conversion from transport to AST.");
                }

                var block = new StBlock();

                List <IStExpression> arguments = new List <IStExpression>();

                int index = -1;
                foreach (var param in entity.Value.TsCreationFunctionBinding.Parameters)
                {
                    index++;
                    var member = this.GetBoundMember(param, entity.Value);

                    ////if (member.Type is TransportModelTypeReferenceGenericParameter)
                    ////{
                    ////    throw new InvalidOperationException($"Generic parameter reference {member.Name} is not supported in creation method parameter binding for {entity.Key}");
                    ////}

                    if (member.Type is ITransportModelTypeReferenceTransportModelItem <TransportModelItem> modelItemReference && !(modelItemReference.TransportModelItem is TransportModelEnum))
                    {
                        var varName = $"paramVar{index}";

                        block.statements.Add(
                            new StVariableStatement()
                            .WithDeclarationList(l =>
                                                 l.WithDeclaration(d =>
                                                                   d.WithName(new StIdentifier().WithEscapedText(varName))
                                                                   .WithType(new StKeywordTypeNodeAnyKeyword())
                                                                   .WithInitializer(
                                                                       new StCallExpression()
                                                                       .WithExpression(
                                                                           new StPropertyAccessExpression()
                                                                           .WithExpression(new StThisExpression())
                                                                           .WithName(new StIdentifier().WithEscapedText(member.Type.IsCollection ? this.convertNodesMethodName : convertNodeMethodName)))
                                                                       .WithArgument(
                                                                           new StPropertyAccessExpression()
                                                                           .WithExpression(new StIdentifier().WithEscapedText(nodeParameterName))
                                                                           .WithName(new StIdentifier().WithEscapedText(member.Name)))))));

                        arguments.Add(new StIdentifier().WithEscapedText(varName));
                        continue;
                    }

                    arguments.Add(new StPropertyAccessExpression()
                                  .WithExpression(new StIdentifier().WithEscapedText(nodeParameterName))
                                  .WithName(new StIdentifier().WithEscapedText(member.Name)));
                }

                var call = new StCallExpression()
                           .WithExpression(new StPropertyAccessExpression().WithExpression(new StIdentifier().WithEscapedText(typescriptAliasName)).WithName(new StIdentifier().WithEscapedText(entity.Value.TsCreationFunctionBinding.Name)));

                arguments.ForEach(a => call.arguments.Add(a));

                block.statements.Add(
                    new StReturnStatement()
                    .WithExpression(call));

                convertFunction.body.WithStatement(
                    new StIfStatement()
                    .WithExpression(
                        new StBinaryExpression()
                        .WithLeft(new StPropertyAccessExpression()
                                  .WithExpression(new StIdentifier().WithEscapedText(nodeParameterName))
                                  .WithName(new StIdentifier().WithEscapedText("kind")))
                        .WithOperatorToken(new StEqualsEqualsTokenToken())
                        .WithRight(new StPropertyAccessExpression()
                                   .WithExpression(new StPropertyAccessExpression().WithExpression(new StIdentifier().WithEscapedText(typescriptAliasName)).WithName(new StIdentifier().WithEscapedText("SyntaxKind")))
                                   .WithName(new StIdentifier().WithEscapedText(((TransportModelEntityTsDiscriminantSyntaxKind)entity.Value.TsDiscriminant).SyntaxKindValueName))))
                    .WithThenStatement(block));
            }

            return(convertFunction);
        }
        private void EmitTypeMarkerFunction(Parameters parameters, CodeFileTs output)
        {
            var name = "TypeMarker";
            var nodeParameterName    = "node";
            var typescriptModuleName = "typescript";
            var typescriptAliasName  = "T";
            var typePropertyName     = "$type";

            var importStatement = new StImportDeclaration()
                                  .WithModuleSpecifier(new StStringLiteral().WithText(typescriptModuleName))
                                  .WithImportClause(c =>
                                                    c
                                                    .WithNamedBindings(new StNamespaceImport().WithName(new StIdentifier().WithEscapedText(typescriptAliasName)))
                                                    );

            var classDefinition = new StClassDeclaration()
                                  .WithModifier(new StExportKeywordToken())
                                  .WithName(new StIdentifier().WithEscapedText(name));

            var markerFunction = new StMethodDeclaration()
                                 .WithName(new StIdentifier().WithEscapedText("Mark"))
                                 .WithModifier(new StPublicKeywordToken())
                                 .WithType(new StKeywordTypeNodeBooleanKeyword())
                                 .WithBody(b => b)
                                 .WithParameter(p =>
                                                p
                                                .WithName(new StIdentifier().WithEscapedText(nodeParameterName))
                                                .WithType(new StKeywordTypeNodeAnyKeyword()));

            foreach (var entity in parameters.TransportModel.TransportModelEntities.Where(e => e.Value.TsDiscriminant is TransportModelEntityTsDiscriminantSyntaxKind))
            {
                markerFunction.body.WithStatement(
                    new StIfStatement()
                    .WithExpression(
                        new StBinaryExpression()
                        .WithLeft(new StPropertyAccessExpression()
                                  .WithExpression(new StIdentifier().WithEscapedText(nodeParameterName))
                                  .WithName(new StIdentifier().WithEscapedText("kind")))
                        .WithOperatorToken(new StEqualsEqualsTokenToken())
                        .WithRight(new StPropertyAccessExpression()
                                   .WithExpression(new StPropertyAccessExpression().WithExpression(new StIdentifier().WithEscapedText(typescriptAliasName)).WithName(new StIdentifier().WithEscapedText("SyntaxKind")))
                                   .WithName(new StIdentifier().WithEscapedText(((TransportModelEntityTsDiscriminantSyntaxKind)entity.Value.TsDiscriminant).SyntaxKindValueName))))
                    .WithThenStatement(new StBlock()
                                       .WithStatement(
                                           new StExpressionStatement()
                                           .WithExpression(
                                               new StBinaryExpression()
                                               .WithLeft(
                                                   new StPropertyAccessExpression()
                                                   .WithExpression(new StIdentifier().WithEscapedText(nodeParameterName))
                                                   .WithName(new StIdentifier().WithEscapedText(typePropertyName)))
                                               .WithOperatorToken(new StEqualsTokenToken())
                                               .WithRight(new StStringLiteral()
                                                          .WithText($"{CsEmitterHelper.GetCSharpModelFullyQualifiedName(entity.Value, this.settings, ModelType.Transport)}, {this.settings.CsTransportModelAssemblyName}"))))
                                       .WithStatement(
                                           new StReturnStatement()
                                           .WithExpression(new StBooleanLiteralTrueKeyword()))));
            }

            markerFunction.body
            .WithStatement(new StReturnStatement()
                           .WithExpression(new StBooleanLiteralFalseKeyword()));

            classDefinition.members.Add(markerFunction);

            output.Model = new StRoot()
                           .WithStatement(importStatement)
                           .WithStatement(classDefinition);
        }