public OptionsMenuGameState(GameMain game)
            : base()
        {
            this.Game = game;

            this._Gui        = new GuiManager(this.Game.Services);
            this._Gui.Screen = new Screen(this.Game.GraphicsDevice.Viewport.Width, this.Game.GraphicsDevice.Viewport.Height);
            this._Gui.Screen.Desktop.Bounds = new UniRectangle(
                new UniScalar(0.1f, 0.0f), new UniScalar(0.1f, 0.0f),
                new UniScalar(0.8f, 0.0f), new UniScalar(0.8f, 0.0f));
            this._Dialog = new OptionsMenuDialog(this.Game);
            this._Dialog.Load();
            this._Dialog.Closed += new EventHandler(this.dialog_Closed);
            this._Gui.Screen.Desktop.Children.Add(this._Dialog);

            this.Game.Components.Add(this._Gui);
        }
        public LoadingGameState(GameMain game, CancellationToken cancelMarker)
            : base()
        {
            this.Game = game;
            var taskMgr = this.Game.Services.GetService <TaskManager>();

            this._SpriteBatch = new SpriteBatch(this.Game.GraphicsDevice);

            // Display help text at the start.
            this._HelpText             = this.Game.GetHelpText();
            this._HelpText.SpriteBatch = this._SpriteBatch;

            // Show an animation while loading.
            this._LoaderAnimation             = this.GetLoadingAnimation();
            this._LoaderAnimation.SpriteBatch = this._SpriteBatch;

            var loadTimers = new LoadTimers();

            // Create loader thread.
            // This is executed in the first call to Update().
            this._Loader = new Task(() =>
            {
                var loadStopwatch = System.Diagnostics.Stopwatch.StartNew();

                if (cancelMarker.IsCancellationRequested)
                {
                    cancelMarker.ThrowIfCancellationRequested();
                }

                // Create services.
                this.Game.Services.AddService(typeof(IConfigurationService), new ConfigurationManager(this.Game));
                this.Game.Services.AddService(typeof(IBabyPackageProvider), new XmlFolderBabyPackage(this.Game));
                this.Game.Services.AddService(typeof(ISoundService), new SoundServiceContainer(new SoundService(this.Game)));
                this.Game.Services.AddService(typeof(IApplicationUpdater), new ApplicationUpdater(this.Game));

                if (cancelMarker.IsCancellationRequested)
                {
                    cancelMarker.ThrowIfCancellationRequested();
                }

                // Load content based on those services.
                var startConfigLoad = loadStopwatch.Elapsed;
                var configMgr       = this.Game.Services.GetService <IConfigurationService>();
                bool configExists   = configMgr.Exists;
                configMgr.Load();
                if (!configExists)       // Ensure the configuration file is saved.
                {
                    configMgr.Save(configMgr.Current);
                }
                loadTimers.ConfigLoadTime = loadStopwatch.Elapsed.Subtract(startConfigLoad);

                if (cancelMarker.IsCancellationRequested)
                {
                    cancelMarker.ThrowIfCancellationRequested();
                }

                // Load up the baby package.
                var startBabyPackageLoad = loadStopwatch.Elapsed;
                var babyPackpageProvider = this.Game.Services.GetService(typeof(IBabyPackageProvider)) as IBabyPackageProvider;
                babyPackpageProvider.Load(configMgr.Current.PathToBabyPackage, cancelMarker);
                loadTimers.BabyPackageLoadTime = loadStopwatch.Elapsed;

                if (cancelMarker.IsCancellationRequested)
                {
                    cancelMarker.ThrowIfCancellationRequested();
                }

                // Loading can generate lots of garbage, so do a collection while the loading animation is still on screen.
                GC.Collect();

                loadStopwatch.Stop();
                loadTimers.TotalLoadTime = loadStopwatch.Elapsed;
            });

            var loaderComplete = this._Loader.ContinueWith((t) =>
            {
                // When loading is finished, null it and remove the loading animation.
                this._Loader = null;

                // Notify that we've finished loading.
                if (this.LoadComplete != null)
                {
                    this._HelpText.SpriteBatch = null;
                    this.LoadComplete(this, new LoadCompleteEventArgs(this._HelpText, loadTimers));
                }

                // Load up a few assemblies from disk to keep the options screen responsive.
                var optionsLoader = new Task(() =>
                {
                    var optionsScreen = new OptionsMenuDialog(this.Game);
                    var guiManager    = new Nuclex.UserInterface.GuiManager(this.Game.Services);
                    this.Game.Services.RemoveService(typeof(Nuclex.UserInterface.IGuiService));
                    var fileBrowseDialog = new System.Windows.Forms.OpenFileDialog();
                });
                taskMgr.RegisterTask(optionsLoader);
                optionsLoader.Start();
            }, CancellationToken.None, TaskContinuationOptions.NotOnFaulted, TaskScheduler.FromCurrentSynchronizationContext());

            var updaterTask = loaderComplete.ContinueWith(t =>
            {
                // Spin up the updater (which delays a bit before running).
                var updater = this.Game.Services.GetService <IApplicationUpdater>();
                if (updater.SupportsUpdates)
                {
                    Thread.Sleep(TimeSpan.FromSeconds(30));
                    updater.DoCheckAndUpdate();
                }
            }, TaskContinuationOptions.NotOnFaulted);

            // Register all the tasks with the game to handle exceptions.
            taskMgr.RegisterTask(this._Loader);
            taskMgr.RegisterTask(loaderComplete);
            taskMgr.RegisterTask(updaterTask);
        }