public ExistingSolutionInitVm(
            IGameCategoryContext gameCategoryContext,
            IPatcherFactory patcherFactory,
            IValidateProjectPath validateProjectPath,
            ICreateProject createProject,
            IAddProjectToSolution addProjectToSolution)
        {
            SolutionPath.PathType         = PathPickerVM.PathTypeOptions.File;
            SolutionPath.ExistCheckOption = PathPickerVM.CheckOptions.On;
            SolutionPath.Filters.Add(new CommonFileDialogFilter("Solution", ".sln"));

            var validation = Observable.CombineLatest(
                SolutionPath.PathState(),
                this.WhenAnyValue(x => x.ProjectName),
                (sln, proj) => (sln, proj, validation: validateProjectPath.Validate(proj, sln)))
                             .Replay(1)
                             .RefCount();

            _projectError = validation
                            .Select(i => (ErrorResponse)i.validation)
                            .ToGuiProperty <ErrorResponse>(this, nameof(ProjectError), ErrorResponse.Success);

            InitializationCall = validation
                                 .Select((i) =>
            {
                if (!i.sln.Succeeded)
                {
                    return(i.sln.BubbleFailure <InitializerCall>());
                }
                if (!i.validation.Succeeded)
                {
                    return(i.validation.BubbleFailure <InitializerCall>());
                }
                return(GetResponse <InitializerCall> .Succeed(async() =>
                {
                    createProject.Create(gameCategoryContext.Category, i.validation.Value);
                    addProjectToSolution.Add(i.sln.Value, i.validation.Value);
                    var patcher = patcherFactory.GetSolutionPatcher(new SolutionPatcherSettings()
                    {
                        SolutionPath = i.sln.Value,
                        ProjectSubpath = Path.Combine(i.proj, $"{i.proj}.csproj"),
                    });
                    return patcher.AsEnumerable();
                }));
            });
        }
        public NewSolutionInitVm(
            IGameCategoryContext gameCategoryContext,
            IPatcherFactory patcherFactory,
            IValidateProjectPath validateProjectPath,
            ICreateSolutionFile createSolutionFile,
            ICreateProject createProject,
            IAddProjectToSolution addProjectToSolution,
            IGenerateGitIgnore gitIgnore)
        {
            ParentDirPath.PathType         = PathPickerVM.PathTypeOptions.Folder;
            ParentDirPath.ExistCheckOption = PathPickerVM.CheckOptions.On;

            _solutionPath = Observable.CombineLatest(
                this.ParentDirPath.PathState(),
                this.WhenAnyValue(x => x.SolutionName),
                (parentDir, slnName) =>
            {
                if (string.IsNullOrWhiteSpace(slnName))
                {
                    return(GetResponse <string> .Fail(val: slnName, reason: "Solution needs a name."));
                }

                // Will reevaluate once parent dir is fixed
                if (parentDir.Failed)
                {
                    return(GetResponse <string> .Succeed(value: slnName));
                }
                try
                {
                    var slnPath = Path.Combine(parentDir.Value, slnName);
                    if (File.Exists(slnPath))
                    {
                        return(GetResponse <string> .Fail(val: slnName, reason: $"Target solution folder cannot already exist as a file: {slnPath}"));
                    }
                    if (Directory.Exists(slnPath) &&
                        (Directory.EnumerateFiles(slnPath).Any() ||
                         Directory.EnumerateDirectories(slnPath).Any()))
                    {
                        return(GetResponse <string> .Fail(val: slnName, reason: $"Target solution folder must be empty: {slnPath}"));
                    }
                    return(GetResponse <string> .Succeed(Path.Combine(slnPath, $"{slnName}.sln")));
                }
                catch (ArgumentException)
                {
                    return(GetResponse <string> .Fail(val: slnName, reason: "Improper solution name. Go simpler."));
                }
            })
                            .ToGuiProperty(this, nameof(SolutionPath));

            var validation = Observable.CombineLatest(
                this.ParentDirPath.PathState(),
                this.WhenAnyValue(x => x.SolutionName),
                this.WhenAnyValue(x => x.SolutionPath),
                this.WhenAnyValue(x => x.ProjectName),
                (parentDir, slnName, sln, proj) =>
            {
                // Use solution name if proj empty.
                if (string.IsNullOrWhiteSpace(proj))
                {
                    proj = SolutionNameProcessor(slnName);
                }
                return(parentDir, sln, proj, validation: validateProjectPath.Validate(proj, sln));
            })
                             .Replay(1)
                             .RefCount();

            _projectError = validation
                            .Select(i => (ErrorResponse)i.validation)
                            .ToGuiProperty <ErrorResponse>(this, nameof(ProjectError), ErrorResponse.Success);

            InitializationCall = validation
                                 .Select((i) =>
            {
                if (i.parentDir.Failed)
                {
                    return(i.parentDir.BubbleFailure <InitializerCall>());
                }
                if (i.sln.Failed)
                {
                    return(i.sln.BubbleFailure <InitializerCall>());
                }
                if (i.validation.Failed)
                {
                    return(i.validation.BubbleFailure <InitializerCall>());
                }
                return(GetResponse <InitializerCall> .Succeed(async() =>
                {
                    var projName = Path.GetFileNameWithoutExtension(i.validation.Value);
                    createSolutionFile.Create(i.sln.Value);
                    createProject.Create(gameCategoryContext.Category, i.validation.Value);
                    addProjectToSolution.Add(i.sln.Value, i.validation.Value);
                    gitIgnore.Generate(Path.GetDirectoryName(i.sln.Value) !);
                    var patcher = patcherFactory.GetSolutionPatcher(new SolutionPatcherSettings()
                    {
                        SolutionPath = i.sln.Value,
                        ProjectSubpath = Path.Combine(projName, $"{projName}.csproj")
                    });
                    return patcher.AsEnumerable();
                }));
            });

            _projectNameWatermark = this.WhenAnyValue(x => x.SolutionName)
                                    .Select(x => string.IsNullOrWhiteSpace(x) ? "The name of the patcher" : SolutionNameProcessor(x))
                                    .ToGuiProperty <string>(this, nameof(ProjectNameWatermark), string.Empty);
        }