public async Task <TivoConnection> GetConnectionAsync()
        {
            if (this.connection == null)
            {
                var localConnection = new TivoConnection();

                var serviceProvider = TivoServiceProvider.VirginMediaUK;

                try
                {
                    if (this.IsAwayModeEnabled)
                    {
                        await localConnection.ConnectAway(TivoUsername, TivoPassword, serviceProvider, TivoCertificateStore.Instance);
                    }
                    else
                    {
                        await localConnection.Connect(TivoIPAddress, TivoMak, serviceProvider, TivoCertificateStore.Instance);
                    }

                    this.connection = localConnection;

                    NotifyOfPropertyChange(() => IsConnected);
                }
                catch (Exception)
                {
                    localConnection.Dispose();
                    throw;
                }
            }

            return(this.connection);
        }
        private async Task <TivoConnection> ConnectAsync(bool forceAwayMode)
        {
            if (!this.SettingsAppearValid ||
                !this.IsConnectionEnabled)
            {
                return(null);
            }

            using (this.progressService.Show())
            {
                this.isConnected = false;
                this.isAwayMode  = false;

                var localConnection = new TivoConnection();

                // TODO: detect this based on the Tivo mDNS data
                var service = TivoServiceProvider.VirginMediaUK;

                if (!forceAwayMode)
                {
                    var lanSettings = ConnectionSettings.KnownTivos
                                      .FirstOrDefault(x => x.TSN.Equals(ConnectionSettings.SelectedTivoTsn, StringComparison.Ordinal));

                    if (lanSettings != null &&
                        ConnectionSettings.LanSettingsAppearValid(lanSettings.LastIpAddress, lanSettings.MediaAccessKey) &&
                        lanSettings.NetworkName == this.ConnectedNetworkName)
                    {
                        try
                        {
                            await localConnection.Connect(lanSettings.LastIpAddress.ToString(), lanSettings.MediaAccessKey, service, TivoCertificateStore.Instance);

                            this.isConnected = true;
                            this.isAwayMode  = false;

                            Execute.BeginOnUIThread(() =>
                            {
                                var toast = new ToastPrompt()
                                {
                                    Title   = "Connected",
                                    Message = "Home Mode",
                                    MillisecondsUntilHidden = 600,
                                };

                                toast.Show();
                            });

                            this.analyticsService.ConnectedHomeMode();
                        }
                        catch (Exception ex)
                        {
                            this.Error = ex.Message;
                        }
                    }
                }

                if (!this.isConnected)
                {
                    try
                    {
                        await localConnection.ConnectAway(
                            ConnectionSettings.AwayModeUsername,
                            ConnectionSettings.AwayModePassword,
                            service,
                            TivoCertificateStore.Instance);

                        this.isConnected = true;
                        this.isAwayMode  = true;

                        Execute.BeginOnUIThread(() =>
                        {
                            var toast = new ToastPrompt()
                            {
                                Title   = "Connected",
                                Message = "Away Mode",
                                MillisecondsUntilHidden = 600,
                            };

                            toast.Show();
                        });

                        this.analyticsService.ConnectedAwayMode();
                    }
                    catch (Exception ex)
                    {
                        this.Error = ex.Message;
                    }
                }

                NotifyOfPropertyChange(() => IsConnected);
                NotifyOfPropertyChange(() => IsAwayMode);

                if (!this.isConnected)
                {
                    localConnection.Dispose();
                    localConnection = null;
                }

                return(localConnection);
            }
        }
        public async void TestLANConnection()
        {
            var connection = new TivoConnection();
            // TODO: Detect this
            var serviceProvider = TivoServiceProvider.VirginMediaUK;

            try
            {
                using (ShowProgress())
                {
                    await connection.Connect(this.LanSettings.LastIpAddress.ToString(), this.LanSettings.MediaAccessKey, serviceProvider, TivoCertificateStore.Instance);

                    if (!this.LanSettings.TSN.Equals(connection.ConnectedTsn, StringComparison.Ordinal))
                    {
                        this.LanSettings.TSN = connection.ConnectedTsn;
                    }

                    var knownTivosByTsn = ConnectionSettings.KnownTivos.ToDictionary(x => x.TSN);

                    knownTivosByTsn[connection.ConnectedTsn] = this.LanSettings;

                    ConnectionSettings.KnownTivos      = knownTivosByTsn.Values.ToArray();
                    ConnectionSettings.SelectedTivoTsn = connection.ConnectedTsn;

                    this.eventAggregator.Publish(new ConnectionSettingsChanged());
                }

                var toast = new ToastPrompt()
                {
                    Title           = "Connection succeeded",
                    Message         = "Home Mode",
                    TextOrientation = Orientation.Vertical,
                };

                toast.Show();
            }
            catch (ActionNotSupportedException)
            {
                var toast = new ToastPrompt()
                {
                    Title           = "Connection Failed",
                    Message         = "Network remote control not enabled on TiVo.",
                    TextOrientation = Orientation.Vertical,
                    TextWrapping    = TextWrapping.Wrap,
                    Background      = new SolidColorBrush(Colors.Red),
                };

                toast.Show();
            }
            catch (UnauthorizedAccessException)
            {
                var toast = new ToastPrompt()
                {
                    Title           = "Connection Failed",
                    Message         = "Incorrect Media Access Key",
                    TextOrientation = Orientation.Vertical,
                    TextWrapping    = TextWrapping.Wrap,
                    Background      = new SolidColorBrush(Colors.Red),
                };

                toast.Show();
            }
            catch (TivoException ex)
            {
                string message = ex.Message;

                if (ex.Code == "authenticationFailed")
                {
                    message = "Incorrect Media Access Key";
                }

                var toast = new ToastPrompt()
                {
                    Title           = "Connection Failed",
                    Message         = message,
                    TextOrientation = Orientation.Vertical,
                    TextWrapping    = TextWrapping.Wrap,
                    Background      = new SolidColorBrush(Colors.Red),
                };

                toast.Show();
            }
            catch (Exception)
            {
            }
            finally
            {
                connection.Dispose();
            }
        }