/// <summary>
        /// Unloads camera device, if needed.
        /// </summary>
        /// <returns>Awaitable task.</returns>
        public async Task UnloadCameraAsync()
        {
            if (this.camera == null || this.State == MainPageViewModelState.Unloaded)
            {
                return;
            }

            this.State        = MainPageViewModelState.Unloaded;
            this.PreviewBrush = null;

            this.continuousAutoFocusEnabled = false;

            this.camera.FocusChanged   -= this.CameraOnFocusChanged;
            this.camera.PhotoCaptured  -= this.CameraOnPhotoCaptured;
            this.camera.CaptureStopped -= this.CameraOnCaptureStopped;

            await this.camera.UnloadCameraAsync();

            this.camera = null;

            EventHandler handler = this.CameraUnloaded;

            if (handler != null)
            {
                handler.Invoke(this, EventArgs.Empty);
            }
        }
        /// <summary>
        /// Loads camera device, if needed.
        /// </summary>
        /// <param name="areaSize">The size of the area available for the video preview.</param>
        /// <returns>Awaitable task.</returns>
        public async Task EnsureCameraLoadedAsync(Size areaSize)
        {
            if (this.camera != null)
            {
                // Make sure the the correct camera is loaded.
                if (this.camera.CameraType == this.CameraType && this.State != MainPageViewModelState.Unloaded)
                {
                    Tracing.Trace("MainPageViewModel: {0} camera is already loaded.", this.CameraType);
                    return;
                }

                await this.UnloadCameraAsync();
            }

            this.State = MainPageViewModelState.Loading;

            this.camera = await this.cameraProvider.GetCameraAsync(this.CameraType);

            this.cameraSettings     = this.settingsProvider.GetCameraSettings(this.CameraType);
            this.camera.Orientation = this.orientation;
            this.previewAreaSize    = areaSize;

            await this.camera.LoadCameraAsync();

            await this.StartPreviewAsync(this.previewAreaSize);

            // Allow camera to automatically focus without user requests, if supported.
            await this.TryToEnableContinuousAutoFocusAsync();

            this.camera.FocusChanged   += this.CameraOnFocusChanged;
            this.camera.PhotoCaptured  += this.CameraOnPhotoCaptured;
            this.camera.CaptureStopped += this.CameraOnCaptureStopped;

            this.PreviewSize    = this.camera.PreviewSize;
            this.PreviewBrush   = this.camera.PreviewBrush;
            this.FlashSupported = this.camera.FlashSupported;

            await this.UpdatePhotoCaptureAsync();

            this.State = MainPageViewModelState.Loaded;

            EventHandler handler = this.CameraLoaded;

            if (handler != null)
            {
                handler.Invoke(this, EventArgs.Empty);
            }
        }
        /// <summary>
        /// Unloads camera device, if needed.
        /// </summary>
        /// <returns>Awaitable task.</returns>
        public async Task UnloadCameraAsync()
        {
            if (this.camera == null || this.State == MainPageViewModelState.Unloaded)
            {
                return;
            }

            this.State        = MainPageViewModelState.Unloaded;
            this.PreviewBrush = null;

            this.continuousAutoFocusEnabled = false;

            this.camera.FocusChanged   -= this.CameraOnFocusChanged;
            this.camera.PhotoCaptured  -= this.CameraOnPhotoCaptured;
            this.camera.CaptureStopped -= this.CameraOnCaptureStopped;

            await this.camera.UnloadCameraAsync();
            this.camera = null;

            EventHandler handler = this.CameraUnloaded;
            if (handler != null)
            {
                handler.Invoke(this, EventArgs.Empty);
            }
        }
        /// <summary>
        /// Loads camera device, if needed.
        /// </summary>
        /// <param name="areaSize">The size of the area available for the video preview.</param>
        /// <returns>Awaitable task.</returns>
        public async Task EnsureCameraLoadedAsync(Size areaSize)
        {
            if (this.camera != null)
            {
                // Make sure the the correct camera is loaded.
                if (this.camera.CameraType == this.CameraType && this.State != MainPageViewModelState.Unloaded)
                {
                    Tracing.Trace("MainPageViewModel: {0} camera is already loaded.", this.CameraType);
                    return;
                }

                await this.UnloadCameraAsync();
            }

            this.State = MainPageViewModelState.Loading;

            this.camera             = await this.cameraProvider.GetCameraAsync(this.CameraType);
            this.cameraSettings     = this.settingsProvider.GetCameraSettings(this.CameraType);
            this.camera.Orientation = this.orientation;
            this.previewAreaSize    = areaSize;

            await this.camera.LoadCameraAsync();
            await this.StartPreviewAsync(this.previewAreaSize);

            // Allow camera to automatically focus without user requests, if supported.
            await this.TryToEnableContinuousAutoFocusAsync();

            this.camera.FocusChanged   += this.CameraOnFocusChanged;
            this.camera.PhotoCaptured  += this.CameraOnPhotoCaptured;
            this.camera.CaptureStopped += this.CameraOnCaptureStopped;

            this.PreviewSize    = this.camera.PreviewSize;
            this.PreviewBrush   = this.camera.PreviewBrush;
            this.FlashSupported = this.camera.FlashSupported;

            await this.UpdatePhotoCaptureAsync();

            this.State = MainPageViewModelState.Loaded;

            EventHandler handler = this.CameraLoaded;
            if (handler != null)
            {
                handler.Invoke(this, EventArgs.Empty);
            }
        }