/// <summary>
        /// Adds or updates a private key.
        /// </summary>
        /// <param name="privateKeyData">The data of the private key to add/update.</param>
        /// <returns>No object or value is returned by this method when it completes.</returns>
        public async Task AddOrUpdate(PrivateKeyData privateKeyData)
        {
            var privateKeysFolder = await GetPrivateKeysFolder();
            var privateKeyFile = await privateKeysFolder.CreateFileAsync(privateKeyData.FileName, CreationCollisionOption.ReplaceExisting);
            await FileIO.WriteBytesAsync(privateKeyFile, privateKeyData.Data);

            this.privateKeys.Remove(GetPrivateKey(privateKeyData.FileName));
            this.privateKeys.Add(privateKeyData);
        }
        /// <summary>
        /// Adds or updates a private key.
        /// </summary>
        /// <param name="privateKeyData">The data of the private key to add/update.</param>
        /// <returns>No object or value is returned by this method when it completes.</returns>
        public async Task AddOrUpdate(PrivateKeyData privateKeyData)
        {
            var privateKeysFolder = await GetPrivateKeysFolder();

            var privateKeyFile = await privateKeysFolder.CreateFileAsync(privateKeyData.FileName, CreationCollisionOption.ReplaceExisting);

            await FileIO.WriteBytesAsync(privateKeyFile, privateKeyData.Data);

            this.privateKeys.Remove(GetPrivateKey(privateKeyData.FileName));
            this.privateKeys.Add(privateKeyData);
        }
        /// <summary>
        /// Reads all private keys from the local app data store.
        /// </summary>
        /// <returns>No object or value is returned by this method when it completes.</returns>
        public async Task GetPrivateKeys()
        {
            var privateKeysFolder = await GetPrivateKeysFolder();
            var privateKeyFiles = await privateKeysFolder.GetFilesAsync(CommonFileQuery.OrderByName);

            foreach (var privateKeyFile in privateKeyFiles)
            {
                PrivateKeyData privateKeyData = new PrivateKeyData();
                privateKeyData.FileName = privateKeyFile.Name;
                privateKeyData.Data = (await FileIO.ReadBufferAsync(privateKeyFile)).ToArray();

                this.privateKeys.Add(privateKeyData);
            }
        }
        /// <summary>
        /// Reads all private keys from the local app data store.
        /// </summary>
        /// <returns>No object or value is returned by this method when it completes.</returns>
        public async Task GetPrivateKeys()
        {
            var privateKeysFolder = await GetPrivateKeysFolder();

            var privateKeyFiles = await privateKeysFolder.GetFilesAsync(CommonFileQuery.OrderByName);

            foreach (var privateKeyFile in privateKeyFiles)
            {
                PrivateKeyData privateKeyData = new PrivateKeyData();
                privateKeyData.FileName = privateKeyFile.Name;
                privateKeyData.Data     = (await FileIO.ReadBufferAsync(privateKeyFile)).ToArray();

                this.privateKeys.Add(privateKeyData);
            }
        }
        /// <summary>
        /// Initializes the connection object with the specified connection data.
        /// </summary>
        /// <param name="connectionData">The connection data for the connection.</param>
        /// <exception cref="ObjectDisposedException">The connection object is already disposed.</exception>
        /// <exception cref="InvalidOperationException">The connection object is currently connected.</exception>
        /// <exception cref="ArgumentException">The <paramref name="connectionData"/> object contains a connection type that is not supported by the connection object.</exception>
        /// <exception cref="Exception">Some other error occured (here: the private key for the SSH authentication could not be found).</exception>
        public void Initialize(ConnectionData connectionData)
        {
            this.CheckDisposed();
            this.MustBeConnected(false);

            if (connectionData.Type != ConnectionType.Ssh)
            {
                throw new ArgumentException("ConnectionData does not use Ssh connection.", "connectionData");
            }

            this.connectionData = connectionData;

            // This is already done here instead of in the ConnectAsync method because here the PrivateKeysDataSource.GetPrivateKey method is able to access the Resources.
            if (connectionData.Authentication == AuthenticationType.PrivateKey)
            {
                this.privateKeyData = PrivateKeysDataSource.GetPrivateKey(connectionData.PrivateKeyName);
                if (this.privateKeyData == null)
                {
                    throw new Exception("Private Key '" + connectionData.PrivateKeyName + "' not found. Please correct the authentication details of the connection.");
                }
            }
        }
        /// <summary>
        /// Occurs when the import button is clicked.
        /// </summary>
        /// <param name="sender">The object where the event handler is attached.</param>
        /// <param name="e">The event data.</param>
        private async void importButton_Click(object sender, RoutedEventArgs e)
        {
            FileOpenPicker openPicker = new FileOpenPicker();
            openPicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
            openPicker.ViewMode = PickerViewMode.List;
            openPicker.CommitButtonText = "Import";

            // Filter to include a sample subset of file types.
            openPicker.FileTypeFilter.Clear();
            //openPicker.FileTypeFilter.Add(".pfx");
            openPicker.FileTypeFilter.Add(".pem");
            openPicker.FileTypeFilter.Add(".key");
            openPicker.FileTypeFilter.Add(".ssh");

            // Open the file picker.
            var files = await openPicker.PickMultipleFilesAsync();

            // files is null if user cancels the file picker.
            if (files == null || files.Count == 0)
            {
                return;
            }

            var privateKeysDataSource = App.Current.Resources["privateKeysDataSource"] as PrivateKeysDataSource;
            if (privateKeysDataSource == null)
            {
                return;
            }

            foreach (var file in files)
            {
                var buffer = await FileIO.ReadBufferAsync(file);
                using (var stream = new MemoryStream(buffer.ToArray()))
                {
                    PrivateKeyFile.Validate(stream);
                }

                var privateKeysFolder = await PrivateKeysDataSource.GetPrivateKeysFolder();
                var privateKeyFile = await file.CopyAsync(privateKeysFolder, file.Name, NameCollisionOption.GenerateUniqueName);

                var privateKeyData = new PrivateKeyData()
                {
                    FileName = privateKeyFile.Name,
                    Data = (await FileIO.ReadBufferAsync(privateKeyFile)).ToArray(),
                };

                privateKeysDataSource.PrivateKeys.Remove(PrivateKeysDataSource.GetPrivateKey(privateKeyData.FileName));
                privateKeysDataSource.PrivateKeys.Add(privateKeyData);
            }

            var items = new ObservableCollection<PrivateKeyData>(privateKeysDataSource.PrivateKeys.OrderBy(f => f.FileName));
            this.DefaultViewModel["Items"] = items;
            this.emptyHint.Visibility = this.itemGridView.Items.Count == 0 ? Visibility.Visible : Visibility.Collapsed;
        }
        /// <summary>
        /// Removes a private key.
        /// </summary>
        /// <param name="privateKeyData">The data of the private key to remove.</param>
        /// <returns>No object or value is returned by this method when it completes.</returns>
        internal async Task Remove(PrivateKeyData privateKeyData)
        {
            var privateKeysFolder = await GetPrivateKeysFolder();
            var privateKeyFile = await privateKeysFolder.GetFileAsync(privateKeyData.FileName);
            await privateKeyFile.DeleteAsync();

            this.privateKeys.Remove(GetPrivateKey(privateKeyData.FileName));
        }