Manages the programme's updaters.
		/// <summary>
		/// This initializes the services required to run the client.
		/// </summary>
		/// <param name="p_gmdGameMode">The game mode for which mods are being managed.</param>
		/// <param name="p_mrpModRepository">The mod repository to use to retrieve mods and mod metadata.</param>
		/// <param name="p_nfuFileUtility">The file utility class.</param>
		/// <param name="p_scxUIContext">The <see cref="SynchronizationContext"/> to use to marshall UI interactions to the UI thread.</param>
		/// <param name="p_vwmErrorMessage">The error message if the UAC check failed.</param>
		/// <returns>A <see cref="ServiceManager"/> containing the initialized services, or <c>null</c> if the
		/// services didn't initialize properly.</returns>
		protected ServiceManager InitializeServices(IGameMode p_gmdGameMode, IModRepository p_mrpModRepository, NexusFileUtil p_nfuFileUtility, SynchronizationContext p_scxUIContext, out ViewMessage p_vwmErrorMessage)
		{
			IModCacheManager mcmModCacheManager = new NexusModCacheManager(p_gmdGameMode.GameModeEnvironmentInfo.ModCacheDirectory, p_gmdGameMode.GameModeEnvironmentInfo.ModDirectory, p_nfuFileUtility);

			Trace.TraceInformation("Registering supported Script Types...");
			Trace.Indent();
			IScriptTypeRegistry stgScriptTypeRegistry = ScriptTypeRegistry.DiscoverScriptTypes(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "ScriptTypes"), p_gmdGameMode);
			if (stgScriptTypeRegistry.Types.Count == 0)
			{
				p_vwmErrorMessage = new ViewMessage("No script types were found.", null, "No Script Types", MessageBoxIcon.Error);
				return null;
			}
			Trace.TraceInformation("Found {0} script types.", stgScriptTypeRegistry.Types.Count);
			Trace.Unindent();

			Trace.TraceInformation("Registering supported mod formats...");
			Trace.Indent();
			IModFormatRegistry mfrModFormatRegistry = ModFormatRegistry.DiscoverFormats(mcmModCacheManager, stgScriptTypeRegistry, Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "ModFormats"));
			if (mfrModFormatRegistry.Formats.Count == 0)
			{
				p_vwmErrorMessage = new ViewMessage("No mod formats were found.", null, "No Mod Formats", MessageBoxIcon.Error);
				return null;
			}
			Trace.TraceInformation("Found {0} formats.", mfrModFormatRegistry.Formats.Count);
			Trace.Unindent();

			Trace.TraceInformation("Finding managed mods...");
			Trace.Indent();

			ModRegistry mrgModRegistry = null;
			try
			{
				mrgModRegistry = ModRegistry.DiscoverManagedMods(mfrModFormatRegistry, mcmModCacheManager, p_gmdGameMode.GameModeEnvironmentInfo.ModDirectory, EnvironmentInfo.Settings.ScanSubfoldersForMods, p_gmdGameMode, p_gmdGameMode.GameModeEnvironmentInfo.ModCacheDirectory, p_gmdGameMode.GameModeEnvironmentInfo.ModDownloadCacheDirectory, p_gmdGameMode.GameModeEnvironmentInfo.ModReadMeDirectory, p_gmdGameMode.GameModeEnvironmentInfo.CategoryDirectory);
			}
			catch (UnauthorizedAccessException ex)
			{
				p_vwmErrorMessage = new ViewMessage(String.Format("An error occured while retrieving managed mods: \n\n{0}", ex.Message), null, "Install Log", MessageBoxIcon.Error);
				return null;
			}

			Trace.TraceInformation("Found {0} managed mods.", mrgModRegistry.RegisteredMods.Count);
			Trace.Unindent();

			Trace.TraceInformation("Initializing Install Log...");
			Trace.Indent();
			Trace.TraceInformation("Checking if upgrade is required...");
			InstallLogUpgrader iluUgrader = new InstallLogUpgrader();

			string strLogPath = string.Empty;

			try
			{
				strLogPath = Path.Combine(p_gmdGameMode.GameModeEnvironmentInfo.InstallInfoDirectory, "InstallLog.xml");
			}
			catch (ArgumentNullException)
			{
				p_vwmErrorMessage = new ViewMessage("Unable to retrieve critical paths from the config file." + Environment.NewLine + "Select this game again to fix the folders setup.", null, "Config error", MessageBoxIcon.Warning);
				return null;
			}

			if (!InstallLog.IsLogValid(strLogPath))
				InstallLog.Restore(strLogPath);
			if (iluUgrader.NeedsUpgrade(strLogPath))
			{
				if (!iluUgrader.CanUpgrade(strLogPath))
				{
					p_vwmErrorMessage = new ViewMessage(String.Format("{0} does not support version {1} of the Install Log.", EnvironmentInfo.Settings.ModManagerName, InstallLog.ReadVersion(strLogPath)), null, "Install Log", MessageBoxIcon.Error);
					return null;
				}
				IBackgroundTask tskUpgrader = iluUgrader.UpgradeInstallLog(strLogPath, p_gmdGameMode.GameModeEnvironmentInfo.ModDirectory, mrgModRegistry);
				m_areTaskWait.Reset();
				tskUpgrader.TaskEnded += new EventHandler<TaskEndedEventArgs>(Task_TaskEnded);
				OnTaskStarted(tskUpgrader);
				if (tskUpgrader.IsActive)
					m_areTaskWait.WaitOne();
				tskUpgrader.TaskEnded -= new EventHandler<TaskEndedEventArgs>(Task_TaskEnded);
				if (tskUpgrader.Status != TaskStatus.Complete)
				{
					string strDetails = (string)(tskUpgrader.ReturnValue ?? null);
					p_vwmErrorMessage = new ViewMessage("Install Log was not upgraded.", strDetails, "Install Log", MessageBoxIcon.Error);
					return null;
				}
			}
			IInstallLog ilgInstallLog = InstallLog.Initialize(mrgModRegistry, p_gmdGameMode.GameModeEnvironmentInfo.ModDirectory, strLogPath);
			Trace.Unindent();

			Trace.TraceInformation("Initializing Plugin Management Services...");
			Trace.Indent();
			PluginRegistry prgPluginRegistry = null;
			IPluginOrderLog polPluginOrderLog = null;
			ActivePluginLog aplPluginLog = null;
			IPluginManager pmgPluginManager = null;
			if (!p_gmdGameMode.UsesPlugins)
				Trace.TraceInformation("Not required.");
			else
			{
				Trace.TraceInformation("Initializing Plugin Registry...");
				Trace.Indent();
				prgPluginRegistry = PluginRegistry.DiscoverManagedPlugins(p_gmdGameMode.GetPluginFactory(), p_gmdGameMode.GetPluginDiscoverer());
				Trace.TraceInformation("Found {0} managed plugins.", prgPluginRegistry.RegisteredPlugins.Count);
				Trace.Unindent();

				Trace.TraceInformation("Initializing Plugin Order Log...");
				Trace.Indent();
				polPluginOrderLog = PluginOrderLog.Initialize(prgPluginRegistry, p_gmdGameMode.GetPluginOrderLogSerializer(), p_gmdGameMode.GetPluginOrderValidator());
				Trace.Unindent();

				Trace.TraceInformation("Initializing Active Plugin Log...");
				Trace.Indent();
				aplPluginLog = ActivePluginLog.Initialize(prgPluginRegistry, p_gmdGameMode.GetActivePluginLogSerializer(polPluginOrderLog));
				Trace.Unindent();

				Trace.TraceInformation("Initializing Plugin Manager...");
				Trace.Indent();
				pmgPluginManager = PluginManager.Initialize(p_gmdGameMode, prgPluginRegistry, aplPluginLog, polPluginOrderLog, p_gmdGameMode.GetPluginOrderValidator());
				Trace.Unindent();
			}
			Trace.Unindent();

			Trace.TraceInformation("Initializing Activity Monitor...");
			Trace.Indent();
			DownloadMonitor dmtMonitor = new DownloadMonitor();
			Trace.Unindent();

            Trace.TraceInformation("Initializing Activate Mods Monitor...");
			Trace.Indent();
			ActivateModsMonitor ammMonitor = new ActivateModsMonitor();
			Trace.Unindent();

			Trace.TraceInformation("Initializing Mod Manager...");
			Trace.Indent();
            ModManager mmgModManager = ModManager.Initialize(p_gmdGameMode, EnvironmentInfo, p_mrpModRepository, dmtMonitor, ammMonitor, mfrModFormatRegistry, mrgModRegistry, p_nfuFileUtility, p_scxUIContext, ilgInstallLog, pmgPluginManager);
			Trace.Unindent();

			Trace.TraceInformation("Initializing Update Manager...");
			Trace.Indent();
			UpdateManager umgUpdateManager = new UpdateManager(p_gmdGameMode, EnvironmentInfo);
			Trace.Unindent();

			p_vwmErrorMessage = null;
            return new ServiceManager(ilgInstallLog, aplPluginLog, polPluginOrderLog, p_mrpModRepository, mmgModManager, pmgPluginManager, dmtMonitor, ammMonitor, umgUpdateManager);
		}
		/// <summary>
		/// A simple constructor that initializes the object with the given dependencies.
		/// </summary>
		/// <param name="p_eifEnvironmentInfo">The application's envrionment info.</param>
		/// <param name="p_gmrInstalledGames">The registry of insalled games.</param>
		/// <param name="p_gmdGameMode">The game mode currently being managed.</param>
		/// <param name="p_mrpModRepository">The repository we are logging in to.</param>
		/// <param name="p_dmtMonitor">The download monitor to use to track task progress.</param>
		/// <param name="p_umgUpdateManager">The update manager to use to perform updates.</param>
		/// <param name="p_mmgModManager">The <see cref="ModManager"/> to use to manage mods.</param>
		/// <param name="p_pmgPluginManager">The <see cref="PluginManager"/> to use to manage plugins.</param>
        public MainFormVM(IEnvironmentInfo p_eifEnvironmentInfo, GameModeRegistry p_gmrInstalledGames, IGameMode p_gmdGameMode, IModRepository p_mrpModRepository, DownloadMonitor p_dmtMonitor, ActivateModsMonitor p_ammMonitor, UpdateManager p_umgUpdateManager, ModManager p_mmgModManager, IPluginManager p_pmgPluginManager)
		{
			EnvironmentInfo = p_eifEnvironmentInfo;
			GameMode = p_gmdGameMode;
			GameMode.GameLauncher.GameLaunching += new CancelEventHandler(GameLauncher_GameLaunching);
			ModManager = p_mmgModManager;
			ModRepository = p_mrpModRepository;
			UpdateManager = p_umgUpdateManager;
			ModManagerVM = new ModManagerVM(p_mmgModManager, p_eifEnvironmentInfo.Settings, p_gmdGameMode.ModeTheme);
			DownloadMonitorVM = new DownloadMonitorVM(p_dmtMonitor, p_eifEnvironmentInfo.Settings, p_mmgModManager, p_mrpModRepository);
			ModActivationMonitor = p_ammMonitor;
			ActivateModsMonitorVM = new ActivateModsMonitorVM(p_ammMonitor, p_eifEnvironmentInfo.Settings, p_mmgModManager);
			if (GameMode.UsesPlugins)
				PluginManagerVM = new PluginManagerVM(p_pmgPluginManager, p_eifEnvironmentInfo.Settings, p_gmdGameMode, p_ammMonitor);

			HelpInfo = new HelpInformation(p_eifEnvironmentInfo);

			GeneralSettingsGroup gsgGeneralSettings = new GeneralSettingsGroup(p_eifEnvironmentInfo);
			foreach (IModFormat mftFormat in p_mmgModManager.ModFormats)
				gsgGeneralSettings.AddFileAssociation(mftFormat.Extension, mftFormat.Name);

			ModOptionsSettingsGroup mosModOptions = new ModOptionsSettingsGroup(p_eifEnvironmentInfo);

			List<ISettingsGroupView> lstSettingGroups = new List<ISettingsGroupView>();
			lstSettingGroups.Add(new GeneralSettingsPage(gsgGeneralSettings));
			lstSettingGroups.Add(new ModOptionsPage(mosModOptions));
			DownloadSettingsGroup dsgDownloadSettings = new DownloadSettingsGroup(p_eifEnvironmentInfo, ModRepository);
			lstSettingGroups.Add(new DownloadSettingsPage(dsgDownloadSettings));

			if (p_gmdGameMode.SettingsGroupViews != null)
				lstSettingGroups.AddRange(p_gmdGameMode.SettingsGroupViews);

			SettingsFormVM = new SettingsFormVM(p_gmdGameMode, p_eifEnvironmentInfo, lstSettingGroups);

			UpdateCommand = new Command("Update", String.Format("Update {0}", EnvironmentInfo.Settings.ModManagerName), UpdateProgramme);
			LogoutCommand = new Command("Logout", "Logout", Logout);

			List<Command> lstChangeGameModeCommands = new List<Command>();
			List<IGameModeDescriptor> lstSortedModes = new List<IGameModeDescriptor>(p_gmrInstalledGames.RegisteredGameModes);
			lstSortedModes.Sort((x, y) => x.Name.CompareTo(y.Name));
			foreach (IGameModeDescriptor gmdInstalledGame in lstSortedModes)
			{
				string strId = gmdInstalledGame.ModeId;
				string strName = gmdInstalledGame.Name;
				string strDescription = String.Format("Change game to {0}", gmdInstalledGame.Name);
				Image imgCommandIcon = new Icon(gmdInstalledGame.ModeTheme.Icon, 32, 32).ToBitmap();
				lstChangeGameModeCommands.Add(new Command(strId, strName, strDescription, imgCommandIcon, () => ChangeGameMode(strId), true));
			}
			lstChangeGameModeCommands.Add(new Command("Change Default Game...", "Change Default Game", () => ChangeGameMode(CHANGE_DEFAULT_GAME_MODE)));
			lstChangeGameModeCommands.Add(new Command("Rescan Installed Games...", "Rescan Installed Games", () => ChangeGameMode(RESCAN_INSTALLED_GAMES)));
			ChangeGameModeCommands = lstChangeGameModeCommands;
		}
		/// <summary>
		/// A simpell constructor that initializes the object with the given services.
		/// </summary>
		/// <param name="p_ilgModInstallLog">The install log that tracks mod install info for the current game mode.</param>
		/// <param name="p_aplActivePluginLog">The <see cref="ActivePluginLog"/> tracking plugin activations for the current game mode.</param>
		/// <param name="p_polPluginOrderLog">The <see cref="IPluginOrderLog"/> tracking plugin order for the current game mode.</param>
		/// <param name="p_mrpModRepository">The repository we are logging in to.</param>
		/// <param name="p_mmgModManager">The mod manager to use to manage mods.</param>
		/// <param name="p_pmgPluginManager">The manager to use to manage plugins.</param>
		/// <param name="p_amtMonitor">The download monitor to use to manage the monitored activities.</param>
		/// <param name="p_umgUpdateManager">The update manager to use to perform updates.</param>
        public ServiceManager(IInstallLog p_ilgModInstallLog, ActivePluginLog p_aplActivePluginLog, IPluginOrderLog p_polPluginOrderLog, IModRepository p_mrpModRepository, ModManager p_mmgModManager, IPluginManager p_pmgPluginManager, DownloadMonitor p_amtMonitor, ActivateModsMonitor p_ammMonitor, UpdateManager p_umgUpdateManager)
		{
			ModInstallLog = p_ilgModInstallLog;
			ActivePluginLog = p_aplActivePluginLog;
			PluginOrderLog = p_polPluginOrderLog;
			ModRepository = p_mrpModRepository;
			ModManager = p_mmgModManager;
			PluginManager = p_pmgPluginManager;
			DownloadMonitor = p_amtMonitor;
			UpdateManager = p_umgUpdateManager;
            ActivateModsMonitor = p_ammMonitor;
		}