static string HandleAddMethod(ParsedComponent parsedComponent, string add_extension)
        {
            var parameters = parsedComponent.Fields
                             .Select(x => x.Type + " " + x.Name)
                             .Aggregate((x, y) => x + ", " + y);

            var fieldSequence = parsedComponent.Fields
                                .Select(x => "c." + (parsedComponent.IsReactive() ? x.Name.VariateFirstChar() : x.Name.FirstCharToUpper()) + " = " + x.Name + ";")
                                .Aggregate((x, y) => x + Format.NewLine(2) + y);

            add_extension = add_extension
                            .Replace(ComponentParametersTag, parameters)
                            .Replace(AddingComponentsSequenceTag, fieldSequence);
            return(add_extension);
        }
        void GenerateComponentReactives(ParsedComponent parsedComponent)
        {
            if (!parsedComponent.HasFields)
            {
                return;
            }

            string result = MayBakeUsings() ? parsedComponent.Usings : string.Empty;

            var snippet = File.ReadAllText(settings.CodeSnippets.ComponentReactive);

            var subSnippet = snippet.Split(new string[] { ComponentReactiveBlock }, StringSplitOptions.None)[1];

            string members = "";

            if (parsedComponent.IsReactive())
            {
                members = parsedComponent.Fields
                          .Select(field => subSnippet
                                  .Replace(FieldPascalCaseTag, field.Name.VariateFirstChar())
                                  .Replace(FieldCamelCaseTag, field.Name)
                                  .Replace(FieldCamelCase_SetTag, field.Name == "value" ? "this." + field.Name : field.Name)
                                  .Replace(FieldTypeTag, field.Type)
                                  .Replace(FieldIdTag, field.Index.ToString()))
                          .Aggregate((x, y) => x + Format.NewLine(1) + y);
            }
            else
            {
                members = parsedComponent.Fields
                          .Select(field => $"public {field.Type} {field.Name.FirstCharToUpper()};")
                          .Aggregate((x, y) => x + Format.NewLine(1) + y);
            }

            var componentReactive = snippet
                                    .Replace(ComponentNameTag, parsedComponent.ComponentName)
                                    .Replace(subSnippet, members)
                                    .Replace(ComponentReactiveBlock, "");

            if (MayBakeUsings())
            {
                componentReactive = parsedComponent.Usings + componentReactive;
            }

            SaveGeneration(componentReactive,
                           new Tag(TagKeys.Component, parsedComponent.ComponentName),
                           new Tag(TagKeys.GenerationType, GenerationTypes.Reactive));
        }
        void GenerateGroupBuilders(ParsedComponent parsedComponent)
        {
            var group_builder_snippet = File.ReadAllText(settings.CodeSnippets.Group_Builder);

            foreach (var context in parsedComponent.Contexts)
            {
                var group_builderFile = group_builder_snippet
                                        .Replace(ContextNameTag, context)
                                        .Replace(ComponentNameTag, parsedComponent.ComponentName);

                SaveGeneration(group_builderFile,
                               new Tag(TagKeys.Context, context),
                               new Tag(TagKeys.Component, parsedComponent.ComponentName),
                               new Tag(TagKeys.GenerationType, GenerationTypes.GroupBuilder));

                if (!parsedComponent.HasFields || !parsedComponent.IsReactive())
                {
                    continue;
                }

                var snippetPath = parsedComponent.Fields.Length > 1 ? settings.CodeSnippets.Collector : settings.CodeSnippets.CollectorFieldless;

                var collector_snippet = File.ReadAllText(snippetPath);

                var componentEnumValues = parsedComponent.Fields
                                          .Select(field => field.Name)
                                          .Aggregate((x, y) => x + "," + Format.NewLine(1) + y);

                var collector_File = collector_snippet
                                     .Replace(ComponentNameTag, parsedComponent.ComponentName)
                                     .Replace(ComponentEnumValuesTag, componentEnumValues)
                                     .Replace(ContextNameTag, context);

                SaveGeneration(collector_File,
                               new Tag(TagKeys.Context, context),
                               new Tag(TagKeys.Component, parsedComponent.ComponentName),
                               new Tag(TagKeys.GenerationType, GenerationTypes.Collector));
            }
        }
        void GenerateComponentExtensions(ParsedComponent parsedComponent)
        {
            foreach (var context in parsedComponent.Contexts)
            {
                string result = MayBakeUsings() ? parsedComponent.Usings : string.Empty;

                // Header
                var snippetHeader   = File.ReadAllText(settings.CodeSnippets.ComponentHeader);
                var componentHeader = snippetHeader
                                      .Replace(ComponentNameTag, parsedComponent.ComponentName);

                result += Format.NewLine() + componentHeader;

                // Get Property
                var snippet_Get       = File.ReadAllText(settings.CodeSnippets.ComponentExtensions_Get_Property);
                var snippet_Fieldless = File.ReadAllText(settings.CodeSnippets.ComponentExtensions_Fieldless);

                var snippet = parsedComponent.HasFields ? snippet_Get : snippet_Fieldless;

                var get_extension =
                    snippet
                    .Replace(ComponentNameTag, parsedComponent.ComponentName)
                    .Replace(ContextNameTag, context);

                result += Format.NewLine() + get_extension;

                if (parsedComponent.HasFields)
                {
                    // Add Method
                    var snippet_Add = File.ReadAllText(settings.CodeSnippets.ComponentExtensions_Add_Method);

                    string add_extension = snippet_Add;

                    add_extension = HandleAddMethod(parsedComponent, add_extension);

                    var clearActionsSequence = parsedComponent.Fields
                                               .Select(x => string.Format("{0}.On{1}Change = null;", parsedComponent.ComponentName, x.Name.VariateFirstChar()))
                                               .Aggregate((x, y) => x + Format.NewLine(2) + y);

                    var NanoListFieldsInitialization = parsedComponent.Fields.ToList()
                                                       .Where(field => field.Type.Contains("NanoList"))
                                                       .Select(y =>
                                                               Format.NewLine() + "c." +
                                                               (parsedComponent.IsReactive() ? y.Name.VariateFirstChar() : y.Name.FirstCharToUpper())
                                                               + ".Initialize(c._InternalOnValueChange, " + y.Index + ");" +
                                                               Format.NewLine() + "if (c." + y.Name.VariateFirstChar() + ".Count > 0) { c._InternalOnValueChange(" + y.Index + "); }" +
                                                               Format.NewLine()).ToList();

                    add_extension = add_extension
                                    .Replace(ClearingActionsSequenceTag, parsedComponent.IsReactive() ? clearActionsSequence : "")
                                    .Replace(ComponentNameTag, parsedComponent.ComponentName)
                                    .Replace(ContextNameTag, context);

                    if (NanoListFieldsInitialization.Count > 0)
                    {
                        var marker = "return this;";
                        NanoListFieldsInitialization.ForEach(x => add_extension = add_extension.Insert(add_extension.IndexOf(marker), x));
                    }

                    result += Format.NewLine() + add_extension;
                }

                result = GenaratedHeader + result;

                var prefix = state.Contexts.Count > 1 ? context : string.Empty;

                SaveGeneration(result,
                               new Tag(TagKeys.Context, context),
                               new Tag(TagKeys.GenerationType, GenerationTypes.AddRemove));
            }
        }