internal SwitchModeViewModel(PhoneNotifierViewModel PhoneNotifier, PhoneInterfaces?TargetMode, ModeSwitchProgressHandler ModeSwitchProgress, ModeSwitchErrorHandler ModeSwitchError, ModeSwitchSuccessHandler ModeSwitchSuccess, SetWorkingStatus SetWorkingStatus = null, UpdateWorkingStatus UpdateWorkingStatus = null)
            : base()
        {
            if ((PhoneNotifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) && (TargetMode == PhoneInterfaces.Lumia_Flash))
            {
                PhoneInfo Info = ((NokiaFlashModel)PhoneNotifier.CurrentModel).ReadPhoneInfo(false);
                if (Info.BootManagerProtocolVersionMajor >= 2)
                {
                    try
                    {
                        // The implementation of SwitchToFlashAppContext() is improved
                        // SwitchToFlashAppContext() should only be used with BootMgr v2
                        // For switching from BootMgr to FlashApp, it will use NOKS
                        // That will switch to a charging state, whereas a normal context switch will not start charging
                        // The implementation of NOKS in BootMgr mode has changed in BootMgr v2
                        // It does not disconnect / reconnect anymore and the apptype is changed immediately
                        // NOKS still doesnt return a status
                        // BootMgr v1 uses normal NOKS and waits for arrival of FlashApp
                        ((NokiaFlashModel)PhoneNotifier.CurrentModel).SwitchToFlashAppContext();

                        // But this was called as a real switch, so we will raise an arrival event.
                        PhoneNotifier.CurrentInterface = PhoneInterfaces.Lumia_Flash;
                        PhoneNotifier.NotifyArrival();
                    }
                    catch { }
                }
            }

            if (PhoneNotifier.CurrentInterface == TargetMode)
            {
                ModeSwitchSuccess(PhoneNotifier.CurrentModel, (PhoneInterfaces)PhoneNotifier.CurrentInterface);
            }
            else
            {
                this.PhoneNotifier = PhoneNotifier;
                this.CurrentModel  = (NokiaPhoneModel)PhoneNotifier.CurrentModel;
                this.CurrentMode   = PhoneNotifier.CurrentInterface;
                this.TargetMode    = TargetMode;
                if (ModeSwitchProgress != null)
                {
                    this.ModeSwitchProgress += ModeSwitchProgress;
                }
                if (ModeSwitchError != null)
                {
                    this.ModeSwitchError += ModeSwitchError;
                }
                if (ModeSwitchSuccess != null)
                {
                    this.ModeSwitchSuccess += ModeSwitchSuccess;
                }
                if (SetWorkingStatus != null)
                {
                    this.SetWorkingStatus = SetWorkingStatus;
                }
                if (UpdateWorkingStatus != null)
                {
                    this.UpdateWorkingStatus = UpdateWorkingStatus;
                }

                if (this.CurrentMode == null)
                {
                    LogFile.Log("Waiting for phone to connect...", LogType.FileAndConsole);
                    PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
                }
                else
                {
                    // Make sure this ViewModel has its View loaded before we continue,
                    // or else loading of Views can get mixed up.
                    if (SynchronizationContext.Current == null)
                    {
                        StartSwitch();
                    }
                    else
                    {
                        SynchronizationContext.Current.Post((s) =>
                        {
                            ((SwitchModeViewModel)s).StartSwitch();
                        }, this);
                    }
                }
            }
        }
        internal async static Task <IDisposable> SwitchToWithProgress(PhoneNotifierViewModel Notifier, PhoneInterfaces?TargetMode, ModeSwitchProgressHandler ModeSwitchProgress, string RequestedVolumeForMassStorage = "MainOS")
        {
            if (Notifier.CurrentInterface == TargetMode)
            {
                return(Notifier.CurrentModel);
            }

            IDisposable Result            = null;
            string      LocalErrorMessage = null;

            AsyncAutoResetEvent Event = new AsyncAutoResetEvent(false);

            SwitchModeViewModel Switch = new SwitchModeViewModel(
                Notifier,
                TargetMode,
                ModeSwitchProgress,
                (string ErrorMessage) =>
            {
                LocalErrorMessage = ErrorMessage;
                Event.Set();
            },
                (IDisposable NewModel, PhoneInterfaces NewInterface) =>
            {
                Result = NewModel;
                Event.Set();
            }
                );

            await Event.WaitAsync(Timeout.InfiniteTimeSpan);

            if (LocalErrorMessage != null)
            {
                throw new WPinternalsException(LocalErrorMessage);
            }

            return(Result);
        }