private static void CreateCSharpFiles(DartModel model, string destination)
        {
            foreach (var folder in model)
            {
                var destinationFolder = Path.Combine(destination, folder.Key);

                // Check Folder
                if (!Directory.Exists(destinationFolder))
                {
                    Directory.CreateDirectory(destinationFolder);
                }

                foreach (var file in folder.Value)
                {
                    // Create CSharp File
                    var csharpFile          = CSharpWriter.CreateFile(file, model);
                    var destinationFileName = $"{file.Name.Substring(0, file.Name.IndexOf("."))}.cs";

                    var destinationPath = Path.Combine(destinationFolder, destinationFileName);


                    if (!File.Exists(destinationFileName))
                    {
                        File.Create(destinationPath).Close();
                    }

                    File.WriteAllText(destinationPath, csharpFile);
                }
            }
        }
        private static DartModel BuildDartModel(string source)
        {
            var model = new DartModel();

            foreach (var sourceDirectory in Directory.GetDirectories(source))
            {
                var folder = sourceDirectory.Replace(source, "").TrimStart('\\');

                foreach (var sourceFilePath in Directory.GetFiles(sourceDirectory))
                {
                    // Create Model from Dart File
                    var sourceFileName = sourceFilePath.Replace(sourceDirectory, "").TrimStart('\\');
                    var dart           = File.ReadAllText(sourceFilePath);
                    var file           = DartClassReader.Construct(sourceFileName, folder, dart);

                    if (model.ContainsKey(folder))
                    {
                        model[folder].Add(file);
                    }
                    else
                    {
                        var list = new List <DartFile>();
                        model.Add(folder, list);
                        list.Add(file);
                    }
                }
            }

            return(model);
        }
        static void Main(string[] args)
        {
            string source       = @"..\..\..\..\flutter\lib\src";
            string destination  = @"..\..\..\..\FlutterSDK\src";
            string modelStorage = @"..\..\..\..\model.json";

            DartModel model = null;

            if (File.Exists(modelStorage))
            {
                model = JsonConvert.DeserializeObject <DartModel>(File.ReadAllText(modelStorage));
            }

            if (model == null)
            {
                model = BuildDartModel(source);
                File.WriteAllText(modelStorage, JsonConvert.SerializeObject(model));
            }

            PostProcessDart(model);

            CreateCSharpFiles(model, destination);

            List <DartFile> dartFiles = model.SelectMany(x => x.Value).ToList();

            Console.WriteLine($"Files: {dartFiles.Count.ToString("N0")}");
            Console.WriteLine($"File Sections: {dartFiles.Sum(x => x.Sections.Count).ToString("N0")}");
            Console.WriteLine($"File Imports: {dartFiles.Sum(x => x.Imports.Count).ToString("N0")}");
            Console.WriteLine($"Classes: {dartFiles.Sum(x => x.Classes.Count).ToString("N0")}");
            Console.WriteLine($"Class Sections: {dartFiles.Sum(x => x.Classes.Select(y => y.Sections.Count).Sum()).ToString("N0")}");

            //Console.ReadLine();
        }
        private static void PostProcessDart(DartModel model)
        {
            ClassList = new Dictionary <string, DartClass>();

            foreach ((string folder, IList <DartFile> file) in model)
            {
                foreach (var @class in file.SelectMany(x => x.Classes))
                {
                    var name = @class.RawName;
                    if (name.Contains("<"))
                    {
                        name = name.Substring(0, name.IndexOf("<")) + "<>";
                    }

                    ClassList.Add($"{folder}.{name.Replace("<T>", "<>")}", @class);
                }
            }

            InheritanceCalculation(ClassList);

            PropertyCombination(ClassList);

            foreach (var file in model.Values.SelectMany(x => x))
            {
                foreach (var item in file.Sections.Where(x => x.Type == SectionType.Enum))
                {
                    if (!CSharpWriter.Enums.Contains(item.Name))
                    {
                        CSharpWriter.Enums.Add(item.Name);
                    }
                }
            }
        }
        public static string CreateFile(DartFile dart, DartModel model)
        {
            var @namespace = SyntaxFactory.NamespaceDeclaration(SyntaxFactory.ParseName(dart.Folder))
                             .NormalizeWhitespace();

            foreach (var @class in dart.Classes)
            {
                var classDeclaration = SyntaxFactory.ClassDeclaration(@class.Name);
                classDeclaration = classDeclaration.AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword));

                // Add class to namespace
                @namespace = @namespace.AddMembers(classDeclaration);
            }

            // Output code
            var code = @namespace
                       .NormalizeWhitespace()
                       .ToFullString();

            return(code);
        }