public ZkooHostAppWithTutorialApplication()
            : base()
        {
            // TODO: Check the correct way to catch all exceptions and show it "We're sorry" dialog.  But the next way is still meaningless now, and sometimes this code can cause a problem that application cannot exit.
            //AppDomain.CurrentDomain.UnhandledException += (sender, e) => { ShutdownApplicationByException((Exception)e.ExceptionObject); };

            try
            {
                Egs.BindableResources.Current.CultureChanged += delegate
                {
                    ApplicationCommonSettings.HostApplicationName = Egs.EgsDeviceControlCore.Properties.Resources.CommonStrings_Zkoo;
                    Egs.ZkooTutorial.BindableResources.Current.ChangeCulture(Egs.EgsDeviceControlCore.Properties.Resources.Culture.Name);
                };

                Egs.BindableResources.Current.ChangeCulture(ApplicationCommonSettings.DefaultCultureInfoName);

                if (DuplicatedProcessStartBlocking.TryGetMutexOnTheBeginningOfApplicationConstructor() == false)
                {
                    var msg = string.Format(System.Globalization.CultureInfo.InvariantCulture, Egs.EgsDeviceControlCore.Properties.Resources.CommonStrings_Application0IsAlreadyRunning, ApplicationCommonSettings.HostApplicationName);
                    MessageBox.Show(msg, ApplicationCommonSettings.HostApplicationName);
                    if (Application.Current != null)
                    {
                        Application.Current.Shutdown();
                    }
                    return;
                }

                hostAppComponents = new EgsHostAppBaseComponents();
                hostAppComponents.InitializeOnceAtStartup();
                hostAppComponents.HasResetSettings += delegate
                {
                    // You can modify the application default settings here.
                    hostAppComponents.Device.Settings.FaceDetectionMethod.Value = Egs.PropertyTypes.FaceDetectionMethods.DefaultProcessOnEgsHostApplication;
                    hostAppComponents.IsToStartTutorialWhenHostApplicationStart = true;
                };
                if (SettingsSerialization.LoadSettingsJsonFile(hostAppComponents) == false)
                {
                    hostAppComponents.Reset();
                }

                hostAppComponents.CameraViewWindow.Closed += delegate { hostAppComponents.Dispose(); };

                hostAppComponents.Disposing += delegate
                {
                    // NOTE: Save settings before Dispose().  Target event is not Disposed but Disposing.
                    if (hostAppComponents.CanSaveSettingsJsonFileSafely)
                    {
                        SettingsSerialization.SaveSettingsJsonFile(hostAppComponents);
                    }

                    if (navigator != null)
                    {
                        // detach static event
                        Microsoft.Win32.SystemEvents.DisplaySettingsChanged -= SystemEvents_DisplaySettingsChanged;
                    }
                    // NOTE: IMPORTANT!
                    if (navigator != null)
                    {
                        navigator.Close(); navigator = null;
                    }

                    zkooTutorialModel = null;
                };

                base.Exit += delegate
                {
                    if (hostAppComponents != null)
                    {
                        hostAppComponents.Dispose(); hostAppComponents = null;
                    }
                    DuplicatedProcessStartBlocking.ReleaseMutex();
                };

                hostAppComponents.CheckIfDeviceFirmwareIsLatestOrNotAndExitApplicationIfFailed();
                // NOTE: If users exit the application by the button on Camera View while "Firmware Update" dialog, exception occurs.
                // MUSTDO: We will fix this.
                if (hostAppComponents.SettingsWindow == null)
                {
                    return;
                }


                // NOTE: Codes about "Tutorial" application.
                // TODO: Tutorial application should be independent from this host application, so I wrote it as an event handler.
                var hasZkooTutorialLaunched  = false;
                var zkooTutorialLaunchAction = new Action(() =>
                {
                    if (hasZkooTutorialLaunched == false)
                    {
                        zkooTutorialModel = new ZkooTutorialModel(hostAppComponents);
                        navigator         = new MainNavigationWindow();
                        // attach static event
                        Microsoft.Win32.SystemEvents.DisplaySettingsChanged += SystemEvents_DisplaySettingsChanged;
                        // NOTE: TODO: When exceptions occur in Initialize, we have to distinguish whether from Settings files or from source code.
                        zkooTutorialModel.TutorialAppHeaderMenu.InitializeOnceAtStartup(navigator, zkooTutorialModel);
                        zkooTutorialModel.InitializeOnceAtStartup(hostAppComponents);
                        navigator.InitializeOnceAtStartup(zkooTutorialModel);
                        hasZkooTutorialLaunched = true;
                    }
                    navigator.StartTutorial();
                });

                hostAppComponents.SettingsWindow.SettingsUserControl.TutorialAppSettingsGroupBoxVisibility = Visibility.Visible;
                hostAppComponents.StartTutorialCommand.PerformEventHandler += delegate
                {
                    zkooTutorialLaunchAction.Invoke();
                };

                hostAppComponents.IsStartingDeviceFirmwareUpdate += delegate { if (navigator != null)
                                                                               {
                                                                                   navigator.ExitTutorial();
                                                                               }
                };
                hostAppComponents.IsStartingHostApplicationUpdate += delegate { if (navigator != null)
                                                                                {
                                                                                    navigator.ExitTutorial();
                                                                                }
                };


                if (ApplicationCommonSettings.IsInternalRelease || ApplicationCommonSettings.IsDebuggingInternal)
                {
                    var exvisionInternalSettingsTabItem = new System.Windows.Controls.TabItem()
                    {
                        Header = "Exvision"
                    };
                    exvisionInternalSettingsTabItem.Content = new Egs.Views.ExvisionSettingsUserControl();
                    hostAppComponents.SettingsWindow.SettingsUserControl.SettingsTabControl.Items.Add(exvisionInternalSettingsTabItem);
                }


                if (hostAppComponents.IsToStartTutorialWhenHostApplicationStart)
                {
                    zkooTutorialLaunchAction.Invoke();
                }
            }
            catch (Exception ex)
            {
                ShutdownApplicationByException(ex);
            }
        }
        public ZkooHostAppApplication()
            : base()
        {
            hostAppComponents = null;

            try
            {
                Egs.BindableResources.Current.CultureChanged += delegate
                {
                    ApplicationCommonSettings.HostApplicationName = Egs.EgsDeviceControlCore.Properties.Resources.CommonStrings_GestureCamera;
                };

                Egs.BindableResources.Current.ChangeCulture(ApplicationCommonSettings.DefaultCultureInfoName);

                if (DuplicatedProcessStartBlocking.TryGetMutexOnTheBeginningOfApplicationConstructor() == false)
                {
                    var msg = string.Format(System.Globalization.CultureInfo.InvariantCulture, Egs.EgsDeviceControlCore.Properties.Resources.CommonStrings_Application0IsAlreadyRunning, ApplicationCommonSettings.HostApplicationName);
                    MessageBox.Show(msg, ApplicationCommonSettings.HostApplicationName);
                    if (Application.Current != null)
                    {
                        Application.Current.Shutdown();
                    }
                    return;
                }

                hostAppComponents = new EgsHostAppBaseComponents();
                hostAppComponents.InitializeOnceAtStartup();
                hostAppComponents.HasResetSettings += delegate
                {
                    // You can modify the application default settings here.
                    hostAppComponents.Device.Settings.CursorSpeedAndPrecisionMode.Value = Egs.PropertyTypes.CursorSpeedAndPrecisionModes.Standard;
                    hostAppComponents.Device.Settings.FaceDetectionMethod.Value         = Egs.PropertyTypes.FaceDetectionMethods.DefaultProcessOnEgsHostApplication;
                };
                if (SettingsSerialization.LoadSettingsJsonFile(hostAppComponents) == false)
                {
                    hostAppComponents.Reset();
                }

                hostAppComponents.CameraViewWindow.Closed += delegate { hostAppComponents.Dispose(); };

                hostAppComponents.Disposing += delegate
                {
                    // NOTE: Save settings before Dispose().  Target event is not Disposed but Disposing.
                    if (hostAppComponents.CanSaveSettingsJsonFileSafely)
                    {
                        SettingsSerialization.SaveSettingsJsonFile(hostAppComponents);
                    }
                };

                base.Exit += delegate
                {
                    if (hostAppComponents != null)
                    {
                        hostAppComponents.Dispose(); hostAppComponents = null;
                    }
                    DuplicatedProcessStartBlocking.ReleaseMutex();
                };

                hostAppComponents.CheckIfDeviceFirmwareIsLatestOrNotAndExitApplicationIfFailed();
                // NOTE: If users exit the application by the button on Camera View while "Firmware Update" dialog, exception occurs.
                // MUSTDO: We will fix this.
                if (hostAppComponents.SettingsWindow == null)
                {
                    return;
                }


                // TODO: The tutorial program will be separated into an independent application.
                hostAppComponents.SettingsWindow.SettingsUserControl.TutorialAppSettingsGroupBoxVisibility = Visibility.Collapsed;
                hostAppComponents.StartTutorialCommand.CanPerform = false;
            }
            catch (Exception ex)
            {
                ShutdownApplicationByException(ex);
            }
        }