public UpgradeGameApplicationService(
            DataConnection dataConnection,
            DataConnectionValidationService dataConnectionValidationService,
            DataExportService dataExportService,
            DataImportService dataImportService,
            DomainModelService domainModelService,
            DomainModelExportService domainModelExportService,
            DomainModelImportService domainModelImportService,
            GameFolderValidator gameFolderValidator,
            GameExecutableValidator gameExecutableValidator,
            LanguageFileValidator languageFileValidator,
            CommentaryFileValidator commentaryFileValidator,
            EmbeddedResourceDeployer embeddedResourceDeployer,
            GameExecutableCodePatcher gameExecutableCodePatcher)
        {
            _dataConnection = dataConnection ?? throw new ArgumentNullException(nameof(dataConnection));
            _dataConnectionValidationService = dataConnectionValidationService ?? throw new ArgumentNullException(nameof(dataConnectionValidationService));
            _dataExportService         = dataExportService ?? throw new ArgumentNullException(nameof(dataExportService));
            _dataImportService         = dataImportService ?? throw new ArgumentNullException(nameof(dataImportService));
            _domainModelExportService  = domainModelExportService ?? throw new ArgumentNullException(nameof(domainModelExportService));
            _domainModelImportService  = domainModelImportService ?? throw new ArgumentNullException(nameof(domainModelImportService));
            _gameFolderValidator       = gameFolderValidator ?? throw new ArgumentNullException(nameof(gameFolderValidator));
            _gameExecutableValidator   = gameExecutableValidator ?? throw new ArgumentNullException(nameof(gameExecutableValidator));
            _languageFileValidator     = languageFileValidator ?? throw new ArgumentNullException(nameof(languageFileValidator));
            _commentaryFileValidator   = commentaryFileValidator ?? throw new ArgumentNullException(nameof(commentaryFileValidator));
            _embeddedResourceDeployer  = embeddedResourceDeployer ?? throw new ArgumentNullException(nameof(embeddedResourceDeployer));
            _gameExecutableCodePatcher = gameExecutableCodePatcher ?? throw new ArgumentNullException(nameof(gameExecutableCodePatcher));

            DomainModel = domainModelService ?? throw new ArgumentNullException(nameof(domainModelService));
        }
        public LanguageFileEditorApplicationService(
            DataConnection dataConnection,
            DataConnectionValidationService dataConnectionValidationService,
            DataExportService dataExportService,
            DataImportService dataImportService,
            DomainModelService domainModelService,
            LanguageFileEditorDomainModelExportService domainModelExportService,
            LanguageFileEditorDomainModelImportService domainModelImportService)
        {
            _dataConnection = dataConnection ?? throw new ArgumentNullException(nameof(dataConnection));
            _dataConnectionValidationService = dataConnectionValidationService ?? throw new ArgumentNullException(nameof(dataConnectionValidationService));
            _dataExportService        = dataExportService ?? throw new ArgumentNullException(nameof(dataExportService));
            _dataImportService        = dataImportService ?? throw new ArgumentNullException(nameof(dataImportService));
            _domainModelExportService = domainModelExportService ?? throw new ArgumentNullException(nameof(domainModelExportService));
            _domainModelImportService = domainModelImportService ?? throw new ArgumentNullException(nameof(domainModelImportService));

            DomainModel = domainModelService ?? throw new ArgumentNullException(nameof(domainModelService));
        }
        public ConfigureGameApplicationService(
            DataConnection dataConnection,
            DataConnectionValidationService dataConnectionValidationService,
            DataExportService dataExportService,
            DataImportService dataImportService,
            DomainModelService domainModelService,
            DomainModelExportService domainModelExportService,
            DomainModelImportService domainModelImportService,
            GameExecutableCodePatcher gameExecutableCodePatcher)
        {
            _dataConnection = dataConnection ?? throw new ArgumentNullException(nameof(dataConnection));
            _dataConnectionValidationService = dataConnectionValidationService ?? throw new ArgumentNullException(nameof(dataConnectionValidationService));
            _dataExportService         = dataExportService ?? throw new ArgumentNullException(nameof(dataExportService));
            _dataImportService         = dataImportService ?? throw new ArgumentNullException(nameof(dataImportService));
            _domainModelExportService  = domainModelExportService ?? throw new ArgumentNullException(nameof(domainModelExportService));
            _domainModelImportService  = domainModelImportService ?? throw new ArgumentNullException(nameof(domainModelImportService));
            _gameExecutableCodePatcher = gameExecutableCodePatcher ?? throw new ArgumentNullException(nameof(gameExecutableCodePatcher));

            DomainModel = domainModelService ?? throw new ArgumentNullException(nameof(domainModelService));
        }
        public void ImportConfiguration(DomainModelService domainModel, string gameExecutableFilePath)
        {
            // Compatibility
            domainModel.Configurations.DisableGameCd     = _gameCdFix.IsCodeModified(gameExecutableFilePath);
            domainModel.Configurations.DisableColourMode = _displayModeFix.IsCodeModified(gameExecutableFilePath);
            domainModel.Configurations.DisableSampleApp  = _sampleAppFix.IsCodeModified(gameExecutableFilePath);
            domainModel.Configurations.DisableMemoryResetForRaceSounds = _raceSoundsFix.IsCodeModified(gameExecutableFilePath);
            // domainModel.Configurations.DisablePitExitPriority = _pitExitPriorityFix.IsCodeModified(gameExecutableFilePath); // TODO: Not implemented yet

            // Gameplay
            domainModel.Configurations.DisableYellowFlagPenalties         = _yellowFlagFix.IsCodeModified(gameExecutableFilePath);
            domainModel.Configurations.EnableCarHandlingDesignCalculation = _carDesignCalculationUpdate.IsCodeModified(gameExecutableFilePath);
            domainModel.Configurations.EnableCarPerformanceRaceCalcuation = _carHandlingPerformanceFix.IsCodeModified(gameExecutableFilePath);
            domainModel.Configurations.GameYear = _gameYearUpdate.GetGameYear(gameExecutableFilePath);

            // Points Scoring System
            domainModel.Configurations.PointsScoringSystemDefault = _pointsSystemF119912002Update.IsCodeModified(gameExecutableFilePath);
            domainModel.Configurations.PointsScoringSystemOption1 = _pointsSystemF119811990Update.IsCodeModified(gameExecutableFilePath);
            domainModel.Configurations.PointsScoringSystemOption2 = _pointsSystemF120032009Update.IsCodeModified(gameExecutableFilePath);
            domainModel.Configurations.PointsScoringSystemOption3 = _pointsSystemF1201020XxUpdate.IsCodeModified(gameExecutableFilePath);

            // Track Editor
            domainModel.Configurations.EnableTrackEditor = _trackEditorFix.IsCodeModified(gameExecutableFilePath);
        }
        public void ExportConfiguration(DomainModelService domainModel, string gameExecutableFilePath)
        {
            // Scenarios for each reversible code module
            // Scenario 1: If currently applied and should not be applied, apply unmodified code
            // Scenario 2: If currently not applied and should be applied, apply modified code
            // Scenario 3: If currently applied and should be applied, do nothing
            // Scenario 4: If currently not applied and should not be applied, do nothing

            // Compatibility
            var isGameCdFixApplied  = _gameCdFix.IsCodeModified(gameExecutableFilePath);
            var isGameCdFixRequired = domainModel.Configurations.DisableGameCd;

            if (isGameCdFixApplied != isGameCdFixRequired)
            {
                ApplyReversibleCode(_gameCdFix, isGameCdFixRequired, gameExecutableFilePath);
            }

            var isDisplayModeFixApplied  = _displayModeFix.IsCodeModified(gameExecutableFilePath);
            var isDisplayModeFixRequired = domainModel.Configurations.DisableColourMode;

            if (isDisplayModeFixApplied != isDisplayModeFixRequired)
            {
                ApplyReversibleCode(_displayModeFix, isDisplayModeFixRequired, gameExecutableFilePath);
            }

            var isSampleAppFixApplied  = _sampleAppFix.IsCodeModified(gameExecutableFilePath);
            var isSampleAppFixRequired = domainModel.Configurations.DisableSampleApp;

            if (isSampleAppFixApplied != isSampleAppFixRequired)
            {
                ApplyReversibleCode(_sampleAppFix, isSampleAppFixRequired, gameExecutableFilePath);
            }

            var isRaceSoundsFixApplied  = _raceSoundsFix.IsCodeModified(gameExecutableFilePath);
            var isRaceSoundsFixRequired = domainModel.Configurations.DisableMemoryResetForRaceSounds;

            if (isRaceSoundsFixApplied != isRaceSoundsFixRequired)
            {
                ApplyReversibleCode(_raceSoundsFix, isRaceSoundsFixRequired, gameExecutableFilePath);
            }

            // var isPitExitPriorityFixApplied = _pitExitPriorityFix.IsCodeModified(gameExecutableFilePath);       // TODO: Not implemented yet
            // var isPitExitPriorityFixRequired = domainModel.Configurations.DisablePitExitPriority;               // TODO: Not implemented yet
            // if (isPitExitPriorityFixApplied != isPitExitPriorityFixRequired)                                    // TODO: Not implemented yet
            // {                                                                                                   // TODO: Not implemented yet
            //     ApplyReversibleCode(_pitExitPriorityFix, isPitExitPriorityFixRequired, gameExecutableFilePath); // TODO: Not implemented yet
            // }                                                                                                   // TODO: Not implemented yet

            // Gameplay
            var isYellowFlagFixApplied  = _yellowFlagFix.IsCodeModified(gameExecutableFilePath);
            var isYellowFlagFixRequired = domainModel.Configurations.DisableYellowFlagPenalties;

            if (isYellowFlagFixApplied != isYellowFlagFixRequired)
            {
                ApplyReversibleCode(_yellowFlagFix, isYellowFlagFixRequired, gameExecutableFilePath);
            }

            var isCarDesignCalculationUpdateApplied  = _carDesignCalculationUpdate.IsCodeModified(gameExecutableFilePath);
            var isCarDesignCalculationUpdateRequired = domainModel.Configurations.EnableCarHandlingDesignCalculation;

            if (isCarDesignCalculationUpdateApplied != isCarDesignCalculationUpdateRequired)
            {
                ApplyReversibleCode(_carDesignCalculationUpdate, isCarDesignCalculationUpdateRequired, gameExecutableFilePath);
            }

            var isCarHandlingPerformanceFixApplied  = _carHandlingPerformanceFix.IsCodeModified(gameExecutableFilePath);
            var isCarHandlingPerformanceFixRequired = domainModel.Configurations.EnableCarPerformanceRaceCalcuation;

            if (isCarHandlingPerformanceFixApplied != isCarHandlingPerformanceFixRequired)
            {
                ApplyReversibleCode(_carHandlingPerformanceFix, isCarHandlingPerformanceFixRequired, gameExecutableFilePath);
            }

            _gameYearUpdate.SetGameYear(domainModel.Configurations.GameYear, gameExecutableFilePath);

            // Scenarios for each irreversible code module
            // Scenario 1: If currently not applied and should be applied, apply modified code
            // Scenario 2: If currently not applied and should not be applied, do nothing
            // Scenario 3: If currently applied, do nothing

            // Points Scoring System
            var isPointsScoringSystemDefaultApplied  = _pointsSystemF119912002Update.IsCodeModified(gameExecutableFilePath);
            var isPointsScoringSystemDefaultRequired = domainModel.Configurations.PointsScoringSystemDefault;

            if (!isPointsScoringSystemDefaultApplied && isPointsScoringSystemDefaultRequired)
            {
                ApplyIrreversibleCode(_pointsSystemF119912002Update, gameExecutableFilePath);
            }

            var isPointsScoringSystemOption1Applied  = _pointsSystemF119811990Update.IsCodeModified(gameExecutableFilePath);
            var isPointsScoringSystemOption1Required = domainModel.Configurations.PointsScoringSystemOption1;

            if (!isPointsScoringSystemOption1Applied && isPointsScoringSystemOption1Required)
            {
                ApplyIrreversibleCode(_pointsSystemF119811990Update, gameExecutableFilePath);
            }

            var isPointsScoringSystemOption2Applied  = _pointsSystemF120032009Update.IsCodeModified(gameExecutableFilePath);
            var isPointsScoringSystemOption2Required = domainModel.Configurations.PointsScoringSystemOption2;

            if (!isPointsScoringSystemOption2Applied && isPointsScoringSystemOption2Required)
            {
                ApplyIrreversibleCode(_pointsSystemF120032009Update, gameExecutableFilePath);
            }

            var isPointsScoringSystemOption3Applied  = _pointsSystemF1201020XxUpdate.IsCodeModified(gameExecutableFilePath);
            var isPointsScoringSystemOption3Required = domainModel.Configurations.PointsScoringSystemOption3;

            if (!isPointsScoringSystemOption3Applied && isPointsScoringSystemOption3Required)
            {
                ApplyIrreversibleCode(_pointsSystemF1201020XxUpdate, gameExecutableFilePath);
            }

            // Track Editor
            var isTrackEditorFixApplied  = _trackEditorFix.IsCodeModified(gameExecutableFilePath);
            var isTrackEditorFixRequired = domainModel.Configurations.EnableTrackEditor;

            if (isTrackEditorFixApplied != isTrackEditorFixRequired)
            {
                ApplyReversibleCode(_trackEditorFix, isTrackEditorFixRequired, gameExecutableFilePath);
            }
        }